The --single-transaction
pilihan untuk mysqldump
tidak melakukan FLUSH TABLES WITH READ LOCK
sebelum memulai pekerjaan cadangan tetapi hanya dalam kondisi tertentu. Salah satu syarat tersebut adalah ketika Anda juga menentukan --master-data
opsi.
Dalam kode sumber, dari mysql-5.6.19/client/mysqldump.c
pada baris 5797:
if ((opt_lock_all_tables || opt_master_data ||
(opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
Untuk mendapatkan kunci solid pada koordinat binlog yang tepat sebelum memulai transaksi repeatable-read, --master-data
opsi memicu kunci ini untuk diperoleh dan kemudian dirilis setelah koordinat binlog telah diperoleh.
Bahkan, mysqldump
tidak FLUSH TABLES
diikuti oleh FLUSH TABLES WITH READ LOCK
karena melakukan kedua hal itu memungkinkan kunci baca diperoleh lebih cepat dalam kasus di mana flush awal membutuhkan waktu.
...namun...
Segera setelah telah memperoleh koordinat binlog, mysqldump
mengeluarkan UNLOCK TABLES
pernyataan, jadi seharusnya tidak ada apa pun yang memblokir sebagai akibat dari flush yang Anda mulai. Seharusnya tidak ada utas Waiting for table flush
sebagai akibat dari transaksi yang mysqldump
ditahan.
Ketika Anda melihat sebuah thread di Waiting for table flush
negara, yang harus berarti bahwa FLUSH TABLES [WITH READ LOCK]
pernyataan itu dikeluarkan dan masih berjalan ketika query mulai - sehingga query harus menunggu flush meja, sebelum dapat mengeksekusi. Dalam kasus daftar proses yang Anda posting, mysqldump
membaca dari tabel yang sama ini, dan kueri telah berjalan untuk sementara waktu, namun kueri pemblokiran belum memblokir selama itu.
Ini semua menunjukkan bahwa sesuatu yang lain telah terjadi.
Ada masalah lama yang dijelaskan dalam Bug # 44884 dengan cara FLUSH TABLES
kerjanya, secara internal. Saya tidak akan terkejut jika masalah ini masih berlanjut, saya akan terkejut jika masalah ini pernah "diperbaiki" karena ini adalah masalah yang sangat kompleks untuk diselesaikan - hampir tidak mungkin untuk benar-benar diperbaiki dalam lingkungan konkurensi tinggi - dan segala upaya untuk memperbaikinya membawa risiko signifikan melanggar sesuatu, atau menciptakan perilaku baru, berbeda, dan masih tidak diinginkan.
Sepertinya ini akan menjadi penjelasan untuk apa yang Anda lihat.
Secara khusus:
jika Anda memiliki kueri yang berjalan lama berjalan melawan tabel, dan masalah FLUSH TABLES
, maka FLUSH TABLES
akan memblokir sampai kueri yang berjalan lama selesai.
Selain itu, setiap pertanyaan yang dimulai setelah FLUSH TABLES
dikeluarkan akan diblokir sampai FLUSH TABLES
selesai.
selain itu, jika Anda membunuh FLUSH TABLES
kueri, kueri yang memblokir masih akan memblokir kueri yang sudah berjalan lama, kueri yang memblokir FLUSH TABLES
kueri, karena meskipun FLUSH TABLES
kueri yang terbunuh tidak selesai, tabel itu (satu, atau lebih lanjut, terlibat dengan permintaan yang sudah berjalan lama) masih dalam proses disiram, dan bahwa pending flush yang tertunda akan terjadi segera setelah permintaan yang sudah berjalan selesai - tetapi tidak sebelumnya.
Kesimpulan yang mungkin di sini adalah bahwa proses lain - mungkin mysqldump lain, atau permintaan yang keliru, atau proses pemantauan yang ditulis dengan buruk mencoba menyiram sebuah tabel.
Permintaan itu kemudian dibunuh atau habis waktu oleh mekanisme yang tidak diketahui, tetapi efek setelahnya bertahan sampai mysqldump
selesai membaca dari tabel yang bersangkutan.
Anda dapat meniru kondisi ini dengan mencoba FLUSH TABLES
sementara permintaan yang sudah berjalan dalam proses. Kemudian mulai permintaan lain, yang akan diblokir. Kemudian bunuh FLUSH TABLES
kueri, yang tidak akan membuka blokir kueri terbaru. Kemudian bunuh kueri pertama, atau biarkan selesai, dan kueri akhir akan berhasil dijalankan.
Sebagai renungan, ini tidak berhubungan:
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
Itu normal, karena mysqldump --single-transaction
masalah a START TRANSACTION WITH CONSISTENT SNAPSHOT
, yang mencegahnya membuang data yang diubah saat dump sedang berlangsung. Tanpa itu, koordinat binlog yang diperoleh di awal akan menjadi tidak berarti, karena --single-transaction
tidak akan seperti yang diklaimnya. Seharusnya tidak terkait dengan Waiting for table flush
masalah ini, karena transaksi ini jelas tidak memiliki kunci.