2 điểm bởi GN⁺ 2025-04-30 | 1 bình luận | Chia sẻ qua WhatsApp
  • Trong thử nghiệm Jepsen, đã xác nhận trường hợp cụm Amazon RDS for PostgreSQL Multi-AZ không tuân thủ Snapshot Isolation, mức cô lập mạnh nhất xét trên toàn bộ các node
  • Nguyên nhân cốt lõi là thứ tự hiển thị giao dịch trên primary được quyết định bằng khóa trong bộ nhớ, trong khi secondary tuân theo thứ tự WAL, khiến hai thứ tự này có thể lệch nhau
  • Ngay cả trong điều kiện dùng storage gp3 và instance db.m6id.large mà không tiêm lỗi hay failover, G-nonadjacent cycle vẫn xuất hiện vài phút một lần ở mức khoảng 150 write TPS / 1600 read-only TPS
  • Hiện tượng bất thường này thuộc loại Long Fork, xuất hiện trong mọi phiên bản được thử nghiệm từ PostgreSQL 13.15 đến 17.4 do AWS hỗ trợ; không quan sát thấy Short Fork/Write Skew
  • Với các giao dịch quan trọng về an toàn, khi dùng read-only secondary có thể nhìn thấy thứ tự thực thi khác nhau, nên cần cân nhắc chỉ dùng writer endpoint hoặc đưa vào ít nhất 1 thao tác write

Cập nhật nguyên nhân Long Fork

  • Sergey Melnik của AWS cùng các thành viên bình luận trên HN là matashii và Ants Aasma đã xác định nguyên nhân Long Fork trong cụm PostgreSQL
  • PostgreSQL primary quyết định thứ tự làm cho giao dịch trở nên nhìn thấy được bằng khóa trong bộ nhớ
  • Secondary làm cho giao dịch trở nên nhìn thấy được theo thứ tự trong Write-Ahead Log (WAL)
  • Nếu thứ tự khóa và thứ tự WAL khác nhau, primary và secondary có thể nhìn thấy thứ tự biểu kiến của giao dịch khác nhau
  • Hành vi này từng được đề cập trong một bài trên mailing list PostgreSQL năm 2013, và Melnik đã viết bài trên blog AWS giải thích về transaction visibility trong cụm PostgreSQL và read replica
  • Jepsen khuyến nghị AWS và PostgreSQL ghi tài liệu về vấn đề này cùng với công việc sửa lỗi

Mức cô lập và kiến trúc của RDS for PostgreSQL

  • PostgreSQL là cơ sở dữ liệu SQL mã nguồn mở đa dụng, cung cấp ba mức cô lập giao dịch bằng MVCC
    • Read UncommittedRead Committed đều hoạt động như Read Committed
    • Repeatable Read thực tế không phải Repeatable Read mà cung cấp Snapshot Isolation
    • Serializable cung cấp Serializability
  • Amazon RDS for PostgreSQL là dịch vụ AWS cung cấp cụm PostgreSQL được quản lý
    • Tự động hóa provisioning, quản lý storage, replication, backup, upgrade, v.v.
    • Multi-AZ deployments phân tán các node cơ sở dữ liệu trên nhiều Availability Zone để giảm khả năng xảy ra lỗi tương quan
    • RDS dùng synchronous replication để chỉ phản hồi sau khi độ bền giao dịch đã được bảo đảm trên cả primary và ít nhất 1 instance secondary
  • Người dùng được cung cấp hai URL nói PostgreSQL wire protocol
    • primary endpoint: dành cho giao dịch read-write
    • reader endpoint: dành cho giao dịch read-only
  • Primary endpoint hỗ trợ mọi mức cô lập của PostgreSQL, nhưng secondary không hỗ trợ Serializable
  • Mức cô lập mạnh nhất có thể dùng trên toàn bộ node là Snapshot Isolation, thứ PostgreSQL gọi là Repeatable Read

Thiết kế thử nghiệm

  • Jepsen đã điều chỉnh thư viện thử nghiệm cho PostgreSQL để phù hợp với Amazon RDS for PostgreSQL, và dùng một wrapper program nhỏ
  • Mỗi vòng thử nghiệm provision một cụm RDS bằng API CreateDBCluster của AWS
    • Storage là gp3
    • Instance là db.m6id.large
  • Khởi chạy 1 node EC2 để chạy thử nghiệm và cung cấp main endpoint cùng read-only endpoint của cụm RDS
  • Không tiêm lỗi và cũng không kích hoạt failover
  • Workload chính gồm các giao dịch xử lý danh sách số nguyên duy nhất
    • Mỗi danh sách được lưu trong một row duy nhất và được mã hóa dưới dạng trường TEXT chứa các giá trị phân tách bằng dấu phẩy
    • Giao dịch đọc danh sách bằng primary key hoặc append số nguyên duy nhất vào danh sách bằng CONCAT
  • Với workload này, Elle checker có thể suy luận phụ thuộc luồng dữ liệu giữa các giao dịch và tìm cycle trong đồ thị để kiểm chứng nhiều mức cô lập

Quan sát G-nonadjacent cycle

  • Ngay cả trong điều kiện bình thường và mức concurrency trung bình, Amazon RDS for PostgreSQL 17.4 vẫn cho thấy G-nonadjacent cycle vài phút một lần
  • Một lần chạy thử nghiệm 2 phút thực hiện khoảng 150 write TPS và 1600 read-only TPS, bao gồm một cycle 4 giao dịch
  • Cycle ví dụ gồm bốn giao dịch T1, T2, T3, T4
    • T1 append 9 vào row 89 để tạo danh sách [4 9], và T2 quan sát thấy điều này
    • T3 append 11 vào row 90 để tạo danh sách [11]
    • T4 append 3 vào row 90 và đọc danh sách kết quả [11, 3], ghi đè version của T3
    • T2 quan sát thấy append của T1 ở row 89 nhưng không thấy append của T3 ở row 90
    • Ngược lại, T4 quan sát thấy append của T3 ở row 90 nhưng bỏ lỡ append của T1 ở row 89
  • Cycle này bao gồm read-write dependency không liền kề với nhau, nên là G-nonadjacent cycle vi phạm Snapshot Isolation
  • Trong Repeatable Read của PostgreSQL chuẩn, hành vi như vậy không được xảy ra, và Jepsen không quan sát thấy nó trong PostgreSQL chuẩn

Vì sao xung đột với Snapshot Isolation

  • Trong Snapshot Isolation, mọi giao dịch phải trông như hoạt động trên snapshot của cơ sở dữ liệu tại timestamp bắt đầu s
  • Hiệu ứng của giao dịch sẽ trở nên nhìn thấy được với các giao dịch khác ở timestamp commit c sau đó
  • Nếu viết các quan sát trong cycle ví dụ thành quan hệ timestamp, chúng mâu thuẫn với nhau
    • T2 đọc append của T1, thời điểm bắt đầu của T2 phải sau commit của T1: c1 < s2
    • T2 không quan sát thấy append của T3, nên s2 < c3
    • T4 ghi đè và quan sát thấy T3, nên c3 < s4
    • T4 không quan sát thấy append của T1, nên s4 < c1
  • Các quan hệ này không thể đồng thời đúng, nên xung đột với mô hình timestamp của Snapshot Isolation

Long Fork và kết quả theo phiên bản

  • Cycle này cũng là một ví dụ về Long Fork
    • Giao dịch thứ nhất và thứ hai tạo thành một fork trạng thái logic
    • Giao dịch thứ ba và thứ tư tạo thành fork thứ hai
    • Hai fork cập nhật các row khác nhau nhưng không quan sát thấy hiệu ứng của nhau
  • Không quan sát thấy Short Fork, tức Write Skew
  • Kết quả này gợi ý rằng Amazon RDS for PostgreSQL có thể cung cấp Parallel Snapshot Isolation, yếu hơn Snapshot Isolation một chút
  • Các bất thường G-nonadjacent xuất hiện đa dạng, từ trường hợp chỉ được nối bằng write-read edge đến trường hợp bao gồm hơn 4 giao dịch
  • Cùng một loại bất thường xảy ra trong mọi phiên bản được thử nghiệm, từ PostgreSQL 13.15, phiên bản cũ nhất AWS hỗ trợ, đến phiên bản mới nhất 17.4

Những điểm người dùng cần kiểm tra

  • Vì tồn tại Long Fork và các G-nonadjacent cycle khác, cụm Amazon RDS for PostgreSQL Multi-AZ không bảo đảm Snapshot Isolation
  • Về điểm này, cụm RDS for PostgreSQL Multi-AZ cung cấp ngữ nghĩa an toàn yếu hơn PostgreSQL một node, vốn trong thử nghiệm Jepsen trước đây có vẻ cung cấp Strong Snapshot Isolation
  • Người dùng có thể xem xét cấu trúc giao dịch của mình có dễ bị Long Fork hay không, hoặc xác minh bằng thử nghiệm rằng các điều kiện bất biến mong muốn có được duy trì không
  • Các giao dịch read có thể nhìn thấy kết quả khác nhau so với các giao dịch khác về thứ tự thực thi giao dịch
  • Vì hiện tượng bất thường có vẻ liên quan đến truy vấn vào read-only secondary, có thể khôi phục Snapshot Isolation bằng các cách sau
    • Chỉ dùng writer endpoint

      • Đưa ít nhất 1 thao tác write vào mọi giao dịch quan trọng về an toàn
      • Việc kiểm chứng của Jepsen là cách tiếp cận thực nghiệm; có thể chứng minh sự tồn tại của bug nhưng không thể chứng minh sự vắng mặt của bug
      • Báo cáo này không phải là kết quả điều tra chi tiết hành vi của RDS for PostgreSQL, mà là sản phẩm của khảo sát sơ bộ

1 bình luận

 
GN⁺ 2025-04-30
Các ý kiến trên Hacker News
  • Ước gì các bài viết trong thế giới phần mềm thường xuyên theo kiểu này hơn: “Amazon RDS for PostgreSQL là một dịch vụ của Amazon Web Services (AWS) cung cấp các instance được quản lý của cơ sở dữ liệu PostgreSQL. Chúng tôi cho thấy các cluster multi-AZ của Amazon RDS for PostgreSQL vi phạm snapshot isolation, mô hình nhất quán mạnh nhất được hỗ trợ trên mọi endpoint…”
    Thẳng thắn, đi vào trọng tâm, không tô vẽ, giống cách chia sẻ kết quả nghiên cứu trong các lĩnh vực STEM khác. Có thời tôi thích những bài blog dí dỏm giải thích bằng meme, nhưng giờ tôi lại nhớ kiểu viết plain và đơn giản

    • Ở công ty cũ của tôi từng có một blog nội bộ nơi ai cũng có thể viết và bình luận, không bắt buộc và cũng hoàn toàn không được tính vào đánh giá. Nó giống như sản phẩm từ hackathon, và vì thích viết kỹ thuật nên tôi khá tận hưởng việc đó
      Khi tôi viết những bài kỹ thuật rất sâu, gần như không có like hay bình luận, đến mức một Staff Engineer còn nói “nên thu hẹp đối tượng độc giả hơn”. Ngược lại, khi thử nghiệm Kubecost thời kỳ đầu, tôi viết một bài nói rằng các khuyến nghị giúp tiết kiệm chi phí không nhiều và có thể gây vấn đề hiệu năng container; dù đó là bài khá kỹ thuật, bàn về CPU throttling và cgroups, nhưng khi chèn meme vào thì mọi người cực kỳ thích
      Sau đó tôi viết một bài khô khan hơn về việc tạo một thư viện ngoài nhỏ cho Python bằng C, truy cập qua ctypes và so sánh cấp phát stack/heap; khi cũng chèn meme vào thì kết quả tương tự. Tôi không thích xu hướng này, nhưng để tiếp cận lượng độc giả rộng thì cũng không biết cách nào khác để tránh. Jensen không nhắm tới nhóm độc giả đó, và lối viết nghiêm ngặt, thuần túy như vậy đáng được vỗ tay
    • Tôi thật sự không còn muốn đọc các bài blog đầy meme nữa. Đặc biệt có quá nhiều bài cố kéo dài nội dung chỉ đáng một đoạn văn, và dạo này các bài viết về lỗ hổng bảo mật thường là tệ nhất
    • Tôi vừa mới nghĩ là mình nhớ Jepsen ngày xưa. Cũng kiểu tập trung vào sự thật, trực diện nhưng vẫn đầy meme. Bài Redis cũ https://aphyr.com/posts/283-call-me-maybe-redis là một ví dụ hay
    • Amazon được biết đến là có văn hóa viết kỹ thuật lành mạnh, và tôi trực tiếp thấy đúng như vậy. Đây là ý kiến cá nhân, không phải quan điểm của công ty. Cũng có bài công khai liên quan: https://quartr.com/insights/business-philosophy/amazon-s-wri...
  • Không có trong tiêu đề và trong bài cũng không thật rõ ràng, nhưng vấn đề này chỉ giới hạn ở multi-AZ cluster, một tính năng tương đối mới của RDS. Nó khác với multi-AZ instance mà nhiều người quen thuộc
    multi-AZ instance là tính năng cũ, trong đó DB chính được sao chép đồng bộ sang DB phụ ở một Availability Zone khác, và nếu DB chính lỗi thì RDS sẽ failover sang DB phụ
    multi-AZ cluster có hai DB phụ và giao dịch được sao chép đồng bộ tới ít nhất một trong số đó. Khi một DB phụ lỗi hoặc hiệu năng giảm, nó vững chắc hơn multi-AZ instance, và cũng cho phép truy cập chỉ đọc vào DB phụ
    Tuy nhiên multi-AZ cluster hẳn có thêm ma thuật bổ sung bên trong, không phải chức năng cơ bản của PostgreSQL, và có lẽ vì thế mà nó thất bại trong bài kiểm thử Jepsen

    • Thú vị là vì sao lại cần thứ ma thuật như vậy. PostgreSQL cơ bản cũng hỗ trợ quorum commit, nên có thể tạo cấu hình kiểu này. Với Patroni cũng có thể tạo cluster multi-AZ tương đương, và trừ bug ra thì nó điều chỉnh việc promote node chính để không làm mất giao dịch hoặc để lộ các giao dịch chưa durable
      Tuy nhiên PostgreSQL vẫn còn một khiếm khuyết có thể tạo ra vấn đề tương tự mẫu này. Một giao dịch không được sao chép mà client biến mất trong lúc commit sẽ lập tức trở nên visible. Trong ví dụ, nếu T1 xảy ra trên leader bị tách mạng rồi kết nối bị ngắt trong lúc commit, T2 cũng xảy ra trên node bị tách, còn T3/T4 xảy ra về sau trên leader mới, thì có thể thấy cùng kết quả. Nhưng điều này không khớp lắm với mô tả rằng bài kiểm thử này không dùng fault injection
      Sửa: Tôi đã không thấy bài viết giải thích mẫu này bằng sự không khớp thứ tự commit giữa replica và node chính. Hơi ngượng vì tôi từng trình bày cách sửa vấn đề này
    • Nếu vi phạm snapshot xảy ra trong multi-AZ instance, tôi thắc mắc liệu nó cũng có thể xảy ra trong cấu hình có nhiều read replica trong một region hay không. Tuy nhiên trong cấu hình multi-AZ, độ trễ lớn hơn nên có thể chỉ là dễ quan sát hơn
    • Ngay câu thứ hai của bài đã nói: “Các cluster multi-AZ của Amazon RDS for PostgreSQL vi phạm Snapshot Isolation”. Ta nên kỳ vọng mọi người đọc chứ
  • Điều tra tốt. Dạo này nhiều lập trình viên phần mềm thậm chí còn không hiểu rõ bản thân transaction, chứ chưa nói đến các mô hình transaction khác nhau. Tôi còn từng gặp cả những lập trình viên CRUD được gọi là “senior developer” mà hoàn toàn không biết gì về transaction trong cơ sở dữ liệu.
    Thực tế, khi có quy mô traffic và phần mềm giải quyết vấn đề không hề tầm thường, transaction và mô hình transaction rất quan trọng đối với hiệu năng và code không lỗi.
    Ví dụ, trong một dự án lớn, sau nhiều phân tích, chúng tôi đã chuyển từ Read Committed mặc định của SQL Server sang Read Committed Snapshot Isolation, và tình trạng tranh chấp lock gần như biến mất, khiến người dùng rất hài lòng. Các kỹ sư phần mềm của dự án đó dùng transaction rất nhiều, nhưng trước khi được dạy các kiến thức cơ bản thì họ hoàn toàn không biết gì về mô hình transaction hay lock.

    • Chuyện này không chỉ giới hạn ở senior developer. Tôi cũng từng thấy system architect không biết isolation level, và có người còn nhầm lẫn “consistency” trong ACID với “consistency” trong CAP.
      Vì chủ yếu làm trong lĩnh vực bán lẻ, tôi thường thấy các hệ thống đầy lỗi giống race condition; càng tiếc hơn vì những isolation level này có thể giúp ích rất nhiều trong các phần đó.
      Tuy nhiên, những trường hợp như vậy chủ yếu thấy ở kỹ sư startup, còn các lập trình viên Oracle/MSSQL điển hình ở doanh nghiệp lớn thì ít nhất cũng nắm đúng kiến thức cơ bản, nên tôi đánh giá khá cao.
    • Việc thiếu nhận thức về transaction tôi thấy nhiều nhất ở môi trường serverless/edge. Nếu có thể gọi đó là kiến trúc backend, thì đó là những nơi vận hành hoàn toàn theo yêu cầu từ client. Ví dụ, truy vấn cơ sở dữ liệu được mô hình hóa bằng React hook hoặc các lệnh gọi API tuần tự.
      Trong sự nghiệp, vài lần tôi đã thấy cách này dẫn đến kết quả thật sự tệ.
    • Chẳng bao lâu nữa, phần lớn lập trình viên phần mềm sẽ chỉ chép rác LLM thành code mà chẳng biết thực tế đang xảy ra chuyện gì. Ở Shopify việc này đã trở thành bắt buộc, còn Microsoft thì khoe rằng 1/3 phần mềm của họ được viết theo cách này. Nếu sau này không còn việc làm kỹ thuật nữa thì cũng không rõ ai sẽ bỏ thời gian ra học.
    • Lời khuyên cho junior suốt 10 năm nay vẫn như cũ. Cuối tuần đọc một cuốn sách về cơ sở dữ liệu SQL, cuối tuần sau đọc một cuốn sách về cơ sở dữ liệu đang dùng trong dự án hiện tại. Làm vậy thì rất có khả năng sẽ trở thành chuyên gia cơ sở dữ liệu của dự án đó.
    • Vài năm trước cũng có tình huống tương tự, và chúng tôi đã chuyển một sản phẩm hiện có doanh thu 1 tỷ USD từ Read Committed sang Read Committed Snapshot, nhờ đó hiệu năng cải thiện đáng kể.
      Tuy nhiên, điểm cần chú ý khi chuyển đổi là mọi code phụ thuộc vào blocking read sẽ bị hỏng. Ví dụ, những đoạn như select with exists phải được viết lại bằng explicit lock hoặc cách khác.
  • Ở công ty cũ, khi đổi lệnh pg_dump trong script backup để bắt đầu dùng worker song song (cờ -j), trong lúc restore đôi khi hiếm gặp các lỗi ám chỉ bất nhất như lỗi trùng khóa và lỗi ràng buộc khóa ngoại.
    Khi đó tôi đã định báo cho AWS và mailing list PostgreSQL, nhưng không thể tái hiện dễ dàng nên không tiến triển được, cuối cùng bỏ cuộc và quay lại dump đơn luồng. Tôi tò mò không biết hiện tượng tôi thấy lúc đó có liên quan đến vấn đề này không.

    • Tôi tò mò đó là một instance đơn, một instance có standby ở Availability Zone khác, hay là multi-AZ cluster đã được thử nghiệm ở đây.
  • Đọc bài này thì có vẻ tác động thực tế là khi một lần ghi vừa xảy ra trên cùng một hàng rồi ngay sau đó đọc rất nhanh, có thể trả về dữ liệu cũ. Transaction ghi được đánh dấu là hoàn tất, nhưng trước khi toàn bộ lớp phân tán của multi-AZ RDS instance được cập nhật hoàn toàn, nếu đọc ngay cùng hàng đó thì hàng có thể chưa tồn tại hoặc cột chưa được cập nhật đầy đủ, nên giá trị cũ được trả về.
    Theo cơ chế snapshot của PostgreSQL, có vẻ điều này không có nghĩa là chỉ một phần byte của kiểu cột nhiều byte được cập nhật rồi đọc ra một giá trị vô nghĩa.
    Rốt cuộc nó trông giống một race condition sẽ hội tụ theo thời gian. Hoặc tôi tò mò liệu có ai đọc thành nghĩa rằng các transaction về sau trong “long fork” có thể vĩnh viễn không hoàn tất ngay cả trong tình huống bình thường hay không.

    • Đây không chỉ là dữ liệu cũ theo nghĩa “một snapshot nhất quán tại một thời điểm nhất định, không phản ánh một số transaction gần đây”. Ở đây có vẻ là tình huống một transaction chỉ đọc trên node phụ quan sát thấy một transaction T, nhưng lại có thể bỏ sót các transaction lẽ ra về mặt logic phải được thực thi trước T.
  • Câu “Công việc này được Jepsen thực hiện độc lập mà không có thù lao” là nội dung mà các bên liên quan đến RDBMS sẽ không muốn thấy ngay cả vào một ngày đẹp trời. Chắc hẳn nội bộ đã có vài email bày tỏ lo ngại qua lại. Như mọi khi, xin bày tỏ sự kính trọng với aphyr.

    • “Các bên liên quan đến RDBMS” là đang nói ai vậy?
    • Nếu là bên nhận thì tôi nghĩ nên vui mới đúng. Theo truyền thống, chẳng mấy hệ thống vượt qua Jepsen một cách yên ổn, nhưng được Aphyr kiểm tra nghĩa là họ đang được đối xử một cách nghiêm túc.
  • Chưa hoàn toàn rõ liệu đây có phải là vấn đề trong các cụm PostgreSQL upstream nhiều instance hay không. Không biết có đúng khi hiểu rằng AWS đã làm gì đó trong cấu hình cụm, hoặc thêm một bản vá gây ra hành vi này hay không

    • Câu hỏi hay. Hiện vẫn chưa hiểu đủ về kiến trúc sao chép của AWS để tái hiện bằng PostgreSQL chuẩn. Có vẻ hành vi này không xảy ra trên PostgreSQL một node, nhưng có thể xảy ra trong một số cấu hình sao chép
      Sao chép PostgreSQL nhìn chung có nhiều cách khác nhau và kết quả cũng khác nhau. Ví dụ có báo cáo Patroni của Bin Wang: https://www.binwang.me/2024-12-02-PostgreSQL-High-Availabili...
    • Đây không phải là vấn đề trong cụm PostgreSQL một instance. Nhưng cụm PostgreSQL nhiều instance gồm một node primary duy nhất và các replica streaming/vật lý thì bị ảnh hưởng
      Điều được phát hiện ở đây cũng là PostgreSQL hiện không cung cấp hành vi snapshot nhất quán giữa node primary và replica. Có lẽ giao dịch chỉ đọc T2 đã chạy trên node secondary, còn các giao dịch thay đổi T1/T3/T4 chạy trên node primary
      Về bối cảnh, snapshot trên node PostgreSQL secondary dựa vào thứ tự bền vững của giao dịch, tức vị trí bản ghi commit trong WAL, để quyết định giao dịch nào nhìn thấy được. Trong khi đó, thứ tự hiển thị trên node primary được quyết định bởi thời điểm backend đã phê duyệt giao dịch lần đầu nhận thông báo rằng giao dịch đã commit hoàn toàn, và thời điểm sau đó nó đánh dấu commit
      Trên từng node primary và secondary, thứ tự commit giữa các backend được kết nối là nhất quán, nhưng thứ tự commit giữa primary và secondary có thể hơi khác nhau. Đang có công việc để cải thiện điều này, nhưng vẫn còn ở giai đoạn rất đang tiến hành
    • Còn tùy “cụm PostgreSQL upstream multi instance” nghĩa là gì. PostgreSQL không chính thức hỗ trợ failover instance primary, chỉ có cơ chế sao chép PostgreSQL có thể đồng bộ. Có thể tự xây công cụ xung quanh đó để cấu hình cụm, và Patroni là một trong các công cụ như vậy
      Có vẻ AWS đã vá PostgreSQL để sao chép sang hai instance, và xử lý là đủ nếu một trong hai xác nhận thay đổi. Việc xác nhận này xảy ra khi nào không phải thông tin công khai
      Cá nhân tôi cho rằng với PostgreSQL, sao chép ở cấp filesystem kiểu drbd sẽ tốt hơn. Các instance AWS Multi-AZ kiểu cũ có lẽ dùng cách này. Tuy nhiên throughput sẽ thấp hơn và không thể đọc từ instance secondary
    • Đúng, khác nhau. Có video giải thích sâu hơn họ đã làm gì ở đây: https://youtu.be/fLqJXTOhUg4
      Đặc biệt là đoạn này: https://youtu.be/fLqJXTOhUg4?t=434
  • Tiêu đề được gửi lên đang hỏi đúng trọng tâm. RDS for PostgreSQL 17.4 không triển khai snapshot isolation một cách đúng đắn

    • Cần một chút bối cảnh vì người trên HN thường phàn nàn về tiêu đề báo cáo Jepsen. Báo cáo Jepsen thường là sản phẩm của quá trình hợp tác dài với khách hàng, và khách hàng thường có ý kiến rất mạnh về tiêu đề báo cáo
      Các cuộc thảo luận có thể khá căng về việc tiêu đề có quá khắt khe với hệ thống hay không, quá ưu ái hay không, có nêu được vấn đề ý nghĩa nhất trong hơn chục vấn đề đã phát hiện hay không, có công bằng theo tiêu chuẩn Jepsen muốn trở thành bên trung gian trung thực cho các kết quả an toàn dữ liệu của database hay không, và 10 năm sau khi mọi người vẫn tiếp tục link nhưng không còn áp dụng cho phiên bản mới thì nên hiểu thế nào
      Sau vài lần thử gây bực bội, họ đang tránh vấn đề này bằng chính sách đặt mọi tiêu đề báo cáo theo dạng “Jepsen: ”. Nếu HN muốn văn bản link mang tính mô tả hơn hoặc nhiều màu sắc hơn thì tất nhiên có thể tự chọn
    • Bình luận này cũng bỏ sót điểm chính. Đó là trong cụm multi-AZ
      Dù vậy, vì đây là bài của Kyle Kingsbury, kiểu Chuck Norris của các bảo đảm giao dịch, AWS cần trả lời hoặc giải thích. Ngay cả khi có vẻ nó chỉ áp dụng cho cụm multi-AZ, một trong hai lựa chọn của RDS cho PostgreSQL, cũng vậy. Triển khai Multi-AZ có thể có một hoặc hai instance DB standby, và ở đây là về cấu hình có hai instance DB standby
      Tài liệu AWS không có cam kết như vậy. Bộ hướng dẫn RDS dài 5494 trang cũng hầu như chỉ nhắc đến isolation hoặc serializable trong tài liệu tham số của từng engine
      Cũng không có gì về tính nhất quán đọc toàn cục của cụm Multi-AZ. Dù là sao chép bán đồng bộ, writer chờ xác nhận bản ghi log từ một standby, nhưng hai reader có thể đang ở trên các snapshot khác nhau
      [1] - "New Amazon RDS for MySQL & PostgreSQL Multi-AZ Deployment Option: Improved Write Performance & Faster Failover" - https://aws.amazon.com/blogs/aws/amazon-rds-multi-az-db-clus...
      [2] - "Amazon RDS Multi-AZ with two readable standbys: Under the hood" - https://aws.amazon.com/blogs/database/amazon-rds-multi-az-wi...
    • Đã gửi email cho moderator yêu cầu đổi sang câu được sao chép nguyên văn từ bài được link: “Amazon RDS for PostgreSQL multi-AZ clusters violate Snapshot Isolation”
  • Nếu lập trình viên giả định snapshot isolation nhưng Amazon RDS for PostgreSQL thực tế chỉ cung cấp parallel snapshot isolation, thì tôi tò mò sẽ có những lỗi an toàn hay lỗi ở cấp ứng dụng nào có thể phát sinh, đặc biệt trong cấu hình multi-AZ dùng endpoint read replica

    • Có thể nghĩ đến một luồng như git push. Bắt đầu transaction, đọc trạng thái hiện tại rồi kiểm tra xem có khớp với trạng thái kỳ vọng không, ghi trạng thái mới, rồi commit kèm hash của trạng thái mới. Trong trường hợp không may, có thể sinh ra một commit hash không khớp với bất kỳ trạng thái hợp lệ nào
      Chính việc khó suy luận về những thứ như vậy khiến vấn đề khó tránh. Vì thế giải pháp dễ nhất có lẽ gần với việc: nếu write phụ thuộc vào điều kiện từ read, thì “có thể khôi phục snapshot isolation bằng cách chỉ dùng writer endpoint”
      Tuy vậy, khá bất ngờ là cách “chỉ dùng writer endpoint” này chưa được kiểm thử, nhất là trong tình huống mất tính sẵn sàng
    • Có thể nghĩ đến tình huống để lại bình luận bên dưới một bài đăng. Giả sử cần trao “first commenter badge” cho người bình luận đầu tiên
      User1 đăng bình luận, rồi User2 đăng bình luận; sau đó User1 trong một transaction riêng kiểm tra thấy chỉ có 1 bình luận nên nhận badge. User2 cũng thực hiện cùng kiểm tra trong một transaction riêng, chỉ thấy 1 bình luận của mình và cũng có thể nhận badge
      Với snapshot isolation, điều này là không thể. Ít nhất một trong các transaction riêng đó phải thấy 2 bình luận
      Bài báo gốc về parallel snapshot cũng đáng đọc: https://scispace.com/pdf/transactional-storage-for-geo-repli...
  • Khi thấy câu “hiện tượng này xảy ra trên tất cả các phiên bản đã thử nghiệm, từ 13.15 đến 17.4”, tôi đã lo rằng việc nâng major version là một lựa chọn sai lầm, nhưng có vẻ không phải vậy. Đây không phải là regression, mà gần với một yêu cầu tính năng hoặc một bug đã tồn tại từ lâu hơn