เกี่ยวกับ“ การประมวลผลรหัสธุรกรรม”


10

ตอนนี้ฉันอ่านเอกสารเกี่ยวกับ "Transaction ID Wraparound" แต่มีบางอย่างที่ฉันไม่เข้าใจจริงๆเอกสารเป็น url ต่อไปนี้ http://www.postgresql.org/docs/9.0/static/routine-vacuuming .html # สูญญากาศ-FOR-วิจิตร

23.1.4 การป้องกันการล้มเหลวของการห่อธุรกรรม ID

ความหมายของธุรกรรม MVCC ของ PostgreSQL นั้นขึ้นอยู่กับความสามารถในการเปรียบเทียบหมายเลขรหัสธุรกรรม (XID): เวอร์ชันแถวที่มีการแทรก XID มากกว่า XID ของธุรกรรมปัจจุบันคือ "ในอนาคต" และไม่ควรมองเห็นธุรกรรมปัจจุบัน แต่เนื่องจาก ID ธุรกรรมมีขนาดที่ จำกัด (32 บิต) คลัสเตอร์ที่รันเป็นเวลานาน (มากกว่า 4 พันล้านธุรกรรม) จะได้รับการใช้งาน ID ของรายการ: ตัวนับ XID ล้อมรอบเป็นศูนย์และธุรกรรมทั้งหมดที่อยู่ใน อดีตดูเหมือนจะเป็นในอนาคต - ซึ่งหมายความว่าผลผลิตของพวกเขาจะมองไม่เห็น ในระยะสั้นการสูญเสียข้อมูลหายนะ (ที่จริงแล้วข้อมูลยังคงอยู่ที่นั่น แต่มันก็สบายดีถ้าคุณไม่สามารถทำได้) เพื่อหลีกเลี่ยงสิ่งนี้จำเป็นต้องดูดทุกตารางในฐานข้อมูลทุก ๆ อย่างน้อยหนึ่งครั้งทุกๆสองพันล้านธุรกรรม

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

มีคนอธิบายเรื่องนี้ได้ไหม เหตุใดหลังจากที่ฐานข้อมูลมีปัญหา ID การพันธุรกรรมที่เกิดขึ้นในอดีตจะปรากฏเป็นอนาคต ในระยะสั้นฉันต้องการที่จะรู้ว่า PostgreSQL จะอยู่ในสถานการณ์ "การสูญเสียข้อมูล" หลังจากการทำรายการ ID โดยการ autovacuum โดยอัตโนมัติหรือไม่?

สำหรับมุมมองส่วนตัวของฉันเราสามารถรับ ID ธุรกรรมปัจจุบันโดยใช้ฟังก์ชัน txid_current () whoes output เป็น 64 บิตและจะไม่ถูกกรณืดังนั้นฉันคิดว่า ID ธุรกรรมการแทรกของ tuples ซึ่งรู้ว่า xmin จะเป็นผู้ดูแลมากกว่า xid ที่ได้รับ โดย txid_current () ฟังก์ชั่น ยกเว้นว่าคุณจะใช้ pg_resetxlog รีเซ็ต ID ธุรกรรมการรีเซ็ตหลังจากปิดเซิร์ฟเวอร์ PostgreSQL ฉันถูกไหม ? ขอบคุณ


ฉันคิดว่าการแก้ไขล่าสุดของคุณน่าจะเป็นคำถามใหม่ถ้าเป็นไปได้
แจ็คบอกว่าลอง topanswers.xyz

คำตอบ:


10

เหตุใดหลังจากที่ฐานข้อมูลมีปัญหา ID การพันธุรกรรมที่เกิดขึ้นในอดีตจะปรากฏเป็นอนาคต

พวกเขาทำไม่ได้ ข้อความที่ยกมาเพียงอธิบายว่าทำไม postgres จำเป็นต้องใช้ modulo 2 31 arithmatic (ซึ่งหมายถึงการทำธุรกรรมที่สามารถสรุปได้ตราบใดที่การทำธุรกรรมเก่านั้น 'แช่แข็ง' เร็วพอ):

XID ปกติจะถูกเปรียบเทียบโดยใช้ modulo-2 ^ 31 arithmetic ซึ่งหมายความว่าสำหรับทุก XID ปกติมี XID สองพันล้านที่เป็น "เก่า" และสองพันล้านที่เป็น "ใหม่"

จะเฉพาะเจาะจง:

แถวเก่าจะต้องได้รับการมอบหมาย XID FrozenXID ใหม่บางครั้งก่อนที่พวกเขาจะไปถึงเครื่องหมายสองพันล้านธุรกรรม

หรือล้อมรอบ XID จะทำให้สิ่งต่าง ๆ พัง เพื่อป้องกันการติดตั้ง postgres จะเริ่มส่งคำเตือนและในที่สุดก็ปิดตัวลงและปฏิเสธที่จะเริ่ม transactons ใหม่หากจำเป็น:

หากด้วยเหตุผลบางอย่าง autovacuum ล้มเหลวในการล้าง XID เก่าจากตารางระบบจะเริ่มเปล่งข้อความเตือนเช่นนี้เมื่อ XID ที่เก่าที่สุดของฐานข้อมูลมาถึงธุรกรรมสิบล้านรายการจากจุดโดยรอบ:

WARNING:  database "mydb" must be vacuumed within 177009986 transactions 
HINT:  To avoid a database shutdown, execute a database-wide VACUUM in "mydb". 

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

กล่าวอีกนัยหนึ่ง "ธุรกรรมที่เกิดขึ้นในอดีตดูเหมือนจะเป็นในอนาคต" และ "การสูญเสียข้อมูล" เป็นทั้งทฤษฏีและจะไม่เกิดจากการใช้รหัสธุรกรรมในทางปฏิบัติ



5

บล็อกที่คุณวางดูเหมือนจะตอบคำถาม ทุกอย่างขึ้นอยู่กับตรรกะที่ใช้ในการซ่อนธุรกรรมในอนาคต

ตัวนับ ID ธุรกรรม (XID) ถูก จำกัด ไว้ที่32 บิตและหากถึงจำนวนถัดไปนั้นแทนที่จะแทนที่ธุรกรรมสูงสุดเก่ามันเริ่มต้นใหม่ที่ศูนย์

ตอนนี้มันเป็นศูนย์ดังนั้น PostgreSQL จึงซ่อนธุรกรรมทั้งหมด> 0 จากรายการ ดังนั้นแม้ว่าธุรกรรม # 2,147,483,633 เกิดขึ้น 20 วินาทีที่ผ่านมา PostgreSQL คิดว่าจะไม่เกิดขึ้นอีก 2,147,483,633 ธุรกรรม


1
เอกสารได้รับการแก้ไขในเดือนธันวาคมปี 2013 XID ถูกคำนวณโดยใช้ modulo-2 ^ 31
eradman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.