อ่าน 3 นาที
การควบคุมการทำงานพร้อมกันแบบหลายเวอร์ชัน
การควบคุมการทำงานพร้อมกันแบบหลายเวอร์ชัน ( MCC หรือ MVCC ) เป็น วิธี การควบคุมการทำงานพร้อมกันแบบไม่ใช้การล็อก ซึ่งมักใช้ใน ระบบจัดการฐานข้อมูล...
การควบคุมการทำงานพร้อมกันแบบหลายเวอร์ชัน
การควบคุมการทำงานพร้อมกันแบบหลายเวอร์ชัน ( MCCหรือMVCC ) เป็น วิธี การควบคุมการทำงานพร้อมกันแบบไม่ใช้การล็อกซึ่งมักใช้ในระบบจัดการฐานข้อมูลเพื่อให้สามารถเข้าถึงฐานข้อมูลพร้อมกันได้ และในภาษาโปรแกรมเพื่อใช้งานหน่วยความจำธุรกรรม[ 1 ]
คำอธิบาย
หากไม่มีการควบคุมการทำงานพร้อมกัน หากมีคนกำลังอ่านข้อมูลจากฐานข้อมูลในขณะที่อีกคนหนึ่งกำลังเขียนข้อมูลลงไป ผู้อ่านอาจเห็นข้อมูลที่เขียนไม่เสร็จหรือข้อมูลที่ไม่สอดคล้องกัน ตัวอย่างเช่น เมื่อทำการ โอนเงินระหว่างสองบัญชีธนาคาร หากผู้อ่านอ่านยอดเงินคงเหลือในธนาคารหลังจากที่เงินถูกถอนออกจากบัญชีต้นทางแล้ว และก่อนที่เงินจะถูกฝากเข้าบัญชีปลายทาง ก็อาจทำให้ดูเหมือนว่าเงินหายไปจากธนาคาร การแยกส่วน (Isolation) คือคุณสมบัติที่ให้การรับประกันในการเข้าถึงข้อมูลพร้อมกัน การแยกส่วนนี้ถูกนำไปใช้โดยใช้ โปรโตคอล ควบคุมการทำงานพร้อมกันวิธีที่ง่ายที่สุดคือการทำให้ผู้อ่านทุกคนรอจนกว่าผู้เขียนจะทำงานเสร็จ ซึ่งเรียกว่า การ ล็อกแบบอ่าน-เขียน (read-write lock ) การล็อกมักก่อให้เกิดการแย่งชิงทรัพยากรโดยเฉพาะอย่างยิ่งระหว่างธุรกรรมการอ่านที่ใช้เวลานานและธุรกรรมการอัปเดต MVCC มุ่งแก้ปัญหานี้โดยการเก็บสำเนาข้อมูลแต่ละรายการไว้หลายชุด ด้วยวิธีนี้ ผู้ใช้แต่ละคนที่เชื่อมต่อกับฐานข้อมูลจะเห็นภาพรวมของฐานข้อมูล ณ ช่วงเวลาใดเวลาหนึ่ง การเปลี่ยนแปลงใดๆ ที่ผู้เขียนทำขึ้น จะไม่ปรากฏให้ผู้ใช้รายอื่นในฐานข้อมูลเห็น จนกว่าการเปลี่ยนแปลงนั้นจะเสร็จสมบูรณ์ (หรือในแง่ของฐานข้อมูล คือ จนกว่าการทำธุรกรรมจะได้รับการยืนยัน)
เมื่อฐานข้อมูล MVCC ต้องการอัปเดตข้อมูล ระบบจะไม่เขียนทับข้อมูลเดิมด้วยข้อมูลใหม่ แต่จะสร้างเวอร์ชันใหม่ของข้อมูลนั้นแทน ดังนั้นจึงมีการจัดเก็บเวอร์ชันต่างๆ ไว้หลายเวอร์ชัน เวอร์ชันที่แต่ละธุรกรรมเห็นจะขึ้นอยู่กับระดับการแยกธุรกรรมที่นำมาใช้ ระดับการแยกธุรกรรมที่ใช้กันทั่วไปใน MVCC คือการแยกธุรกรรมแบบสแนปช็อต (Snapshot Isolation ) การแยกธุรกรรมแบบสแนปช็อตจะทำให้ธุรกรรมสังเกตสถานะของข้อมูล ณ เวลาที่ธุรกรรมเริ่มต้นขึ้น
MVCC ให้ มุมมอง ที่สอดคล้องกัน ณ จุดเวลาใดเวลาหนึ่งการทำธุรกรรมการอ่านภายใต้ MVCC โดยทั่วไปจะใช้การประทับเวลาหรือรหัสธุรกรรมเพื่อกำหนดสถานะที่จะอ่านจากฐานข้อมูล และอ่านข้อมูลในเวอร์ชันเหล่านั้น ดังนั้น การทำธุรกรรมการอ่านและการเขียนจึงแยกออกจากกันโดยไม่จำเป็นต้องใช้การล็อก อย่างไรก็ตาม แม้ว่าการล็อกจะไม่จำเป็น แต่ฐานข้อมูล MVCC บางฐาน เช่น Oracle ก็ยังใช้การล็อกอยู่ การเขียนจะสร้างเวอร์ชันใหม่กว่า ในขณะที่การอ่านพร้อมกันจะเข้าถึงเวอร์ชันที่เก่ากว่า
MVCC นำเสนอความท้าทายในการลบเวอร์ชันที่ล้าสมัยและจะไม่ถูกอ่านอีกต่อไป ในบางกรณี จะมีการนำกระบวนการตรวจสอบและลบเวอร์ชันที่ล้าสมัยออกเป็นระยะๆ ซึ่งมักจะเป็นกระบวนการหยุดการทำงานทั้งหมด (stop-the-world) ที่ตรวจสอบทั้งตารางและเขียนทับด้วยเวอร์ชันล่าสุดของแต่ละรายการข้อมูลPostgreSQLสามารถใช้วิธีนี้ได้ด้วย กระบวนการ VACUUM FREEZEฐานข้อมูลอื่นๆ จะแบ่งบล็อกจัดเก็บข้อมูลออกเป็นสองส่วน คือ ส่วนข้อมูลและส่วนบันทึกการเปลี่ยนแปลง (undo log) ส่วนข้อมูลจะเก็บเวอร์ชันที่ยืนยันล่าสุดเสมอ ส่วนบันทึกการเปลี่ยนแปลงช่วยให้สามารถสร้างเวอร์ชันเก่าของข้อมูลขึ้นมาใหม่ได้ ข้อจำกัดหลักของวิธีหลังนี้คือ เมื่อมีปริมาณงานที่ต้องอัปเดตจำนวนมาก ส่วนบันทึกการเปลี่ยนแปลงจะหมดพื้นที่ และธุรกรรมจะถูกยกเลิกเนื่องจากไม่สามารถบันทึกภาพรวม (snapshot) ได้ สำหรับฐานข้อมูลแบบเอกสารวิธีนี้ยังช่วยให้ระบบสามารถเพิ่มประสิทธิภาพเอกสารได้โดยการเขียนเอกสารทั้งหมดลงในส่วนที่ต่อเนื่องกันของดิสก์ เมื่อมีการอัปเดต เอกสารทั้งหมดสามารถเขียนทับได้แทนที่จะตัดส่วนต่างๆ ออกหรือเก็บไว้ในโครงสร้างฐานข้อมูลที่เชื่อมโยงกันและไม่ต่อเนื่อง
การดำเนินการ
MVCC ใช้การประทับเวลา ( TS ) และรหัสธุรกรรมที่เพิ่มขึ้นเรื่อยๆเพื่อให้เกิดความสอดคล้องของธุรกรรม MVCC รับประกันว่าธุรกรรม ( T ) จะไม่ต้องรอเพื่ออ่านวัตถุในฐานข้อมูล ( P ) โดยการเก็บรักษาวัตถุไว้หลายเวอร์ชัน แต่ละเวอร์ชันของวัตถุPมีทั้งการประทับเวลาอ่าน ( RTS ) และการประทับเวลาเขียน ( WTS ) ซึ่งช่วยให้ธุรกรรมTi สามารถอ่านเวอร์ชันล่าสุดของวัตถุที่อยู่ก่อนหน้าการประทับเวลาอ่านRTS ของธุรกรรม ( T i ) ได้
หากธุรกรรมTiต้องการเขียนข้อมูลไปยังวัตถุPและมีธุรกรรมTk อีกธุรกรรมหนึ่ง กำลังดำเนินการกับวัตถุเดียวกันอยู่ เวลาประทับการอ่าน( RTS )ของ Ti ต้องอยู่ก่อนเวลาประทับการอ่าน( RTS ) ของ Tk กล่าวคือRTSของTi < RTSของTkเพื่อให้การดำเนินการเขียน ข้อมูล ( WTS )สำเร็จการเขียนข้อมูลจะไม่สามารถเสร็จสมบูรณ์ได้หากมีธุรกรรมอื่นที่ค้างอยู่ซึ่งมีเวลาประทับการอ่าน (RTS) ก่อนหน้าสำหรับวัตถุ เดียวกัน เปรียบเสมือนคนที่ยืนต่อแถวในร้านค้า พวกเขาจะไม่สามารถทำรายการชำระเงินให้เสร็จสมบูรณ์ได้จนกว่าคนที่อยู่ข้างหน้า จะทำรายการของตนเสร็จสมบูรณ์
กล่าวอีกครั้งคือ วัตถุทุกชิ้น ( P ) มีการประทับเวลา ( TS ) อย่างไรก็ตาม หากธุรกรรมTi ต้องการเขียนไปยังวัตถุ และการประทับเวลา ( TS ) ของธุรกรรมนั้นเร็วกว่าการประทับเวลาอ่านปัจจุบันของวัตถุTS ( Ti ) < RTS ( P ) ธุรกรรมนั้นจะถูกยกเลิกและเริ่มต้นใหม่ (เนื่องจากธุรกรรมในภายหลังขึ้นอยู่กับค่าเก่าอยู่แล้ว) มิฉะนั้นTi จะสร้างเวอร์ชันใหม่ของวัตถุPและตั้งค่าการประทับเวลาอ่าน/เขียนTSของเวอร์ชันใหม่ให้เท่ากับการประทับเวลาของธุรกรรมTS ← TS ( Ti ) [ 2 ]
ข้อเสียของระบบนี้คือค่าใช้จ่ายในการจัดเก็บอ็อบเจ็กต์หลายเวอร์ชันในฐานข้อมูล ในทางกลับกัน การอ่านจะไม่ถูกบล็อก ซึ่งอาจมีความสำคัญสำหรับงานที่เกี่ยวข้องกับการอ่านค่าจากฐานข้อมูลเป็นส่วนใหญ่ MVCC มีความสามารถพิเศษในการใช้งานการแยกแบบสแนปช็อต อย่างแท้จริง ซึ่งวิธีการควบคุมการทำงานพร้อมกันแบบอื่นมักทำได้ไม่สมบูรณ์หรือมีต้นทุนด้านประสิทธิภาพสูง
โครงสร้างสำหรับจัดเก็บระเบียน ( แถว ) ในฐานข้อมูลโดยใช้ MVCC ใน ภาษา Rustอาจมีลักษณะดังนี้
struct Record { /// แทรกรหัสระบุธุรกรรมลงใน stamp. insert_transaction_id : u32 ,/// ลบรหัสระบุธุรกรรมdelete_transaction_id : u32 ,/// ความยาวของข้อมูลdata_length : u16 ,/// เนื้อหาของเรคอร์ดข้อมูล: Vec < u8 > , }| ออฟเซ็ต | อ็อกเท็ต | 0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| อ็อกเท็ต | นิดหน่อย | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
| 0 | 0 | ใส่รหัสธุรกรรม | |||||||||||||||||||||||||||||||
| 4 | 32 | ลบตัวระบุธุรกรรม | |||||||||||||||||||||||||||||||
| 8 | 64 | ความยาวของข้อมูล | |||||||||||||||||||||||||||||||
| 10 | 80 | ข้อมูล… | |||||||||||||||||||||||||||||||
| 14 | 112 | ||||||||||||||||||||||||||||||||
| ⋮ | ⋮ | ||||||||||||||||||||||||||||||||
- ใส่รหัสระบุธุรกรรม: 32 บิต
- ตัวระบุธุรกรรม MVCC สำหรับการแทรกข้อมูล
- ลบตัวระบุธุรกรรม: 32 บิต
- ตัวระบุธุรกรรม MVCC สำหรับการลบ
- ความยาวข้อมูล: 16 บิต
- ความยาวของข้อมูล
- ข้อมูล : ตัวแปร
- เนื้อหาที่จัดเก็บไว้ในบันทึก
ตัวอย่าง
การอ่านและเขียนพร้อมกัน
ณ เวลา = 1 สถานะของฐานข้อมูลอาจเป็นดังนี้:
| เวลา | วัตถุที่ 1 | วัตถุ 2 |
|---|---|---|
| 0 | "ฟู" โดย T0 | "บาร์" โดย T0 |
| 1 | "สวัสดี" โดย T1 |
T0 เขียนค่า Object 1="Foo" และ Object 2="Bar" ลงไป หลังจากนั้น T1 เขียนค่า Object 1="Hello" ลงไป ทำให้ Object 2 ยังคงมีค่าเดิม ค่าใหม่ของ Object 1 จะแทนที่ค่า 0 สำหรับธุรกรรมทั้งหมดที่เริ่มต้นหลังจาก T1 ยืนยันการเปลี่ยนแปลง ซึ่งในขณะนั้น Object 1 เวอร์ชัน 0 จะถูกเก็บกวาดโดยระบบจัดการหน่วยความจำ (garbage collection)
หากธุรกรรมที่ใช้เวลานาน T2 เริ่มดำเนินการอ่านข้อมูลของ Object 2 และ Object 1 หลังจากที่ T1 เสร็จสิ้นแล้ว และมีธุรกรรมอัปเดตพร้อมกัน T3 ซึ่งลบ Object 2 และเพิ่ม Object 3 "Foo-Bar" สถานะของฐานข้อมูล ณ เวลา 2 จะเป็นดังนี้:
| เวลา | วัตถุที่ 1 | วัตถุ 2 | วัตถุที่ 3 |
|---|---|---|---|
| 0 | "ฟู" โดย T0 | "บาร์" โดย T0 | |
| 1 | "สวัสดี" โดย T1 | ||
| 2 | (ลบแล้ว) โดย T3 | "ฟู-บาร์" โดย T3 |
มีการสร้างเวอร์ชันใหม่ของ Object 2 ณ เวลา 2 ซึ่งถูกทำเครื่องหมายว่าถูกลบไปแล้ว และมี Object 3 ใหม่ เนื่องจาก T2 และ T3 ทำงานพร้อมกัน T2 จึงเห็นเวอร์ชันของฐานข้อมูลก่อนเวลา 2 กล่าวคือ ก่อนที่ T3 จะทำการเขียนข้อมูลลงไป ดังนั้น T2 จึงอ่าน Object 2 "Bar" และ Object 1 "Hello" นี่คือวิธีการที่การควบคุมการทำงานพร้อมกันแบบหลายเวอร์ชันช่วยให้สามารถอ่านข้อมูลแบบแยกส่วน (snapshot isolation) ได้โดยไม่ต้องล็อกใดๆ
ประวัติศาสตร์
การควบคุมการทำงานพร้อมกันแบบหลายเวอร์ชันได้รับการอธิบายโดยละเอียดในบทความปี 1981 เรื่อง "การควบคุมการทำงานพร้อมกันใน ระบบ ฐานข้อมูลแบบกระจาย " [ 3 ]โดยPhil Bernsteinและ Nathan Goodman ซึ่งในขณะนั้นทำงานอยู่ที่Computer Corporation of Americaบทความของ Bernstein และ Goodman อ้างอิงวิทยานิพนธ์ปี 1978 [ 4 ]โดยDavid P. Reedซึ่งอธิบาย MVCC ไว้อย่างชัดเจนและอ้างว่าเป็นผลงานต้นฉบับ
ผลิตภัณฑ์ซอฟต์แวร์ฐานข้อมูลเชิงพาณิชย์สำหรับการขนส่งตัวแรกที่มี MVCC คือVAX Rdb/ELNซึ่งวางจำหน่ายในปี 1984 [ 5 ]และสร้างขึ้นที่Digital Equipment CorporationโดยJim Starkey Starkey ได้สร้างฐานข้อมูล MVCC ที่ประสบความสำเร็จในเชิงพาณิชย์ตัวที่สอง[ 6 ]คือInterBase [ 7 ]
ดูเพิ่มเติม
- รายชื่อฐานข้อมูลที่ใช้ MVCC
- อ่าน-คัดลอก-อัปเดต
- การควบคุมการทำงานพร้อมกันโดยอิงตามเวลาประทับ
- นาฬิกาเวกเตอร์
- การควบคุมเวอร์ชัน
อ่านเพิ่มเติม
- Gerhard Weikum และ Gottfried Vossen, ระบบสารสนเทศเชิงธุรกรรม: ทฤษฎี อัลกอริทึม และการปฏิบัติในการควบคุมและการกู้คืนการทำงานพร้อมกัน , Morgan Kaufmann, 2002, ISBN 1-55860-508-8
สรุปเนื้อหา
ข้อมูลสำคัญจากบทความ
ข้อมูลสำคัญเกี่ยวกับ การควบคุมการทำงานพร้อมกันแบบหลายเวอร์ชัน
การควบคุมการทำงานพร้อมกันแบบหลายเวอร์ชัน ( MCC หรือ MVCC ) เป็น วิธี การควบคุมการทำงานพร้อมกันแบบไม่ใช้การล็อก ซึ่งมักใช้ใน ระบบจัดการฐานข้อมูล...
คำอธิบาย
หากไม่มีการควบคุมการทำงานพร้อมกัน หากมีคนกำลังอ่านข้อมูลจากฐานข้อมูลในขณะที่อีกคนหนึ่งกำลังเขียนข้อมูลลงไป ผู้อ่านอาจเห็นข้อมูลที่เขียนไม่เสร็จหรือข้อมูล ที่ไม่สอดคล้องกัน ตัวอย่างเช่น เมื่อทำการ โอนเงิน ระหว่างสองบัญชีธนาคาร...
การดำเนินการ
MVCC ใช้ การประทับเวลา ( TS ) และ รหัสธุรกรรมที่เพิ่มขึ้นเรื่อยๆ เพื่อให้เกิด ความสอดคล้องของธุรกรรม MVCC รับประกันว่าธุรกรรม ( T ) จะไม่ต้องรอเพื่อ อ่าน วัตถุ ในฐานข้อมูล ( P ) โดยการเก็บรักษาวัตถุไว้หลายเวอร์ชัน แต่ละเวอร์ชันของวัตถุ P มีทั้ง...
การอ่านและเขียนพร้อมกัน
ณ เวลา = 1 สถานะของฐานข้อมูลอาจเป็นดังนี้: