Trường hợp phát hiện race condition trong Aurora RDS
(hightouch.com)- Một trường hợp đã xác minh bằng thực nghiệm lỗi race condition xảy ra trong AWS Aurora RDS và nhận được xác nhận nguyên nhân từ AWS
- Trong quá trình mở rộng hệ thống xử lý sự kiện, Hightouch phát hiện hiện tượng chuyển đổi write instance thất bại trong quá trình failover của Aurora
- Kết quả phân tích log cho thấy hai instance đồng thời thực hiện tác vụ ghi, gây xung đột ở tầng lưu trữ và làm tiến trình bị kết thúc
- AWS chính thức xác nhận nguyên nhân là do vấn đề xử lý tín hiệu nội bộ, khiến writer cũ chưa bị hạ cấp xong thì writer mới đã được nâng cấp
- Trường hợp này nhấn mạnh tầm quan trọng của kiểm soát đồng thời trong các hệ thống phân tán quy mô lớn và sự cần thiết của quy trình dừng ghi khi failover
Bối cảnh
- Ngày 20 tháng 10 năm 2025, tại region AWS
us-east-1đã xảy ra sự cố do lỗi race condition trong hệ thống quản lý DNS - Vì điều này, backlog xử lý sự kiện của Hightouch tăng vọt và hệ thống chạm đến giới hạn
- Để đảm bảo thông lượng, vào ngày 23 tháng 10 công ty đã tiến hành nâng cấp instance Aurora RDS, và trong quá trình đó phát hiện thêm một lỗi race condition mới
Kiến trúc hệ thống sự kiện của Hightouch
- Hệ thống phụ trách thu thập và truyền sự kiện được cấu thành từ Kubernetes, Kafka, Postgres(Aurora)
- Postgres được dùng như hàng đợi metadata theo lô, xử lý 500.000 sự kiện mỗi giây trong vòng 1 giây
- Aurora PostgreSQL gồm instance chỉ ghi (primary), instance chỉ đọc (replica) và tầng lưu trữ dùng chung
Kế hoạch nâng cấp
- Thêm instance đọc → nâng cấp reader hiện có và gán mức ưu tiên failover → thực hiện failover → nâng cấp writer hiện có → gỡ reader tạm thời
- Đây là quy trình được nêu trong tài liệu AWS và đã được kiểm chứng bằng kiểm thử tải trong môi trường staging
Thử nâng cấp và phát sinh vấn đề
- Lúc 16:39 EDT ngày 23 tháng 10, sau khi chạy failover đã xuất hiện hiện tượng writer cũ quay trở lại làm primary
- Cả hai lần thử đều cho cùng kết quả, và một số dịch vụ gặp lỗi không thể ghi (DatabaseError: cannot execute UPDATE in a read-only transaction)
- Kết quả phân tích log xác nhận có log cho thấy hai instance đồng thời thực hiện tác vụ ghi rồi bị dừng do xung đột lưu trữ
Nguyên nhân của race condition
- Trong quá trình failover của Aurora, race condition xảy ra giữa bước 3 (hạ cấp writer cũ) và bước 4 (nâng cấp writer mới)
- Vì vậy, hai instance đồng thời có quyền ghi và xảy ra xung đột
- Khi thử lại trong trạng thái đã loại bỏ write traffic, failover hoàn tất bình thường, qua đó giả thuyết race condition được chứng minh
Xác nhận và ứng phó từ AWS
- Sau khi rà soát nội bộ, AWS xác nhận nguyên nhân là lỗi xử lý tín hiệu hạ cấp writer, không liên quan đến cấu hình hay mẫu traffic của Hightouch
- Bản sửa lỗi đã nằm trong roadmap, và biện pháp tạm thời được khuyến nghị là dừng ghi trong lúc failover
Biện pháp cuối cùng
- Hightouch đã hoàn tất nâng cấp cluster, đồng thời
- bổ sung quy trình dừng ghi trước khi failover có chủ đích
- tăng cường giám sát theo dõi thay đổi vai trò writer
- cập nhật sổ tay vận hành (playbook)
Bài học chính
- Cần chuẩn bị phương án khôi phục cho các chuyển đổi trạng thái ngoài dự kiến trong quá trình migration
- Đảm bảo observability là chìa khóa để phát hiện vấn đề
- Tầm quan trọng của thiết kế giảm thiểu ảnh hưởng giữa các thành phần trong hệ thống phân tán
- Cần nhận thức được sự khác biệt giữa môi trường kiểm thử và môi trường production thực tế
Không có thêm thông tin trong bài gốc
1 bình luận
Ý kiến trên Hacker News
Đọc bài này thì có vẻ như trong lúc failover thủ công nếu ứng dụng vẫn cố duy trì lưu lượng ghi như bình thường thì sẽ luôn thất bại
Nhưng điều đó lại làm nảy sinh vài câu hỏi. Tại sao những người dùng Aurora khác không phải lúc nào cũng gặp vấn đề này, liệu AWS có thể không biết hay không, và nếu biết thì tại sao lại không xử lý như một sự cố khẩn cấp cấp P0
Có lẽ có những điều kiện tinh vi như trạng thái giao dịch đang chạy hoặc timeout đang tác động vào đây
SELECT ... FOR UPDATEâm thầm thất bại và transaction chuyển sang chế độ autocommit trong tổ hợp Python + MySQL. Không ai quan tâm nên tôi cứ nói một mình, rồi vài tháng sau có người khác liên hệ bảo họ cũng gặp đúng vấn đề đó. Cuối cùng nó cũng được sửa, nhưng lúc ấy tôi đã thôi theo dõi rồiLiên kết liên quan: câu hỏi trên Stack Overflow
Tôi đã nhiều lần thấy hành vi ngoài dự kiến trên Aurora PostgreSQL
Đặc biệt là trong lúc Zero Downtime Patching (ZDP), trạng thái session bị giữ sai nên ngay cả truy vấn đơn giản cũng bị hủy nhanh hơn rất nhiều so với
statement_timeoutTôi đoán là khi client reconnect, Aurora đã kế thừa nguyên trạng thái timer cũ của session trước đó nên query bị hủy ngay lập tức
Bên tôi cũng thực hiện failover định kỳ trong môi trường có lưu lượng ghi rất cao, nhưng đang vận hành ổn định bằng quy trình tự động với AWS JDBC wrapper
Người ta trả tiền là để tin rằng Aurora sẽ giữ được những bất biến cơ bản như thế này, nên việc xảy ra vấn đề như vậy khá bất ngờ
Nhìn vào log và phần giải thích từ AWS thì có vẻ giả thuyết của tác giả bài gốc là không đúng
Có vẻ sau khi promotion thất bại, một tiến trình giám sát bên ngoài đã phát hiện trạng thái cluster không nhất quán và buộc dừng bằng kill -9. Các thông báo liên quan đến subsystem storage xuất hiện sau đó
Tôi muốn hỏi về so sánh hiệu năng giữa Aurora và RDS Postgres.
Nếu không cần multi-AZ hay failover nhanh, liệu cấu hình gp3 64k IOPS trên RDS có cho hiệu năng tốt hơn không? Aurora có vẻ đặc biệt chậm ở insert và chi phí cao. Các benchmark cũng không nêu rõ cấu hình RDS nên khó tin tưởng
Ngoài ra cũng không cần tự provision IOPS và có khoảng 80k IOPS.
Cách tính phí IO cũng có hai kiểu: pay-per-IO phù hợp với môi trường tải thấp, còn chế độ phí cố định phù hợp hơn với workload nhiều IO.
Nhân tiện, Serverless gần như lúc nào cũng không kinh tế. Nó chỉ hữu ích khi có các đợt tăng tải ngắn
Điều này thể hiện rất rõ “mô hình khối Lego” mà các kỹ sư AWS hay nói đến
Họ thiết kế lớp storage hoàn toàn độc lập, nên ngay cả khi dịch vụ ở tầng trên lỗi thì tính nhất quán dữ liệu vẫn được đảm bảo. Tôi nghĩ đây là một ví dụ hay về kỹ thuật của AWS
Tôi nghe nói AWS đã khuyến nghị rằng hãy dừng ghi trong lúc failover, nên muốn hỏi liệu có thể chia sẻ mã case liên quan hay không
Thật mừng khi biết không chỉ mình tôi gặp vấn đề này
Kiến trúc tách rời compute-storage của Aurora khá thú vị
Hyperscale của MSSQL cũng có cấu trúc tương tự, và đó gần như là sản phẩm duy nhất trong các dịch vụ Azure mà tôi cảm thấy thực sự đáng để dùng thử