cara untuk mencegah permintaan menunggu kunci level tabel

10

Kami mengalami masalah setelah memindahkan basis data pelanggan kami ke server tambahan. Ini seharusnya memiliki efek positif pada kinerja situs, tetapi ada masalah dengan penguncian tabel di MyISAM. (Saya pernah mendengar menggunakan InnoDB bukan MyISAM, tetapi kami tidak dapat mengganti mesin dalam waktu dekat).
Kami dapat menemukannya pada kueri pembaruan yang dilakukan ketika moderator mengaktifkan komentar pada artikel tersebut. Inilah prosesnya:

  • pembaruan-permintaan diproses SET status = 1 WHERE id = 5(indeks diatur)
  • file halaman yang di-cache dihapus

Pada titik ini seluruh halaman menjadi lambat. Basis data sendiri sibuk selama beberapa menit. Saya mengambil daftar proses beberapa kali dan melihat sekitar 60 entri dari kueri pemilihan yang berbeda, yang semuanya dalam keadaan menunggu kunci tingkat tabel .

1. Saya tidak mengerti mengapa pembaruan ini di atas meja article_commentsdapat memengaruhi pernyataan pilih untuk tabel articleuntuk menunggu kunci level tabel. Dalam daftar proses, hampir semua permintaan menunggu berasal dari tabel ini. Saya telah membaca tentang fakta bahwa pembaruan / sisipan lebih disukai untuk dipilih dan bahwa ini dapat menyebabkan masalah seperti itu, tetapi tabel artikel itu sendiri tidak diperbarui ketika komentar menjadi aktif, sehingga pilihan tidak harus menunggu. Apakah saya salah mengerti?
2. Apakah ada sesuatu selain beralih ke InnoDB untuk mencegah perilaku ini atau setidaknya untuk mendapatkan keseimbangan yang lebih baik? Saya sangat jengkel tentang kenyataan bahwa masalah ini tidak muncul sebelum memindahkan database ke server baru. Saya kira ada beberapa kesalahan konfigurasi tetapi saya tidak tahu cara mengidentifikasi.

32 bit mengapung
sumber
1
Aktifkan pencatatan umum dan perhatikan pernyataan GABUNG di antara tabel ini. Ketika Anda PILIH itu menciptakan BACA KUNCI implisit. Karena MYISAM tidak mendukung penguncian ROW LEVEL, MYISAM terkunci pada level tabel. Ini mungkin terjadi bahwa penguncian ini terjadi pada server lama tetapi tidak ada yang menonton? Bandingkan baris my.cnf Anda dengan garis antar host dan terutama pastikan key_buffer Anda disetel dengan benar.
randomx
Kami memiliki beberapa masalah kinerja lainnya di server lama, dan sering menonton daftar proses. Terutama ada banyak proses tidur, tetapi kami tidak pernah memperhatikan yang menunggu (saya melihat info ini umumnya pertama kali di server baru ini). Rekan saya menyalin my.cnf lama dan menyesuaikan nilai ke perangkat keras yang ada, tetapi tidak ada banyak entri. Saya juga membandingkan output dari "SHOW VARIABLES" tetapi tidak benar-benar tahu harus mencari apa. Kami akan memeriksa kembali keybuffer besok, terima kasih atas komentar Anda.
32bit terbang
Baru-baru ini kami memiliki masalah yang sama. Awalnya kami key_buffer_sizediatur untuk 1GB. Meningkatkan itu untuk 10GBmengurangi masalah.
Haluk
@ Rick James, terima kasih. Anda menyelamatkan saya banyak masalah hari ini. Apakah Anda memiliki daftar keinginan di Amazon atau di tempat lain? :) Saya mengatur query_cache_limit ke 1024. Tidak ada masalah kunci sekarang. Saya melakukannya dalam variabel pada awalnya dari klien mysql. set global query_cache_limit = 1024; Sekarang saya akan menulisnya ke my.cnf. Solusi ini memberi saya waktu untuk merencanakan migrasi innodb tanpa tekanan, jadi terima kasih.

Jawaban:

8

MyISAM Storage Engine sangat terkenal karena melakukan kunci tabel penuh untuk setiap DML (INSERT, UPDATE, DELETEs). InnoDB pasti akan mengatasi masalah itu dalam jangka panjang.

Saya menulis tentang pro dan kontra menggunakan MyISAM vs InnoDB

Sehubungan dengan pertanyaan Anda saat ini, berikut adalah skenario yang mungkin:

  • articledan article_commentskeduanya adalah tabel MyISAM
  • article_commentsmemiliki satu atau lebih indeks dengan statussebagai kolom
  • Pembaruan halaman indeks untuk di article_comments-cache dalam Buffer Kunci MyISAM (berukuran oleh key_buffer_size ), menyebabkan halaman indeks lama keluar dari Buffer Kunci MyISAM
  • Anda memiliki kueri SELECT yang melakukan GABUNGAN antara articledanarticle_comments

Dalam skenario yang saya sarankan, SELECT terhadap articletabel dapat ditunda untuk mengizinkan penulisan karena harus menunggu untuk article_commentsbebas dari DML apa pun (dalam hal ini, an UPDATE)

RolandoMySQLDBA
sumber
Terima kasih atas jawaban Anda (dan tautannya), skenario Anda nyata. Saya tidak menyadari bahwa sebagian besar artikel pilih memang bergabung dengan tabel komentar (atau dengan kata lain, melihat pernyataan tidak lengkap dalam daftar proses phpmyadmin). Apakah Anda tahu solusi jangka pendek untuk mencegah beberapa permintaan tunggu? Saya sudah mencobanya dengan "UPDATE LOW_PRIORITY" dalam pernyataan khusus tetapi itu tidak membuat perubahan nyata. Kami benar-benar akan berubah menjadi innodb di masa depan tetapi saya ingin tahu apakah ada cara untuk mendapatkan peningkatan saat ini.
32bit naik
Solusi utama: Konversikan tabel ke InnoDB. Lihat posting saya dba.stackexchange.com/a/9422/877 tentang cara mengubah semua MyISAM menjadi InnoDB
RolandoMySQLDBA
7

Pada titik ini seluruh halaman menjadi lambat. Basis data sendiri sibuk selama beberapa menit.

Baunya seperti kamu punya Query_cache besar?

mysql> SHOW VARIABLES LIKE 'query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 16777216 | -- Not over 50M
| query_cache_type             | DEMAND   | -- Only if using SQL_CACHE
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+

Untuk sistem produksi dengan banyak penulisan, Anda juga dapat mematikan MATI query_cache.

Semua entri dalam query_cache untuk tabel yang diberikan dibersihkan ketika setiap penulisan terjadi pada tabel itu. Semakin besar QC, semakin lambat tugas ini.

MyISAM menggunakan kunci "level tabel". Membaca dan menulis tidak dapat terjadi secara bersamaan (di tabel yang sama). Mentah, tetapi efektif.

Rick James
sumber
1
Baiklah. Kami memiliki sekitar 64 juta cache. Terima kasih atas informasi ini yang baru bagi saya, namun, kami memiliki nilai yang sama pada server lama di mana kami tidak melihat tablelockings. Kami sudah mulai pindah ke InnoDB tetapi fakta ini tetap menjadi misteri ...
32bitfloat