อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

สวัสดีทุกคน. วลาดิสลาฟ โรดิน ติดต่อมา ปัจจุบันฉันเป็นผู้นำหลักสูตรสำหรับหลักสูตร High Workload Architect ที่ OTUS และยังสอนหลักสูตรสถาปัตยกรรมซอฟต์แวร์อีกด้วย

นอกเหนือจากการสอน ดังที่คุณอาจสังเกตเห็นแล้ว ฉันกำลังเขียนเนื้อหาต้นฉบับสำหรับบล็อก OTUS บนHabré และฉันต้องการให้ตรงกับบทความของวันนี้เพื่อให้ตรงกับการเปิดตัวหลักสูตร "PostgreSQL"ซึ่งกำลังเปิดรับสมัครอยู่ในขณะนี้

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

การแนะนำ

В ครั้งสุดท้าย เราได้พูดคุยเกี่ยวกับความจริงที่ว่าธุรกรรมในฐานข้อมูลทำหน้าที่แก้ปัญหาสองประการ: การรับประกันความทนทานต่อข้อผิดพลาดและการเข้าถึงข้อมูลในสภาพแวดล้อมที่มีการแข่งขัน เพื่อดำเนินงานเหล่านี้อย่างสมบูรณ์ ธุรกรรมต้องมีคุณสมบัติ ACID วันนี้เราจะพูดถึงรายละเอียดเกี่ยวกับจดหมายนี้ ฉัน (แยก) ในตัวย่อนี้

ฉนวนกันความร้อน

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

ความผิดปกติที่รู้จักกันดีที่สุดคือ: การอ่านสกปรก, การอ่านที่ไม่สามารถทำซ้ำได้, การอ่าน Phantom แต่ในความเป็นจริงยังมีอีก 5 รายการ: การเขียนสกปรก, การอัปเดตเคอร์เซอร์หายไป, การอัปเดตที่หายไป, การอ่านเอียง, การเขียนเอียง

เขียนสกปรก

สาระสำคัญของความผิดปกตินี้คือธุรกรรมสามารถเขียนทับข้อมูลที่ไม่มีข้อผูกมัดได้

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

ความผิดปกตินี้เป็นอันตรายไม่เพียงเพราะข้อมูลอาจขัดแย้งกันหลังจากทำธุรกรรมทั้งสอง (ดังในภาพ) แต่ยังเป็นเพราะอะตอมมิกซิตีถูกละเมิด: เนื่องจากเราอนุญาตให้เขียนทับข้อมูลที่ไม่มีข้อผูกมัด จึงไม่ชัดเจนว่าจะย้อนกลับธุรกรรมหนึ่งได้อย่างไรโดยไม่ส่งผลกระทบต่ออีกธุรกรรมหนึ่ง .

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

อ่านสกปรก

Dirty Read หมายถึงการอ่านข้อมูลที่ไม่มีข้อผูกมัด

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

ปัญหาเกิดขึ้นเมื่อจำเป็นต้องดำเนินการหรือตัดสินใจตามตัวอย่าง

เพื่อแก้ไขความผิดปกติ คุณสามารถแนบการล็อกการอ่านได้ แต่จะส่งผลต่อประสิทธิภาพอย่างมาก มันง่ายกว่ามากที่จะบอกว่าสำหรับธุรกรรมการย้อนกลับ สถานะเริ่มต้นของข้อมูล (ก่อนเริ่มการบันทึก) จะต้องถูกบันทึกไว้ในระบบ ทำไมไม่อ่านจากตรงนั้นล่ะ? มีราคาไม่แพงพอที่จะทำให้ฐานข้อมูลส่วนใหญ่ลบการอ่านสกปรกออกตามค่าเริ่มต้น

การอัปเดตที่หายไป

การอัปเดตที่หายไปหมายถึงการอัปเดตที่สูญหาย และการแปลสะท้อนถึงสาระสำคัญของปัญหาได้ค่อนข้างแม่นยำ:

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

ในความเป็นจริง ผลลัพธ์ของธุรกรรม T2 ถูกกลับรายการ สถานการณ์นี้สามารถแก้ไขได้โดยการล็อกการเขียนโดยตรงหรือโดยนัย นั่นคือเราเพียงอัปเดตบันทึกแล้วเกิดการล็อคโดยนัยหรือดำเนินการ เลือกเพื่ออัพเดตทำให้เกิดการล็อกการอ่านและการเขียนเกิดขึ้น โปรดทราบว่าการดำเนินการดังกล่าวค่อนข้างอันตราย: ด้วยการอ่านที่ "บริสุทธิ์" ของเรา เราจะบล็อกการอ่านอื่นๆ ฐานข้อมูลบางแห่งมีความปลอดภัยมากกว่า เลือกเพื่อแชร์อนุญาตให้อ่านข้อมูลได้แต่ไม่แก้ไข

เคอร์เซอร์สูญเสียการอัปเดต

เพื่อการควบคุมที่ละเอียดยิ่งขึ้น ฐานอาจมีเครื่องมืออื่นๆ เช่น เคอร์เซอร์ เคอร์เซอร์คือโครงสร้างที่ประกอบด้วยชุดของแถวและช่วยให้คุณสามารถวนซ้ำได้ ประกาศ cursor_name สำหรับ select_statement. เนื้อหาของเคอร์เซอร์อธิบายโดยการเลือก

ทำไมคุณถึงต้องการเคอร์เซอร์? ความจริงก็คือฐานข้อมูลบางแห่งมีการล็อคบันทึกทั้งหมดที่เลือกโดยการเลือก (ความเสถียรในการอ่าน) หรือเฉพาะในบันทึกที่มีเคอร์เซอร์อยู่ในปัจจุบันเท่านั้น (ความเสถียรของเคอร์เซอร์) ด้วยความเสถียรของเคอร์เซอร์ จึงมีการนำการล็อกแบบสั้นมาใช้ ซึ่งช่วยให้เราสามารถลดจำนวนการล็อกได้หากเราวนซ้ำตัวอย่างข้อมูลจำนวนมาก ดังนั้น ความผิดปกติของการอัปเดตที่สูญหายจะถูกแยกออกจากกันสำหรับเคอร์เซอร์

อ่านซ้ำไม่ได้

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

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

ทำไมเรื่องนี้ถึงเป็นปัญหา? ลองจินตนาการว่าเป้าหมายของธุรกรรม T2 ในภาพคือการเลือกสินค้าทั้งหมดที่มีราคาต่ำกว่า 150 USD คนอื่นอัพเดทราคาเป็น $200 ดังนั้นตัวกรองที่ติดตั้งจึงไม่ทำงาน

ความผิดปกติเหล่านี้จะไม่เกิดขึ้นเมื่อเพิ่มอินเทอร์ล็อคสองเฟสหรือเมื่อใช้กลไก MVCC ซึ่งฉันต้องการจะหารือแยกกัน

ผีอ่าน

Phantom คือการอ่านข้อมูลที่เพิ่มโดยธุรกรรมอื่น

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

ตัวอย่างเช่น เราสามารถสังเกตการเลือกผลิตภัณฑ์ที่ถูกที่สุดไม่ถูกต้องเมื่อเกิดความผิดปกตินี้

การกำจัดการอ่าน Phantom นั้นค่อนข้างยากอยู่แล้ว การบล็อกแบบปกตินั้นไม่เพียงพอ เนื่องจากเราไม่สามารถบล็อกสิ่งที่ยังไม่มีได้ ระบบ 2PL ใช้การล็อคแบบคาดการณ์ ในขณะที่ระบบ MVCC มีตัวกำหนดเวลาธุรกรรมที่จะย้อนกลับธุรกรรมที่อาจหยุดชะงักเนื่องจากการแทรก ทั้งกลไกที่หนึ่งและที่สองนั้นค่อนข้างหนัก

อ่านเบี้ยว

การอ่านที่เอียงเกิดขึ้นเมื่อเราทำงานกับหลายตาราง ซึ่งเนื้อหาจะต้องเปลี่ยนแปลงอย่างสม่ำเสมอ

สมมติว่าเรามีตารางที่แสดงถึงโพสต์และข้อมูลเมตาของโพสต์:

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

ธุรกรรมหนึ่งอ่านจากตาราง ส่วนอีกธุรกรรมหนึ่งแก้ไข:

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

จากผลของธุรกรรม T1 โพสต์จึงมีชื่อ = Good และ updated_by = T2 ซึ่งเป็นความไม่สอดคล้องกันบางประการ

อันที่จริง นี่เป็นการอ่านซ้ำไม่ได้ แต่เป็นส่วนหนึ่งของหลายตาราง

เพื่อแก้ไขปัญหานี้ T1 สามารถล็อกแถวทั้งหมดที่จะอ่านได้ ซึ่งจะป้องกันไม่ให้ธุรกรรม T2 เปลี่ยนแปลงข้อมูล ในกรณีของ MVCC ธุรกรรม T2 จะถูกยกเลิก การป้องกันความผิดปกตินี้อาจมีความสำคัญหากเราใช้เคอร์เซอร์

เขียนเอียง

ความผิดปกตินี้อธิบายได้ง่ายกว่าด้วยตัวอย่าง: สมมติว่าในระบบของเรา แพทย์อย่างน้อยหนึ่งคนควรเข้าปฏิบัติหน้าที่ แต่แพทย์ทั้งสองคนตัดสินใจยกเลิกการปฏิบัติหน้าที่:

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

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

นี่เป็นการอ่านซ้ำที่ไม่สามารถอ่านซ้ำได้ หรืออีกทางหนึ่ง ผู้เลือกสามารถล็อกเรกคอร์ดเหล่านี้ได้

การเอียงการเขียนและการเอียงการอ่านเป็นการผสมผสานระหว่างความผิดปกติก่อนหน้านี้ คุณสามารถพิจารณาเขียนแบบเอียง ซึ่งโดยพื้นฐานแล้วคือการอ่านแบบ Phantom พิจารณาตารางที่ประกอบด้วยชื่อของพนักงาน เงินเดือน และโครงการที่พวกเขาทำงานอยู่:

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

อะไรอาจเป็นผลมาจากการลดระดับการแยกธุรกรรมในฐานข้อมูล?

ผลลัพธ์ที่ได้คือภาพต่อไปนี้: ผู้จัดการแต่ละคนคิดว่าการเปลี่ยนแปลงของตนจะไม่ทำให้ต้องใช้งบประมาณเกิน ดังนั้นพวกเขาจึงทำการเปลี่ยนแปลงบุคลากรซึ่งร่วมกันทำให้ต้นทุนเกิน

สาเหตุของปัญหาเหมือนกับในการอ่าน Phantom ทุกประการ

ผลการวิจัย

การผ่อนคลายระดับการแยกธุรกรรมในฐานข้อมูลเป็นการแลกเปลี่ยนระหว่างความปลอดภัยและประสิทธิภาพ การเลือกระดับนี้ควรพิจารณาจากความเสี่ยงที่อาจเกิดขึ้นกับธุรกิจหากมีความผิดปกติบางอย่างเกิดขึ้น

เรียนรู้เพิ่มเติมเกี่ยวกับหลักสูตร

ที่มา: will.com

เพิ่มความคิดเห็น