# Cutover ngày go-live: chuyển dữ liệu, chạy song song và đường lui khi hỏng

> Một đêm go-live tại khách hàng có thể đổ vỡ dù code không sai, chỉ vì không ai biết ai được quyền nói câu "quay lại", và quay lại bằng dữ liệu nào.

Bản gốc: https://fdetimes.net/vi/bach-khoa/cutover-go-live-ke-hoach-rollback-du-lieu-khach/

Thử hình dung: 22 giờ tối thứ Sáu, hệ thống nhận đơn cũ của khách vẫn chạy, còn pipeline bạn xây suốt ba tháng đã sẵn sàng. Bạn có bốn tiếng để chuyển. Câu hỏi quan trọng nhất đêm đó không nằm ở code. Nếu 1 giờ sáng có gì sai, ai quyết định quay lại, và quay lại bằng dữ liệu nào?

Với một FDE, đêm go-live là lúc khách hàng thực sự đánh giá bạn. Demo cho họ thấy hệ thống làm được gì, còn cutover cho họ biết có nên giao hệ thống vận hành của mình vào tay bạn hay không. Vì thế đây là kỹ năng đáng tập từ trước, khi chưa phải tự mình cầm runbook trong một đêm thật.

## Cutover là một trình tự, không phải một nút bấm

AWS Prescriptive Guidance mô tả cutover thành một chuỗi cố định: đóng băng việc ghi dữ liệu vào hệ cũ, lấy bản backup cuối, đồng bộ dữ liệu lần cuối, đổi routing, rồi kiểm thử.

Thứ tự này có lý do. Đóng băng trước để hệ cũ không nhận thêm giao dịch nào trong lúc bạn đang chép, nếu không bản đồng bộ cuối sẽ thiếu một số đơn mà không ai hay.

Bản backup cuối không chỉ để lưu trữ. AWS nói rõ có thể dùng chính bản này để rollback khi khẩn cấp. Vì vậy hãy ghi lại chính xác thời điểm lấy backup và restore thử nó trước đêm cutover, để chắc rằng bản này thật sự dùng được khi cần.

Sau đó bạn chọn giữa chuyển một lần (big bang) và chuyển theo từng phần. Theo AWS, cách chuyển theo phần phức tạp và tốn thời gian hơn, nhưng thường ít downtime hơn và rollback nhanh hơn.

Vì thế, với những hệ thống production sống còn với việc kinh doanh, người ta thường chọn cách này. Khi khách có hàng nghìn người dùng, bạn có thể chuyển một chi nhánh hoặc 5% traffic trước, sau đó mới mở rộng.

## Chạy song song: để máy so sánh trước khi tin

Một cách để kiểm tra hệ mới trước khi tin nó là cho nó chạy cạnh hệ cũ trên traffic thật. Thư viện Scientist của GitHub làm việc này ở mức code: mỗi lần được gọi, cả hai nhánh đều chạy theo thứ tự xáo ngẫu nhiên, kết quả được so sánh, chỗ lệch được ghi lại, còn người dùng vẫn nhận kết quả của nhánh cũ.

Với dữ liệu, Stripe mô tả bốn bước: ghi song song vào bảng cũ và bảng mới, chuyển phần đọc sang bảng mới, chuyển phần ghi, rồi mới xoá dữ liệu cũ. Dữ liệu đã có từ trước được backfill sang bảng mới.

Nếu bạn đang thay một bộ quy tắc phân loại đơn bằng model mới, mẫu này áp dụng được ngay: model chạy ở chế độ shadow, mọi kết quả lệch với quy tắc cũ được log lại để xem trước ngày chuyển.

Nhưng chạy song song cũng có giới hạn. Tài liệu runbook của DualEntry, viết cho hệ thống kế toán, cảnh báo rằng nhập liệu hai lần làm khối lượng việc tăng gấp đôi, và chính bản thứ hai là bản dễ bị lệch.

Họ khuyên chuyển dứt khoát tại một mốc kỳ kế toán và để hệ cũ ở chế độ chỉ đọc. Từ hai cách nhìn này có thể rút ra một nguyên tắc: để máy chạy song song và so sánh thì được, còn bắt nhân viên của khách nhập liệu hai lần thì nên tránh.

## Rollback chỉ dễ khi chưa có dữ liệu mới

Đây là chỗ nhiều kế hoạch bỏ sót. AWS lưu ý rằng nếu rollback sau khi hệ mới đã nhận giao dịch thật, bạn có thể phải khôi phục cả dữ liệu đó về hệ cũ.

Có ba cách: dùng một database fail-forward, ghi song song (dual write), hoặc backup rồi restore. Hệ mới chạy trên dữ liệu thật càng lâu thì đường quay lại càng khó.

Theo AWS, một kế hoạch rollback cần ba thứ: các checkpoint kích hoạt, chiến lược xử lý dữ liệu, và một người được chỉ định đích danh để quyết định sửa tiếp (fix forward) hay quay lại.

Một bài viết trên blog AWS bổ sung quy tắc giới hạn thời gian. Nếu trong khung thời gian đã định, đội không nói rõ được vấn đề là gì và cách giải quyết ra sao, hãy rollback.

**Điểm mấu chốt:** Kế hoạch rollback chưa từng diễn tập chỉ là một lời hứa trên giấy.

AWS yêu cầu ghi quy trình rollback ngay trong kế hoạch cutover và diễn tập nó. Bài viết trên blog AWS còn so sánh việc này với diễn tập phòng cháy: phải làm đều đặn để quy trình không bị quên.

## Một runbook mẫu cho đêm go-live

AWS khuyên lập runbook ghi rõ giờ bắt đầu, giờ kết thúc, thứ tự và người phụ trách từng việc, kèm ma trận RACI. Thử hình dung một nhà phân phối chuyển việc nhận đơn sang hệ thống mới do bạn triển khai. Runbook rút gọn có thể trông như sau:

| Giờ | Việc | Người làm | Điểm quyết định |
|---|---|---|---|
| 22:00 | Đóng băng ghi dữ liệu vào hệ cũ | DBA của khách | Xác nhận không còn đơn mới vào |
| 22:15 | Backup cuối, ghi lại mốc | DBA của khách | Backup restore thử được |
| 22:45 | Đồng bộ dữ liệu cuối | FDE | Số bản ghi hai bên khớp |
| 23:30 | Đổi routing sang hệ mới | DevOps | Từ đây hệ mới nhận đơn thật |
| 23:45 | Kiểm thử và đối soát | FDE + nghiệp vụ | Giới hạn 60 phút, hết giờ thì rollback |
| 00:45 | Quyết định go-live | Trưởng dự án phía khách | Fix forward hay rollback |

Cột cuối là phần quan trọng nhất. Giả sử hệ cũ có 12.480 đơn trong ngày còn hệ mới đếm được 12.477. Ba đơn lệch này là một checkpoint kích hoạt: hoặc bạn tìm ra nguyên nhân trong khung thời gian đã định, hoặc bạn quay lại.

Nhưng quay lại bằng gì? Từ 23:30, khi routing đã đổi, hệ mới có thể đã nhận đơn thật, và bản backup lúc 22:15 không chứa các giao dịch đó.

Restore riêng bản backup sẽ làm mất mọi đơn vào sau 23:30, nên kế hoạch phải chọn trước một trong ba cách xử lý dữ liệu ở trên, chẳng hạn ghi song song về hệ cũ trong suốt khung kiểm thử.

DualEntry đưa ra một quy tắc nên chép vào mọi runbook: chưa được tuyên bố go-live khi chưa phải mọi dòng trong danh sách đối soát đều đúng. Với ví dụ trên, danh sách có thể gồm: số đơn khớp, tổng giá trị đơn khớp, và 50 bản ghi chọn ngẫu nhiên giống nhau ở cả hai hệ.

## Năm lỗi khiến đêm go-live kéo đến sáng

Lỗi thứ nhất là không có ai được chỉ định đích danh để quyết định rollback. Năm kỹ sư cùng nhìn một con số lệch, ai cũng muốn thử sửa thêm mười phút, và giới hạn thời gian không còn tác dụng.

Lỗi thứ hai là có văn bản rollback nhưng chưa ai chạy thử, nên đến lúc cần mới phát hiện restore mất ba tiếng chứ không phải ba mươi phút. Lỗi thứ ba là quên rằng sau khi đổi routing, hệ mới đã bắt đầu nhận dữ liệu thật, trong khi kế hoạch rollback vẫn coi như chưa có gì xảy ra.

Lỗi thứ tư là bắt nhân viên khách nhập liệu song song "cho chắc". Lỗi thứ năm là tuyên bố go-live trước khi đối soát xong, chỉ vì ai cũng đã mệt.

Nếu bạn đang chuẩn bị sang vai trò FDE, hãy tìm trong JD những cụm như "migration", "go-live support" hay "deployment ownership". Trong CV, một dòng như "viết và điều phối runbook cutover, diễn tập rollback trên staging, go-live mà không mất dữ liệu" cho nhà tuyển dụng biết nhiều hơn mọi danh sách framework.

Khách hàng có thể quên model bạn dùng. Nhưng họ sẽ nhớ đêm go-live đó có ai đứng ra trả lời được câu "nếu hỏng thì sao" hay không.

**Thử ngay tuần này:**

- Lấy một hệ thống bạn sắp deploy, viết runbook cutover dạng bảng gồm giờ bắt đầu, giờ kết thúc, thứ tự và người phụ trách từng việc
- Viết ba dòng điều kiện đối soát phải đúng hết thì mới được tuyên bố go-live
- Tổ chức 30 phút diễn tập rollback trên môi trường staging và ghi lại thời gian thực tế để khôi phục

## Nguồn

- [Cutover stage - AWS Prescriptive Guidance](https://docs.aws.amazon.com/prescriptive-guidance/latest/best-practices-migration-cutover/cutover-stage.html)

- [Pre-cutover stage - AWS Prescriptive Guidance](https://docs.aws.amazon.com/prescriptive-guidance/latest/best-practices-migration-cutover/pre-cutover-stage.html)

- [Migration Rollback Strategies: When Your Migration Doesn't Go as Planned](https://aws.amazon.com/blogs/migration-and-modernization/migration-rollback-strategies-when-your-migration-doesnt-go-as-planned)

- [Online migrations at scale](https://stripe.com/blog/online-migrations)

- [Scientist: Measure Twice, Cut Once](https://github.blog/engineering/infrastructure/scientist/)

- [migration cutover runbook (DualEntry docs)](https://docs.dualentry.com/accountants/get-started/migration-cutover-runbook)
