2 คะแนน โดย GN⁺ 2025-04-30 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Multi-AZ cluster ของ Amazon RDS for PostgreSQL รองรับ Snapshot Isolation อย่างเป็นทางการ, แต่ในทางปฏิบัติมักเกิด วงจร G-nonadjacent และปรากฏการณ์ Long Fork ที่ละเมิดคุณสมบัตินี้
  • การทดสอบอิงจาก PostgreSQL transaction workload ที่สร้างขึ้นเอง และพบว่า เกิดข้อผิดพลาดด้านความสอดคล้องในทุกเวอร์ชันตั้งแต่ PostgreSQL 13.15 ถึง 17.4
  • ข้อผิดพลาดเหล่านี้เกิดขึ้นหลัก ๆ บน secondary node แบบอ่านอย่างเดียว และ Snapshot Isolation ก็ยังพังได้แม้อยู่ในระดับ "Repeatable Read"
  • RDS cluster อาจให้ความสอดคล้องในระดับ Parallel Snapshot Isolation ซึ่งเป็นโมเดลที่อ่อนกว่าของ PostgreSQL แบบ single node พื้นฐาน
  • Transaction แบบอ่านอย่างเดียวอาจสังเกตลำดับของ transaction ที่ต่างกัน และความไม่สอดคล้องนี้อาจนำไปสู่ข้อผิดพลาดด้านความถูกต้องของข้อมูล

Background

  • PostgreSQL เป็น SQL DB โอเพนซอร์สที่ใช้ MVCC และมีระดับ transaction isolation หลายแบบ โดย Repeatable Read ในทางปฏิบัติหมายถึง Snapshot Isolation
  • Amazon RDS ให้บริการ PostgreSQL ในรูปแบบ managed cluster และการตั้งค่า Multi-AZ เป็นสถาปัตยกรรมเพื่อการ replication และ fault tolerance
  • endpoint หลักสามารถอ่าน/เขียนได้, ส่วน secondary เป็นแบบอ่านอย่างเดียวและไม่รองรับระดับ Serializable

Test Design

  • นำเครื่องมือทดสอบ Jepsen PostgreSQL มาห่อให้เข้ากับ RDS เพื่อรันทดสอบ transaction แบบอัตโนมัติ
  • ออกแบบ transaction ให้มีโครงสร้างเป็นการอ่านลิสต์ของคีย์ที่กำหนด หรือ append เลขจำนวนเต็มที่ไม่ซ้ำเข้าไป, และใช้ Elle checker เพื่อตรวจจับ cycle
  • ยืนยันการเกิด Long Fork และ G-nonadjacent ได้ภายใน 2 นาที ภายใต้โหลด 150 TPS สำหรับการเขียน และ 1600 TPS สำหรับการอ่าน

Results

  • พิสูจน์การละเมิด Snapshot Isolation ผ่านวงจร G-nonadjacent ที่ประกอบด้วย 4 transaction
    • T₂ มองเห็นการเปลี่ยนแปลงของ T₁ แต่ไม่เห็น T₃ ขณะที่ T₄ เห็น T₃ แต่ไม่เห็น T₁ → เกิดความขัดแย้งกันของลำดับเวลา
  • นี่คือ ปรากฏการณ์ Long Fork และเป็น กรณีที่ชัดเจนซึ่งพิสูจน์การละเมิด Snapshot Isolation
  • ไม่พบ Write Skew จึงช่วยสนับสนุนความเป็นไปได้ว่าเป็น Parallel Snapshot Isolation

Discussion

  • Multi-AZ RDS มีระดับความสอดคล้องต่ำกว่า PostgreSQL แบบ single node
  • เมื่อใช้ read-only node มีความเป็นไปได้ที่จะเกิดข้อผิดพลาดด้านความสอดคล้อง จึงควรพิจารณาใช้เฉพาะ write node หรือทำให้ทุก transaction มีการเขียนอย่างน้อยหนึ่งครั้ง
  • การวิเคราะห์ครั้งนี้ยังเป็นเพียงการทดสอบระยะแรก และ พิสูจน์ได้ว่าปัญหามีอยู่ แต่ไม่ได้รับประกันว่าไม่มีปัญหาอื่นเพิ่มเติม

1 ความคิดเห็น

 
GN⁺ 2025-04-30
ความเห็นบน Hacker News
  • แม้จะไม่ได้ระบุไว้อย่างชัดเจนในชื่อบทความ แต่นี่เกี่ยวกับฟีเจอร์ใหม่ของ RDS ที่ชื่อว่า Multi-AZ Cluster

    • Multi-AZ Instance คือฟีเจอร์แบบเดิมที่ทำ replication แบบ synchronous จากฐานข้อมูลหลักไปยังฐานข้อมูลสำรองในอีก AZ
    • Multi-AZ Cluster มีฐานข้อมูลสำรองสองตัว และทรานแซกชันจะถูกทำ replication แบบ synchronous ไปยังฐานข้อมูลสำรองอย่างน้อยหนึ่งตัว
    • ทำให้ระบบทนทานกว่าเมื่อฐานข้อมูลสำรองล้มเหลวหรือประสิทธิภาพลดลง และยังอนุญาตให้เข้าถึงฐานข้อมูลสำรองแบบอ่านอย่างเดียวได้
    • Multi-AZ Cluster ไม่ใช่ความสามารถปกติของ Postgres และอาจเป็นสาเหตุที่ทำให้ไม่ผ่านการทดสอบของ Jepsen
  • ที่บริษัทก่อนหน้านี้ ตอนที่มีการเปลี่ยนคำสั่ง pg_dump ในสคริปต์แบ็กอัปให้ใช้ worker แบบขนาน (แฟลก -j) ก็พบปัญหาความสอดคล้องกันตอนกู้คืนแบ็กอัป เช่น duplicated key error และ fk constraint error

    • มีการรายงานปัญหานี้ไปยัง AWS และ mailing list ของ Postgres แต่เพราะทำให้เกิดซ้ำได้ไม่ง่าย จึงไม่ได้รับการแก้ไข
    • สุดท้ายก็กลับไปใช้การ dump แบบเธรดเดียว และสงสัยว่าปัญหานี้เกี่ยวข้องกับพฤติกรรมที่เราเคยเจอหรือไม่
  • นี่เป็นงานที่ Jepsen ทำอย่างอิสระ และไม่ได้รับค่าตอบแทน

    • เป็นข่าวที่ผู้มีส่วนได้ส่วนเสียกับ RDBMS คงไม่อยากได้ยินในวันที่ทุกอย่างกำลังไปได้สวย
    • ขอคารวะ aphyr
  • ความหมายในทางปฏิบัติของปัญหานี้คือ การอ่านที่เกิดขึ้นอย่างรวดเร็วหลังการเขียนลงแถวเดียวกัน อาจคืนค่าข้อมูลเก่าได้

    • ก่อนที่ทรานแซกชันเขียนจะแสดงสถานะว่าเสร็จสมบูรณ์ เลเยอร์แบบกระจายทั้งหมดของอินสแตนซ์ RDS แบบ Multi-AZ อาจยังอัปเดตไม่ครบถ้วน ทำให้การอ่านทันทีอาจได้แถวที่ไม่มีอยู่จริงหรือค่าเก่า
    • เนื่องจากวิธีทำ snapshot ของ PostgreSQL จึงไม่ได้หมายความว่าจะมีการอัปเดตเพียงบางไบต์ของชนิดคอลัมน์แบบหลายไบต์จนทำให้การอ่านได้ค่าที่ไร้ความหมาย
    • มันดูเหมือน race condition ที่ท้ายที่สุดแล้วจะกลับมามีความสอดคล้องกัน
  • ยังไม่ชัดเจนว่าใน upstream Postgres cluster แบบหลายอินสแตนซ์จะไม่มีปัญหานี้จริงหรือไม่

    • จึงสงสัยว่า AWS เพิ่มอะไรบางอย่างเข้าไปในโครงสร้างของคลัสเตอร์ หรือเพิ่มแพตช์ที่ทำให้เกิดพฤติกรรมนี้หรือไม่
  • ชื่อที่ส่งมานั้นกลบประเด็นสำคัญไว้: RDS สำหรับ PostgreSQL 17.4 ไม่ได้ implement snapshot isolation อย่างถูกต้อง

  • ถ้านักพัฒนาคิดว่าได้ snapshot isolation แต่ Amazon RDS for PostgreSQL ให้จริงเพียง parallel snapshot isolation จะเกิดปัญหาด้านความปลอดภัยหรือบั๊กระดับแอปพลิเคชันอะไรได้บ้าง โดยเฉพาะในคอนฟิกแบบ Multi-AZ ที่ใช้ read replica endpoint

  • ปรากฏการณ์นี้เกิดขึ้นในทุกเวอร์ชันที่ทดสอบตั้งแต่ 13.15 ถึง 17.4

    • ตอนแรกกังวลว่าการอัปเกรดเมเจอร์เวอร์ชันเป็นการตัดสินใจที่ผิด แต่ดูแล้วนี่ไม่ใช่ regression หากเป็น feature request หรือบั๊กที่มีมานาน
  • น่าจะดีถ้ามีการทดสอบ Jepsen กับทุกเวอร์ชันของ Amazon RDS

  • AWS ควรอัปเดตเอกสารเพื่อสื่อสารเรื่องนี้

    • สงสัยว่าการแก้ snapshot isolation จะทำให้เกิด performance regression ในด้าน latency หรือ throughput หรือ AWS จะยืนยันแทนว่าสถานะปัจจุบันแข็งแรงเพียงพอแล้ว
    • ไม่ว่าอย่างไร AWS ก็ควรพูดถึงเรื่องนี้