InnoDB เก็บข้อมูลธุรกรรมไว้ก่อนที่จะส่งมอบที่ไหน


12

ฉันได้ทำการทดสอบบางอย่างโดยใช้READ_COMMITTEDและREAD_UNCOMMITTEDที่บ้านโดยใช้เทคโนโลยี JDBC

ฉันเห็นว่าREAD_UNCOMMITTEDจริง ๆ แล้วสามารถอ่านข้อมูลที่ไม่มีข้อผูกมัดเช่นข้อมูลจากธุรกรรมบางรายการที่ยังไม่ได้รับการยืนยัน

คำถาม

  • ข้อมูลที่ไม่ได้รับการจัดเก็บอยู่ที่ไหนเช่นการREAD_UNCOMMITTEDทำธุรกรรมสามารถอ่านข้อมูลที่ปราศจากข้อผูกมัดจากการทำธุรกรรมอื่นได้หรือไม่
  • เหตุใดจึงเป็นไปไม่ได้ที่การREAD_COMMITTEDทำธุรกรรมในการอ่านข้อมูลที่ไม่มีข้อผูกมัดนั่นคือการ "อ่านสกปรก" กลไกอะไรบังคับใช้ข้อ จำกัด นี้

คำตอบ:


11

" ข้อมูลที่ไม่ได้ถูกจัดเก็บไว้ที่ใดที่ธุรกรรม READ_UNCOMMITTED สามารถอ่านข้อมูลที่ไม่ได้รับการยอมรับจากธุรกรรมอื่นได้ "

บันทึกรุ่นปราศจากข้อผูกมัด (PK แบบคลัสเตอร์) จะถือว่าเป็นรุ่น "ปัจจุบัน" ของบันทึกในหน้า ดังนั้นพวกเขาสามารถเก็บไว้ในบัฟเฟอร์พูลและ / หรือใน tablespace (เช่น tablename.ibd) ธุรกรรมที่จำเป็นต้องสร้างสแน็ปช็อต / มุมมองในสิ่งอื่นใดนอกจาก READ-UNCOMMITTED จำเป็นต้องสร้างแถวเวอร์ชันก่อนหน้า (ตามรายการประวัติ) โดยใช้เรคคอร์ด UNDO (เก็บไว้ในพื้นที่ตารางระบบ ) เมื่ออ่านระเบียนที่ไม่มีข้อผูกมัด InnoDB อาจต้องอ่านบันทึกดัชนีรองที่ไม่ได้รับการผูกมัดจากChange Bufferและนำไปใช้ก่อนที่จะนำเสนอบันทึกกลับไปยังผู้ใช้

พฤติกรรมนี้สามารถทำให้การย้อนกลับใน InnoDB ค่อนข้างแพง เป็นปัจจัยใหญ่ที่สามารถนำไปสู่ปัญหาประสิทธิภาพการทำงานที่อาจเกิดขึ้นจากการทำธุรกรรมที่ไม่ได้ใช้งานเป็นเวลานานซึ่งมีการบันทึกการปรับปรุงเนื่องจากการทำธุรกรรมเหล่านั้นจะปิดกั้นการดำเนินงานและประวัติรายการของบันทึกรุ่นเก่า ตามความต้องการจะยังคงเติบโต มันช้าลงธุรกรรมใหม่ที่จำเป็นต้องอ่านรุ่นเก่า / มุ่งมั่นของระเบียนตามที่พวกเขาต้องการที่จะสำรวจรายการประวัติอีกต่อไปและยาวซึ่งเป็นรายการเชื่อมโยงเดี่ยวของบันทึก UNDO - และทำงานมากขึ้นเพื่อสร้างใหม่ บันทึกรุ่นเก่า ดังนั้นคุณจะใช้ซีพียูจำนวนมาก (ไม่ต้องพูดถึงการล็อกภายในแบบพื้นฐาน: mutexes, rw_locks, semaphores เป็นต้น

หวังว่ามันสมเหตุสมผล :)

ในฐานะที่เป็น FYI ใน MySQL 5.7 คุณสามารถย้ายพื้นที่ตาราง UNDO และออกจากระบบพื้นที่ตารางและให้ตัดทอนโดยอัตโนมัติ พวกเขาสามารถเติบโตได้ค่อนข้างใหญ่หากคุณมีธุรกรรมที่ใช้เวลานานซึ่งป้องกันการดำเนินการกวาดล้างส่งผลให้มีความยาวของรายการประวัติยาวมากและไม่เคยเติบโต การเก็บมันไว้ใน tablespace ของระบบเป็นสาเหตุที่พบบ่อยที่สุดของไฟล์ ibdata1 / ที่กำลังเติบโตซึ่งไม่สามารถถูกตัดทอน / หด / สุญญากาศเพื่อที่จะเรียกคืนพื้นที่นั้นในภายหลัง


4

คุณถาม

ข้อมูลที่ไม่ได้รับการจัดเก็บอยู่ที่ไหนเช่นธุรกรรม READ_UNCOMMITTED สามารถอ่านข้อมูลที่ปราศจากข้อผูกมัดจากธุรกรรมอื่นได้หรือไม่

ในการที่จะตอบคำถามของคุณคุณจำเป็นต้องรู้ว่าสถาปัตยกรรมของ InnoDB เป็นอย่างไร

รูปต่อไปนี้ถูกสร้างขึ้นเมื่อหลายปีก่อนโดย Percona CTO Vadim Tkachenko

สถาปัตยกรรม InnoDB

ตามเอกสาร MySQL ในรูปแบบการทำธุรกรรม InnoDB และการล็อค

COMMIT หมายถึงการเปลี่ยนแปลงที่เกิดขึ้นในการทำธุรกรรมในปัจจุบันนั้นเป็นการถาวรและสามารถมองเห็นได้ในช่วงอื่น ๆ ในทางกลับกันคำสั่ง ROLLBACK ยกเลิกการแก้ไขทั้งหมดที่ทำโดยการทำธุรกรรมปัจจุบัน ทั้ง COMMIT และ ROLLBACK ปล่อยการล็อค InnoDB ทั้งหมดที่ตั้งค่าไว้ระหว่างการทำธุรกรรมปัจจุบัน

เนื่องจาก COMMIT และ ROLLBACK ควบคุมการเปิดเผยข้อมูลดังนั้น READ COMMITTED และ READ UNCOMMITTED จึงต้องอาศัยโครงสร้างและกลไกที่บันทึกการเปลี่ยนแปลง

  1. ส่วนย้อนกลับ / เลิกทำพื้นที่
  2. ทำซ้ำบันทึก
  3. Gaps Locks เทียบกับตารางที่เกี่ยวข้อง

เซ็กเมนต์ Rollback และ Undo Space จะทราบว่าข้อมูลที่เปลี่ยนแปลงมีลักษณะอย่างไรก่อนที่จะมีการเปลี่ยนแปลง บันทึกการทำซ้ำจะรู้ว่าการเปลี่ยนแปลงใดที่จะถูกนำไปใช้เพื่อให้มีข้อมูลอัปเดตปรากฏขึ้น

คุณยังถาม

เหตุใดจึงเป็นไปไม่ได้ที่ธุรกรรม READ_COMMITTED ในการอ่านข้อมูลที่ไม่มีข้อผูกมัดเช่นกำลังทำการ "อ่านสกปรก" กลไกอะไรบังคับใช้ข้อ จำกัด นี้

บันทึกการทำซ้ำเลิกทำพื้นที่และแถวที่ถูกล็อค คุณต้องพิจารณาว่า InnoDB Buffer Pool (ซึ่งคุณสามารถวัดหน้าสกปรกด้วยinnodb_max_dirty_pages_pct , innodb_buffer_pool_pages_dirtyและinnodb_buffer_pool_bytes_dirty )

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

เพื่อให้เข้าใจการล็อกแถวเพื่อจัดการแยกอย่างสมบูรณ์โปรดอ่านรูปแบบการทำธุรกรรมและการล็อค InnoDB


1
ก่อนอื่นขอขอบคุณสำหรับคำตอบและการแก้ไขโพสต์ของฉัน ... ดังนั้นก่อนที่จะคอมมิทผู้ใช้คนอื่น ๆ ของระบบจะไม่เห็นการเปลี่ยนแปลงหรือไม่ ผู้ใช้ที่นี่หมายถึงการทำธุรกรรมใช่ไหม? เนื่องจาก READ UNCOMMITTED สามารถอ่านข้อมูลที่ไม่มีข้อผูกมัดระดับการแยกนี้อ่านข้อมูลนี้ได้ที่ไหน มีแหล่งข้อมูลที่ไม่มีข้อผูกมัดมากกว่าหนึ่งแหล่งสำหรับรายการข้อมูลในฐานข้อมูลหรือไม่? ถ้าเป็นเช่นนั้นส่วนใดของข้อมูลที่ไม่ได้ถูกเปิดเผยจะถูกอ่าน
Shuzheng
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.