--single-transaction
ตัวเลือกของการmysqldump
ไม่ทำFLUSH TABLES WITH READ LOCK
ก่อนที่จะเริ่มงานสำรองแต่ภายใต้เงื่อนไขบาง หนึ่งในเงื่อนไขเหล่านั้นคือเมื่อคุณระบุ--master-data
ตัวเลือกด้วย
ในซอร์สโค้ดจากmysql-5.6.19/client/mysqldump.c
ที่บรรทัด 5797:
if ((opt_lock_all_tables || opt_master_data ||
(opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
เพื่อให้ได้การล็อคที่มั่นคงในพิกัด binlog ที่แม่นยำก่อนที่จะเริ่มการทำธุรกรรมอ่านซ้ำ--master-data
ตัวเลือกทริกเกอร์ล็อคนี้จะได้รับแล้วปล่อยเมื่อได้รับพิกัด Binlog
ในความเป็นจริงmysqldump
ที่ไม่FLUSH TABLES
ตามมาด้วยFLUSH TABLES WITH READ LOCK
เพราะทำสิ่งที่ทั้งสองช่วยให้ล็อคอ่านจะได้รับเร็วขึ้นในกรณีที่ล้างครั้งแรกใช้เวลาบางส่วน
... แต่ ...
ทันทีที่ได้รับพิกัด binlog mysqldump
ออกUNLOCK TABLES
คำสั่งดังนั้นจึงไม่ควรมีสิ่งใดที่ปิดกั้นเนื่องจากการฟลัชที่คุณเริ่มต้น ไม่ควรมีเธรดใด ๆWaiting for table flush
เป็นผลมาจากธุรกรรมที่mysqldump
กำลังถือครองอยู่
เมื่อคุณเห็นเธรดอยู่ในWaiting for table flush
สถานะนั่นควรหมายความว่าFLUSH TABLES [WITH READ LOCK]
คำสั่งนั้นถูกใช้และยังคงทำงานอยู่เมื่อคิวรีเริ่มต้น - ดังนั้นคิวรีจึงต้องรอให้ฟลัชตารางหยุดทำงานก่อนที่จะสามารถดำเนินการได้ ในกรณีของรายการกระบวนการที่คุณโพสต์mysqldump
กำลังอ่านจากตารางเดียวกันนี้และมีการเรียกใช้คิวรีมาระยะหนึ่งแล้ว แต่คิวรีการบล็อกไม่ได้ถูกบล็อกตลอดระยะเวลาที่ผ่านมา
ทั้งหมดนี้แสดงให้เห็นว่ามีสิ่งอื่นเกิดขึ้น
มีปัญหาอันยาวนานอธิบายไว้ใน Bug # 44884ด้วยวิธีการFLUSH TABLES
ทำงานภายใน ฉันจะไม่แปลกใจถ้าปัญหายังคงมีอยู่ฉันจะประหลาดใจถ้าปัญหานี้ "คงที่" เพราะเป็นปัญหาที่ซับซ้อนมากในการแก้ไข - แทบเป็นไปไม่ได้ที่จะแก้ไขอย่างแท้จริงในสภาพแวดล้อมที่เกิดขึ้นพร้อมกันสูง - และความพยายามใด ๆ การแก้ไขมันมีความเสี่ยงที่สำคัญในการทำลายสิ่งอื่นหรือสร้างพฤติกรรมที่แตกต่างและไม่พึงประสงค์
ดูเหมือนว่านี่จะเป็นคำอธิบายสำหรับสิ่งที่คุณเห็น
โดยเฉพาะ:
หากคุณมีคิวรีที่ใช้เวลานานรันกับตารางและปัญหาFLUSH TABLES
ดังนั้นFLUSH TABLES
จะปิดกั้นจนกว่าคิวรีที่รันเป็นเวลานานจะเสร็จสมบูรณ์
นอกจากนี้แบบสอบถามใด ๆ ที่เริ่มต้นหลังจากที่FLUSH TABLES
มีการออกจะปิดกั้นจนกว่าFLUSH TABLES
จะเสร็จสมบูรณ์
นอกจากนี้หากคุณฆ่าFLUSH TABLES
คิวรีแบบสอบถามที่กำลังบล็อกจะยังคงบล็อกในคิวรีเดิมที่รันมานานคิวรีที่กำลังบล็อกFLUSH TABLES
คิวรีนั้นแม้ว่าคิวรีที่ถูกฆ่าFLUSH TABLES
จะไม่เสร็จสิ้นตารางนั้น (อันนั้นหรือ ยิ่งเกี่ยวข้องกับคิวรีที่ใช้เวลานาน) ยังอยู่ในขั้นตอนของการฟลัชและฟลัชที่ค้างอยู่จะเกิดขึ้นทันทีที่เคียวรีที่รันนานจะเสร็จสิ้น แต่ไม่ใช่ก่อนหน้านี้
ข้อสรุปที่น่าจะเป็นที่นี่คือกระบวนการอื่น - อาจเป็นอีก mysqldump หรือแบบสอบถามที่ไม่เหมาะสมหรือกระบวนการตรวจสอบที่เขียนไม่ดีพยายามล้างตาราง
แบบสอบถามนั้นถูกฆ่าหรือหมดเวลาโดยกลไกที่ไม่รู้จัก แต่ภายหลังผลกระทบของมันยังคงอยู่จนกระทั่งmysqldump
อ่านจากตารางที่มีปัญหา
คุณสามารถทำซ้ำเงื่อนไขนี้ได้โดยพยายามFLUSH TABLES
ในขณะที่แบบสอบถามที่ใช้เวลานานกำลังดำเนินการอยู่ จากนั้นเริ่มแบบสอบถามอื่นซึ่งจะปิดกั้น จากนั้นจึงฆ่าFLUSH TABLES
แบบสอบถามซึ่งจะไม่เลิกบล็อกแบบสอบถามล่าสุด จากนั้นฆ่าแบบสอบถามแรกหรือปล่อยให้เสร็จและแบบสอบถามสุดท้ายจะทำงานได้สำเร็จ
ตามมาภายหลังสิ่งนี้ไม่เกี่ยวข้อง:
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
นั่นเป็นเรื่องปกติเนื่องจากmysqldump --single-transaction
ปัญหา a START TRANSACTION WITH CONSISTENT SNAPSHOT
ซึ่งป้องกันไม่ให้ข้อมูลดัมพ์ที่ถูกเปลี่ยนแปลงในขณะที่ดัมพ์กำลังดำเนินการอยู่ หากไม่มีสิ่งนั้นพิกัด binlog ที่ได้รับเมื่อเริ่มต้นจะไม่มีความหมายเนื่องจาก--single-transaction
จะไม่ใช่สิ่งที่มันอ้างว่าเป็น สิ่งนี้ไม่ควรเกี่ยวข้องกับWaiting for table flush
ปัญหาเนื่องจากธุรกรรมนี้ไม่มีการล็อค