3 คะแนน โดย GN⁺ 2023-12-20 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

ภูมิหลังของ MySQL

  • MySQL เป็นหนึ่งในฐานข้อมูล SQL ที่ถูกนำไปใช้อย่างแพร่หลายที่สุดตลอดช่วง 28 ปีที่ผ่านมา
  • ใช้เป็นหลักสำหรับการประมวลผลธุรกรรมออนไลน์ (OLTP) และยังถูกนำไปใช้เป็นส่วนหนึ่งของระบบ OLAP และระบบคิวด้วย
  • เดิมออกแบบมาให้เป็นฐานข้อมูลแบบเซิร์ฟเวอร์เดียว แต่ได้ขยายความสามารถผ่านรูปแบบการทำ replication แบบหลายโหนดหลากหลายแบบ
  • บทความนี้วิเคราะห์ MySQL โดยมุ่งเน้นที่การใช้ InnoDB storage engine

ระดับการแยกธุรกรรมของ ANSI SQL แย่กว่าที่คิด

  • เพื่ออธิบายความละเอียดอ่อนของระดับการแยกธุรกรรมใน SQL จำเป็นต้องอธิบายภูมิหลังทางประวัติศาสตร์ของระดับความปลอดภัย 4 ระดับสำหรับความสอดคล้องของธุรกรรมที่เสนอในปี 1977 และมาตรฐาน SQL ที่ ANSI เผยแพร่ในปี 1986
  • ANSI SQL กำหนดระดับการแยกธุรกรรมผ่านปรากฏการณ์ที่เป็นไปได้ 3 แบบ ได้แก่ dirty read, non-repeatable read และ phantom
  • ในปี 1995 มีการชี้ให้เห็นข้อบกพร่องของระดับการแยกธุรกรรมใน ANSI SQL และในปี 1999 Adya ได้พัฒนาคำนิยามเชิงรูปแบบและไม่ขึ้นกับการนำไปใช้สำหรับระดับการแยกธุรกรรมของ ANSI SQL

ระดับการแยกธุรกรรมของ MySQL

  • เอกสารของ MySQL ระบุว่ารองรับระดับการแยกธุรกรรม 4 ระดับตามที่อธิบายไว้ในมาตรฐาน SQL:1992
  • มีคำอธิบายว่า MySQL บรรลุแต่ละระดับการแยกธุรกรรมเหล่านี้ได้อย่างไร
  • ระดับ Repeatable Read ของ MySQL รับประกันความปลอดภัยผ่านกลไก snapshot

การออกแบบการทดสอบ

  • ออกแบบชุดทดสอบสำหรับ MySQL โดยใช้ไลบรารีทดสอบของ Jepsen
  • ทำการทดสอบในหลายสภาพแวดล้อม เช่น MySQL แบบโหนดเดียว, คลัสเตอร์ replication แบบ binlog และคลัสเตอร์ AWS RDS
  • ใช้ตัวตรวจสอบ list-append ของ Elle เพื่อรันเวิร์กโหลดหลักสำหรับการแยกธุรกรรม

ผลลัพธ์

  • Repeatable Read ของ MySQL อนุญาตให้เกิด G2-item ซึ่งระดับการแยกธุรกรรม PL-2.99 ของ Adya ห้ามไว้
  • Repeatable Read ของ MySQL ยังอนุญาตให้เกิด G-single (read skew)
  • Repeatable Read ของ MySQL อนุญาตให้เกิดปรากฏการณ์ P4 (lost update)
  • Repeatable Read ของ MySQL แสดงข้อผิดพลาดด้านความสอดคล้องภายใน
  • Repeatable Read ของ MySQL ละเมิด Monotonic Atomic View

GN⁺ ความเห็น

  • การที่ระดับ Repeatable Read ของ MySQL แสดงพฤติกรรมต่างจากที่ระบุไว้ในมาตรฐาน เป็นข้อมูลสำคัญสำหรับนักพัฒนาและผู้ดูแลฐานข้อมูล เพราะอาจหมายความว่าไม่สามารถตอบสนองความคาดหวังด้านความสอดคล้องและการแยกธุรกรรมของข้อมูลได้
  • ผลการทดสอบให้ข้อมูลที่จำเป็นต่อการทำความเข้าใจระดับการแยกธุรกรรมของระบบฐานข้อมูล และการเลือกใช้กลไกการแยกธุรกรรมที่เหมาะสม
  • ข้อค้นพบเหล่านี้ให้มุมมองว่ามาตรฐานที่เกี่ยวข้องกับระดับการแยกธุรกรรมของฐานข้อมูลอาจแตกต่างจากการนำไปใช้จริงอย่างไร ซึ่งช่วยให้เข้าใจความซับซ้อนของเทคโนโลยีฐานข้อมูลและความแตกต่างอันละเอียดอ่อนของระดับการแยกธุรกรรมได้ดีขึ้น

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

 
GN⁺ 2023-12-20
ความคิดเห็นจาก Hacker News
  • ผู้แปลยืนกรานมานานว่า repeatable read เป็นไอเดียที่ไม่ดี ต่อให้การใช้งานจะสมบูรณ์แบบและทำงานได้ถูกต้องในฐานข้อมูล ก็ยังเข้าใจยากเมื่อต้องจัดการกับคิวรีที่ซับซ้อน

    • คิดว่ามีระดับการแยกธุรกรรมที่มีความหมายอยู่สองแบบ:
      • read committed
      • serializable
    • การตั้งค่า serializable ไม่มีเรื่องไม่คาดคิดเกิดขึ้น ส่วนแนวทาง read committed ก็ชัดเจนว่าถ้าต้องการมุมมองของข้อมูลที่สอดคล้องกัน จะต้องล็อกก่อนเริ่มอ่านแถว
    • read committed คล้ายกับโค้ดมัลติเธรดทั่วไปและการจัดการหน่วยความจำมาก ทำให้วิศวกรส่วนใหญ่เข้าใจได้โดยสัญชาตญาณ
    • serializable เข้มงวดมากจนยากที่จะพลาดแบบไม่คาดคิด
    • ระดับตรงกลางเป็นพื้นที่ที่ไม่มีใครอยู่ และสิ่งที่สอดคล้องน้อยกว่า Read Committed ก็ไม่ควรเรียกว่าฐานข้อมูลอีกต่อไป
  • มีกำหนดบรรยายหัวข้อ "Isolation Levels and MVCC in SQL Databases: A Technical Comparative Study" ที่ FOSSDEM-2024

    • เป็นงานศึกษาเปรียบเทียบ Oracle, MySQL, SQL Server, PostgreSQL และ YugabyteDB
  • กำลังประเมินบทความเกี่ยวกับ AWS RDS แต่อยากรู้ว่ามีการโฟกัสไปที่ AWS Aurora (MySQL) หรือไม่ AWS สร้างแพลตฟอร์มฐานข้อมูลที่แสร้งว่าเป็น MySQL หรือ PostgreSQL น่าสนใจที่จะดูว่า Aurora MySQL มี "คุณสมบัติ" แบบเดียวกับ RDS หรือ MariaDB หรือไม่

  • คิดว่านี่เป็นตัวอย่างที่ยอดเยี่ยมของ "ระบบที่ใช้งานได้จริง" ซึ่งสร้างอยู่บนฐานที่แสดงอาร์ติแฟกต์ด้านความสอดคล้องจำนวนมาก

  • ค่อนข้างน่ากังวลที่การจำลองข้อมูลของ RDS หยุดทำงานภายใน 5 นาที และไม่มีการแจ้งเตือนความล้มเหลวของ health check

  • สงสัยว่า append (a) ถูกแมปกับการทำงาน SQL จริงในตารางนั้นอย่างไร และฟิลด์ TEXT ถูกใช้เป็นลิสต์หรือไม่

    • เคยมีปัญหาในโหมด repeatable read ของ MySQL ที่ SELECT เดียวเลือกเพียงแถวเดียวแต่กลับคืนผลลัพธ์ที่เป็นไปไม่ได้ ตัวอย่างเช่น ใน SELECT min(value), max(value) FROM table WHERE id = 1; โดยที่ id เป็น primary key กลับเคยได้ค่าของ min และ max ที่ต่างกัน
  • น่าจะมีประโยชน์หากเปรียบเทียบไม่ใช่แค่กับนิยามเชิงทฤษฎีของโหมดการแยกธุรกรรม แต่รวมถึงฐานข้อมูลเชิงสัมพันธ์ยอดนิยมอื่น ๆ เช่น PostgreSQL, MS SQL และ Oracle ด้วย นี่คือสิ่งที่นักพัฒนาควรคำนึงถึงเมื่อต้องการความเข้ากันได้

  • ดูเหมือนว่า SELECT ... FOR UPDATE จะเป็นคำตอบของทุกปัญหาเหล่านี้ เพราะถ้าล็อกแถวที่จะอัปเดต ทุกอย่างก็จะทำงานตามที่โฆษณาไว้

  • เดิมทีวันนี้ตั้งใจจะทำงานสักหน่อย แต่ก็อยากขอบคุณที่ aphyr's 'call me maybe' และ jepsen.io เป็นหนึ่งในคอนเทนต์ที่ดีที่สุดที่เคยอ่านบนอินเทอร์เน็ต

  • สงสัยว่าเนื้อหาในการวิเคราะห์ MySQL นี้จะมีส่วนไหนบ้างที่ใช้ได้เหมือนกันกับ MariaDB ซึ่งใช้ InnoDB เป็น storage engine เริ่มต้น