--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ปัญหาเนื่องจากธุรกรรมนี้ไม่มีการล็อค