Masalahnya adalah khas dari contoh MySQL di mana Anda memiliki tingkat perubahan yang tinggi ke database. Dengan menjalankan impor 5GB, Anda membuat halaman kotor dengan cepat. Saat halaman kotor dibuat, utas pembersih halaman bertanggung jawab untuk menyalin halaman kotor dari memori ke disk.
Dalam kasus Anda, saya berasumsi Anda tidak melakukan impor 5GB setiap saat. Jadi ini adalah kecepatan pemuatan data yang sangat tinggi, dan bersifat sementara. Anda mungkin dapat mengabaikan peringatan tersebut, karena InnoDB akan menyusul secara bertahap.
Berikut penjelasan rinci tentang internal yang mengarah ke peringatan ini.
Sekali per detik, pembersih halaman memindai kumpulan buffer untuk mencari halaman yang kotor untuk dibersihkan dari kumpulan buffer ke disk. Peringatan yang Anda lihat menunjukkan bahwa ia memiliki banyak halaman kotor untuk dibersihkan, dan dibutuhkan lebih dari 4 detik untuk mem-flush satu batch ke disk, ketika itu harus menyelesaikan pekerjaan itu dalam waktu kurang dari 1 detik. Dengan kata lain, ia menggigit lebih banyak daripada yang bisa ia kunyah.
Anda menyesuaikan ini dengan mengurangi innodb_lru_scan_depth
dari 1024 menjadi 256. Ini mengurangi seberapa jauh ke dalam buffer pool, utas pembersih halaman mencari halaman kotor selama siklus sekali per detiknya. Anda memintanya untuk menggigit lebih kecil.
Perhatikan bahwa jika Anda memiliki banyak instance buffer pool, itu akan menyebabkan flushing bekerja lebih banyak. Itu menggigit innodb_lru_scan_depth
jumlah pekerjaan untuk setiap instance buffer pool. Jadi, Anda mungkin secara tidak sengaja menyebabkan kemacetan ini dengan menambah jumlah kumpulan buffer tanpa mengurangi kedalaman pemindaian.
Dokumentasi untuk innodb_lru_scan_depth
mengatakan "Pengaturan yang lebih kecil dari default umumnya cocok untuk sebagian besar beban kerja." Sepertinya mereka memberi opsi ini nilai yang terlalu tinggi secara default.
Anda dapat membatasi IOPS yang digunakan oleh pembilasan latar belakang, dengan innodb_io_capacity
dan innodb_io_capacity_max
pilihan. Opsi pertama adalah batas lunak pada throughput I/O yang akan diminta InnoDB. Tapi batas ini fleksibel; jika pembilasan berada di belakang laju pembuatan halaman kotor baru, InnoDB akan secara dinamis meningkatkan laju pembilasan di luar batas ini. Opsi kedua menentukan batas yang lebih ketat tentang seberapa jauh InnoDB dapat meningkatkan laju pembilasan.
Jika tingkat pembilasan dapat mengikuti tingkat rata-rata pembuatan halaman kotor baru, maka Anda akan baik-baik saja. Tetapi jika Anda secara konsisten membuat halaman kotor lebih cepat daripada yang dapat dihapus, akhirnya kumpulan buffer Anda akan terisi dengan halaman kotor, hingga halaman kotor melebihi innodb_max_dirty_page_pct
dari kolam penyangga. Pada titik ini, tingkat pembilasan akan meningkat secara otomatis, dan mungkin kembali menyebabkan page_cleaner mengirimkan peringatan.
Solusi lain adalah menempatkan MySQL di server dengan disk yang lebih cepat. Anda memerlukan sistem I/O yang dapat menangani throughput yang diminta oleh pembilasan halaman Anda.
Jika Anda melihat peringatan ini sepanjang waktu di bawah lalu lintas rata-rata, Anda mungkin mencoba melakukan terlalu banyak kueri penulisan di server MySQL ini. Mungkin sudah waktunya untuk menskalakan, dan membagi penulisan ke beberapa instance MySQL, masing-masing dengan sistem disknya sendiri.
Baca lebih lanjut tentang pembersih halaman:
- Memperkenalkan utas page_cleaner di InnoDB (salinan yang diarsipkan)
- MySQL-5.7 meningkatkan beban kerja berorientasi DML