2 điểm bởi GN⁺ 2025-04-30 | 1 bình luận | Chia sẻ qua WhatsApp
  • Cụm multi-AZ của Amazon RDS for PostgreSQL chính thức hỗ trợ Snapshot Isolation, nhưng trên thực tế thường xuyên xảy ra chu trình G-nonadjacent và hiện tượng Long Fork vi phạm điều này
  • Bài kiểm thử được thực hiện dựa trên tải công việc giao dịch PostgreSQL do tác giả tự xây dựng, và mọi phiên bản từ PostgreSQL 13.15 đến 17.4 đều phát sinh lỗi nhất quán
  • Các lỗi này chủ yếu xảy ra trên node secondary chỉ đọc, và Snapshot Isolation bị phá vỡ ngay cả ở mức "Repeatable Read"
  • Cụm RDS có thể đang cung cấp mức nhất quán Parallel Snapshot Isolation, đây là mô hình yếu hơn PostgreSQL node đơn mặc định
  • Các giao dịch chỉ đọc có thể quan sát các thứ tự giao dịch khác nhau, và những bất nhất này có thể dẫn tới lỗi toàn vẹn dữ liệu

Background

  • PostgreSQL là DB SQL mã nguồn mở dựa trên MVCC, cung cấp nhiều mức cô lập giao dịch khác nhau. Repeatable Read trên thực tế có nghĩa là Snapshot Isolation
  • Amazon RDS cung cấp PostgreSQL dưới dạng cụm được quản lý, và cấu hình Multi-AZ là kiến trúc dành cho sao chép và khả năng chịu lỗi
  • Endpoint mặc định có thể đọc/ghi, còn secondary là chỉ đọc và không hỗ trợ mức Serializable

Test Design

  • Bọc công cụ kiểm thử Jepsen PostgreSQL để phù hợp với RDS và thực hiện kiểm thử giao dịch tự động
  • Các giao dịch được thiết kế theo cấu trúc đọc danh sách trên các khóa cụ thể hoặc append số nguyên duy nhất, dùng Elle checker để phát hiện chu trình
  • Xác nhận Long Fork và G-nonadjacent xuất hiện trong vòng 2 phút dưới tải 150 TPS ghi và 1600 TPS đọc

Results

  • Chứng minh vi phạm Snapshot Isolation thông qua một chu trình G-nonadjacent gồm 4 giao dịch
    • T₂ quan sát thay đổi của T₁ nhưng không thấy T₃, còn T₄ thấy T₃ nhưng không thấy T₁ → phát sinh mâu thuẫn lẫn nhau về thứ tự thời gian
  • Đây vừa là hiện tượng Long Fork vừa là một trường hợp mạnh chứng minh vi phạm Snapshot Isolation, và
  • Không phát hiện Write Skew, qua đó củng cố khả năng đây là Parallel Snapshot Isolation

Discussion

  • RDS Multi-AZ có mức nhất quán thấp hơn PostgreSQL node đơn
  • có khả năng phát sinh lỗi nhất quán khi dùng node chỉ đọc, nên cần cân nhắc chỉ sử dụng node ghi hoặc bảo đảm mọi giao dịch đều chứa ít nhất một thao tác ghi
  • Phân tích lần này mới ở mức kiểm thử ban đầu và chỉ chứng minh sự tồn tại của vấn đề, không thể bảo đảm sự vắng mặt của nó

1 bình luận

 
GN⁺ 2025-04-30
Ý kiến trên Hacker News
  • Dù không được nêu rõ trong tiêu đề bài viết, đây là về tính năng mới của RDS là cụm multi-AZ

    • Multi-AZ instance là tính năng cũ, trong đó DB chính được sao chép đồng bộ sang DB phụ ở AZ khác
    • Multi-AZ cluster có hai DB phụ, và giao dịch được sao chép đồng bộ tới ít nhất một DB phụ
    • Cách này vững chắc hơn khi DB phụ gặp sự cố hoặc suy giảm hiệu năng, đồng thời cho phép truy cập chỉ đọc vào DB phụ
    • Multi-AZ cluster không phải là tính năng Postgres thông thường, và đó có thể là lý do nó thất bại trong bài kiểm tra Jepsen
  • Ở công ty cũ, khi thay đổi lệnh pg_dump trong script sao lưu để dùng worker song song (cờ -j), đã phát sinh vấn đề nhất quán khi khôi phục bản sao lưu (lỗi khóa trùng lặp và lỗi ràng buộc fk)

    • Đã báo cáo vấn đề cho AWS và mailing list của Postgres, nhưng không thể tái hiện dễ dàng nên không được giải quyết
    • Cuối cùng đã quay lại dump đơn luồng, và không rõ liệu vấn đề này có liên quan đến hiện tượng mà chúng tôi từng gặp hay không
  • Đây là công việc do Jepsen thực hiện độc lập và không được trả tiền

    • Đây là loại tin mà các bên có lợi ích liên quan đến RDBMS sẽ không muốn nghe vào một ngày đẹp trời
    • Xin dành sự kính trọng cho aphyr
  • Ý nghĩa thực tế của vấn đề này là các lần đọc diễn ra rất nhanh sau khi ghi vào cùng một hàng có thể trả về dữ liệu cũ

    • Trước khi giao dịch ghi được đánh dấu là hoàn tất, không phải mọi lớp phân tán của instance RDS multi-AZ đều đã được cập nhật đầy đủ, nên các lần đọc ngay sau đó có thể trả về hàng chưa tồn tại hoặc giá trị cũ
    • Do cơ chế snapshot của PostgreSQL, đây không phải là việc chỉ một phần byte của kiểu cột nhiều byte bị cập nhật khiến lần đọc nhận giá trị vô nghĩa
    • Điều này giống như một race condition mà cuối cùng sẽ đạt được tính nhất quán
  • Chưa rõ liệu cụm Postgres upstream nhiều instance có gặp vấn đề này hay không

    • Không rõ AWS đã thêm thứ gì vào cấu hình cụm, hay đã thêm bản vá nào gây ra hành vi này
  • Tiêu đề được gửi lên đang che mờ điểm cốt lõi: RDS cho PostgreSQL 17.4 không triển khai snapshot isolation đúng cách

  • Nếu lập trình viên giả định có snapshot isolation nhưng Amazon RDS for PostgreSQL thực tế chỉ cung cấp parallel snapshot isolation, thì không rõ có thể phát sinh những lỗi an toàn hoặc lỗi ở mức ứng dụng nào, đặc biệt trong cấu hình multi-AZ dùng endpoint read replica

  • Hiện tượng này xuất hiện ở mọi phiên bản được kiểm tra, từ 13.15 đến 17.4

    • Từng lo rằng nâng cấp major version là một quyết định sai lầm, nhưng có vẻ đây không phải là hồi quy mà là một yêu cầu tính năng hoặc lỗi đã tồn tại lâu năm
  • Sẽ rất tốt nếu Jepsen kiểm tra mọi phiên bản của Amazon RDS

  • AWS nên cập nhật tài liệu để truyền đạt điều này

    • Không rõ việc sửa snapshot isolation có gây hồi quy hiệu năng về độ trễ hoặc thông lượng hay không, hay họ sẽ cho rằng trạng thái hiện tại đã đủ mạnh
    • Dù thế nào thì AWS cũng nên đề cập đến việc này