Apakah Anda mengalami waktu startup MySQL yang lambat dalam mode GTID? Kami baru-baru ini mengalami masalah ini di salah satu penerapan hosting MySQL kami dan mulai memecahkan masalah tersebut. Di blog ini, kami menguraikan masalah yang dapat memperlambat waktu mulai ulang MySQL Anda, cara melakukan debug untuk penerapan Anda, dan apa yang dapat Anda lakukan untuk mengurangi waktu mulai dan meningkatkan pemahaman Anda tentang replikasi berbasis GTID.
Bagaimana Kami Menemukan Masalah
Kami sedang menyelidiki waktu startup MySQL yang lambat pada penerapan MySQL 5.7.21 berbasis disk kelas bawah yang mengaktifkan mode GTID. Sistem adalah bagian dari pasangan master-slave dan berada di bawah beban tulis yang moderat. Saat memulai ulang selama pemeliharaan terjadwal, kami melihat bahwa server database membutuhkan waktu 5-10 menit untuk memulai dan mulai menerima koneksi. Penundaan semacam itu tidak masuk akal, jadi kami mulai menyelidikinya.
Men-debug Waktu Mulai MySQL Anda yang Lambat
Kami menggunakan alat Percona yang populer pt-ioprofile untuk melihat apa yang dilakukan database. pt-ioprofile adalah utilitas yang sangat penting dalam toolkit populer Percona yang digunakan untuk men-debug masalah MySQL, dan Anda dapat melihat daftar fitur lengkap dalam dokumentasinya. pt-ioprofile alat menggunakan strace dan lsof untuk melihat proses I/O dan mencetak tabel file dan aktivitas I/O.
Jadi, kami memulai MySQL, menunggu mysqld proses untuk melahirkan, dan memulai pt-ioprofile untuk melihat apa masalahnya:
# pt-ioprofile --profile-process mysqld --run-time 200 Tue Oct 9 15:42:24 UTC 2018 Tracing process ID 18677 total pread read pwrite write fsync fdatasync open close getdents lseek fcntl filename ... 216.550641 0.000000 216.550565 0.000000 0.000000 0.000000 0.000000 0.000015 0.000040 0.000000 0.000021 0.000000 /mysql_data/binlogs/mysql-bin.000014 ...
Apa yang Memperlambat Restart MySQL Anda?
Saat menjalankan ini beberapa kali, kami mengamati hal berikut:
- mysqld proses menghabiskan sebagian besar waktunya membaca file log biner terbaru. Hal ini terjadi bahkan ketika server telah dihentikan dengan baik dan tidak perlu ada pemulihan error, dll.
- Server juga menghabiskan banyak waktu untuk memuat file data InnoDB, tetapi waktu itu jauh lebih kecil dibandingkan dengan waktu yang dihabiskan untuk membaca file log biner terbaru.
- Jika server segera di-restart lagi, restart berikutnya akan jauh lebih cepat.
- Karena penonaktifan database menghapus log biner dan membuat yang baru saat startup, kami melakukan eksperimen tambahan – sebelum mematikan server, kami menghapus log biner. Server berikutnya mulai kembali dengan cepat.
Pengamatan ini dengan jelas menunjukkan fakta bahwa MySQL menghabiskan banyak waktu membaca file log biner terbaru. Jika file berukuran kecil, seperti saat file log di-flush sebelum dimatikan, startup akan cepat.
Waktu Mulai MySQL Lambat di GTID? Ukuran File Log Biner Anda Mungkin Menjadi MasalahKlik Untuk Tweet
Memahami Pemulihan Binlog GTID
Ternyata, untuk mengisi nilai gtid_executed dan gtid_purged, server MySQL harus mengurai file log biner.
Berikut ringkasan rekomendasi metode dokumentasi MySQL 5.7 berdasarkan pembacaan FALSE atau TRUE:
Saat binlog_gtid_simple_recovery =SALAH:
Untuk menghitung gtid_executed:
- Iterasi file log biner dari yang terbaru, berhenti di file pertama yang memiliki Previous_gtids_log_event masuk.
- Mengonsumsi semua GTID dari Previous_gtids_log_event dan Gtid_log_events dari file log biner ini, dan simpan set GTID ini secara internal. Ini disebut sebagai gtids_in_binlog.
- Nilai gtid_executed dihitung sebagai gabungan dari gtids_in_binlog dan GTID di tabel mysql.gtid_executed .
Proses ini bisa sangat memakan waktu jika ada banyak file log biner tanpa GTID, misalnya, dibuat saat gtid_mode =MATI.
Demikian pula, untuk menghitung gtid_purged:
- Iterasi file log biner dari yang terlama ke yang terbaru, berhenti di log biner pertama yang berisi Previous_gtids_log_event yang tidak kosong (memiliki setidaknya satu GTID), atau yang memiliki setidaknya satu Gtid_log_event .
- Baca Sebelumnya_gtids_log_event dari berkas ini. Hitung variabel internal gtids_in_binlog_not_purged karena kumpulan GTID ini dikurangi dari gtids_in_binlog.
- Nilai gtid_purged disetel ke gtid_executed , dikurangi gtids_in_binlog_not_purged .
Jadi, ini membentuk dasar pemahaman kami tentang cara kerja berbagai hal di versi lama. Namun, pengoptimalan tertentu dapat dilakukan saat binlog_gtid_simple_recovery adalah benar. Inilah kasus yang kami minati:
Kapan binlog_gtid_simple_recovery =BENAR:
(Catatan, ini adalah default di MySQL 5.7.7 dan yang lebih baru)
- Baca saja file log biner terlama dan terbaru.
- Hitung gtid_purged dari Previous_gtids_log_event atau Gtid_log_event ditemukan di file log biner tertua.
- Hitung gtid_executed dari Previous_gtids_log_event atau Gtid_log_event ditemukan di file log biner terbaru.
- Jadi, hanya dua file log biner dibaca saat server dimulai ulang atau saat menghapus log biner.
Jadi, untuk MySQL versi 5.7.7 dan yang lebih baru, file log biner terbaru dan lama selalu dibaca selama startup sistem untuk menginisialisasi variabel sistem GTID dengan benar. Membaca file log biner tertua tidak semahal itu karena peristiwa yang dicari MySQL, Previous_gtids_log_event, selalu menjadi peristiwa pertama dalam file log biner.
Namun, untuk menghitung gtid_executed dengan benar , server harus membaca seluruh file log biner terbaru dan mengumpulkan semua kejadian dalam file itu. Jadi, waktu startup sistem menjadi berbanding lurus dengan ukuran file log biner terbaru .
Perhatikan bahwa situasinya bahkan lebih buruk ketika binlog_gtid_simple_recovery adalah SALAH . Karena ini bukan lagi opsi default dalam rilis terbaru, ini tidak terlalu menjadi perhatian.
Cara Mengatasi Waktu Mulai Lambat Anda
Setelah memahami penyebab masalah yang kami hadapi, solusi yang kami putuskan cukup jelas – kurangi ukuran file log biner. Ukuran default file log biner adalah 1GB. Dibutuhkan waktu untuk menguraikan file dengan ukuran ini selama startup, jadi masuk akal untuk mengurangi nilai max_binlog_size ke nilai yang lebih rendah.
Jika mengurangi ukuran file log biner bukanlah pilihan, maka menghapus file log biner sebelum penghentian pemeliharaan proses mysqld dapat membantu untuk mengurangi waktu pemulihan binlog GTID.