Posting blog ini dimotivasi oleh diskusi internal tentang cara menonaktifkan sepenuhnya cache kueri di MySQL Show Menurut , kita seharusnya dapat menonaktifkan “Query Cache” dengan cepat dengan mengubah query_cache_type menjadi 0, tetapi seperti yang akan kita lakukan . Blog ini akan menunjukkan kepada Anda cara menonaktifkan "cache kueri" dengan benar, dan bagaimana praktik umum mungkin tidak sebaik yang kami kira. Bisakah kita menonaktifkannya dengan mengubah variabel, atau memerlukan restart untuk menghindari mutex global? Beberapa konteks Cache KueriCache kueri menyimpan teks pernyataan "Pilih" bersama dengan hasil terkait yang dikirim ke klien. Jika pernyataan yang identik diterima nanti, server mengambil hasilnya dari cache kueri daripada mem-parsing dan mengeksekusi pernyataan itu lagi. Cache kueri dibagikan di antara sesi, sehingga kumpulan hasil yang dihasilkan oleh satu klien dapat dikirim sebagai tanggapan atas kueri yang sama yang dikeluarkan oleh klien lain Namun, kueri yang dapat di-cache mengambil "kunci eksklusif" di cache kueri MySQL. Selain itu, penyisipan, pemutakhiran, penghapusan, atau modifikasi lain apa pun pada tabel menyebabkan entri apa pun yang relevan dalam cache kueri dihapus. Jika Anda melihat banyak "Menunggu kunci cache kueri" di daftar proses, Anda mungkin menderita kunci eksklusif ini. Dalam posting blog ini, Anda dapat melihat bagaimana mutex global dalam konkurensi tinggi ini dapat menyebabkan penurunan kinerja Jika kita menghadapi situasi ini, bagaimana kita bisa menonaktifkannya? Menonaktifkan Cache KueriAda dua opsi yang dapat Anda ubah. query_cache_type dan query_cache_size. Jadi jika kita mengubah query_cache_size menjadi “0”, apakah itu berarti cache dinonaktifkan? query_cache_type? Or both? And does MySQL require a restart to avoid the global mutex? Kode sumber menunjukkan ini kepada kita kirim_hasil_ke_klien Kerang1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 int Cache_kueri. . send_result_to_client(THD * thd, const LEX_CSTRING &sql) { ulonglong engine_data; Kueri_cache_kueri * kueri; #ifndef EMBEDDED_LIBRARY Blokir_cache_kueri * blok_result_pertama; #berakhir jika Query_cache_block * result_block; Query_cache_block_table * block_table, *block_table_end; char * cache_key = NULL; size_t tot_length; Query_cache_query_flags tanda; DBUG_ENTER("Query_cache. send_result_to_client");
/* Pengujian 'query_cache_size' tanpa a lock here is safe: the benda kami dapat lepas adalah that the query won't be served from cache, but we simpan di mutex mengunci in the case when query cache is disabled. Lihat juga a catatan on double-check locking usage above. */ jika (dinonaktifkan() |. thd - >locked_tables_mode . . thd - >variabel.query_cache_type == 0 . . query_cache_size == 0) goto err; . . . MySQL akan memeriksa apakah cache kueri diaktifkan sebelum menguncinya. Itu memeriksa empat kondisi, dan salah satunya harus benar. Tiga yang terakhir mungkin sudah jelas, tapi apa fungsi “is_disabled()”? . C1 2 3 batal disable_query_cache(batal) { m_query_cache_is_disabled= TRUE; } . . . bool dinonaktifkan(batal) { return m_query_cache_is_disabled; } Kueri_cache C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 batal Cache_kueri. . init() { DBUG_ENTER("Query_cache. init"); mysql_mutex_init(key_structure_guard_mutex, &structure_guard_mutex, MY_MUTEX_INIT_FAST); mysql_cond_init(key_COND_cache_status_changed, &COND_cache_status_changed); m_cache_lock_status = Cache_kueri. . BUKA KUNCI; diinisialisasi = 1; /* Jika kita secara eksplisit mematikan query cache dari command line, query cache akan dinonaktifkan untuk pengingat waktu hidup server. Ini karena kita ingin menghindari mengunci mutex khusus QC jika cache kueri tidak mau digunakan */ jika (variabel_sistem_global. query_cache_type == 0) query_cache. disable_query_cache();
DBUG_VOID_RETURN; } Jika variabel_sistem_global. query_cache_type == 0 kondisi benar akan memanggil disable_query_cache . Artinya, jika kita menyetel function, which sets m_query_cache_is_disabled = True, so is_disabled going to be “True”. That means if we are setting query_cache_type ke 0 pada waktu proses, itu akan menghilangkan mutex global. Mari jalankan beberapa pengujian untuk mengonfirmasi hal ini dan lihat apakah global mutex menghilang setelah mengubah query_cache_type menjadi 0. Menjalankan tes Konteks pada tes
1 sysbench -- tes = "/usr/ . lua" -- laporan - interval=1 --max-time=120 --oltp-read-only=off --max-requests=0 --num-threads=4 --oltp-table-size=2000000 --mysql-host=localhost --mysql-db=test --db-driver=mysql --mysql-user=root run
1 2 3 4 query_cache_type = 1 query_cache_limit = 1jt query_cache_size = 1G performance_schema_instrument = 'wait/synch/%Query_cache%=COUNTED' Jadi pada dasarnya pengujian dijalankan selama dua menit masing-masing saat bermain dengan query_cache_type dan query_cache_size.
Jadi, satu-satunya cara untuk menghentikan aktivitas apa pun di sekitar cache kueri memerlukan memulai ulang MySQL dengan query_cache_type = 0 . Menonaktifkannya atau bahkan menyetelnya ke "0" saat runtime tidak sepenuhnya menghentikan aktivitas mutex. and query_cache_size=0. Disabling it or even set it to “0” on runtime is not completely stopping mutex activity. Tetapi mengapa kita masih membutuhkan query_cache_size sementara dalam teori query_cache_type should be enough? Seperti yang dirujuk di atas, manual mengatakan jika query_cache_type = 0 Jangan menyimpan hasil dalam cache atau mengambil hasil dari cache kueri. Perhatikan bahwa ini tidak membatalkan alokasi buffer cache kueri. Untuk melakukannya, Anda harus menyetel query_cache_size ke 0 Berdasarkan pengujian kami, jika kami mengubah query_cache_type menjadi 0, itu masih mengenai cache. Jadi Anda mungkin berpikir “baiklah, saya tidak mengaktifkan cache kueri dan menggunakan default untuk tetap menonaktifkannya. ” Teruslah membaca, karena Anda mungkin salah. Menurut , mulai dari 5. 6. 8 query_cache_type = 0 disetel secara default, tetapi query_cache_size= 1048576 (1MB). This means that if we keep default configuration, we will still see activity in the query cache as follows: Kerang1 2 3 4 5 6 7 8 9 10 11 12 13 mysql - e "tampilkan status global seperti 'qca%';" +---------------------------------------+---------+ . Nama_Variabel . Nilai . +---------------------------------------+---------+ . Qcache_free_blocks . 1 . . Qcache_free_memory . 1031320 . . Qcache_hits . 0 . . Qcache_inserts . 0 . . Qcache_lowmem_prunes . 0 . . Qcache_not_cached . 423294 . . Qcache_queries_in_cache . 0 . . Qcache_total_blocks . 1 . +---------------------------------------+---------+ Tetapi jika kita hanya menambahkan query_cache_size = 0 ke . cnf dan periksa lagi (tentu saja setelah me-restart server). 1 2 3 4 5 6 7 8 9 10 11 12 13 mysql - e "tampilkan status global seperti 'qca%';" +---------------------------------------+-------+ . Nama_Variabel . Nilai . +---------------------------------------+-------+ . Qcache_free_blocks . 0 . . Qcache_free_memory . 0 . . Qcache_hits . 0 . . Qcache_inserts . 0 . . Qcache_lowmem_prunes . 0 . . Qcache_not_cached . 0 . . Qcache_queries_in_cache . 0 . . Qcache_total_blocks . 0 . +---------------------------------------+-------+ Kami akhirnya tidak mendapatkan aktivitas terkait cache kueri sama sekali. Berapa banyak overhead yang disebabkan oleh ini? Menggali lebih banyak kodeMari kita lihat fungsi. MySQL menggunakan fungsi ini untuk menyimpan kueri dalam cache kueri. Jika kita membaca kode kita dapat menemukan ini C1 2 jika (thd - >locked_tables_mode |. query_cache_size == 0) DBUG_VOID_RETURN; Ini hanya memeriksa query_cache_size , tidak memeriksa jenis. Store Query is called in , which also does not check the query_cache_type . Kesimpulan Ada kontradiksi antara memeriksa cache kueri dan menyimpan data di cache kueri, yang memerlukan penyelidikan lebih lanjut. Namun seperti yang dapat kita lihat, tidak mungkin untuk sepenuhnya menonaktifkan cache kueri dengan cepat dengan mengubah query_cache_type atau/dan query_cache_size to 0. Based on the code and the tests, if you want to make sure the query cache is fully disabled, change query_cache_size dan query_cache_type to 0 and restart MySQL. Adalah fakta yang diketahui bahwa cache kueri dapat menjadi titik perdebatan yang besar, dan kami tidak mencoba untuk membandingkan overhead kinerja karena ini sebagian besar bergantung pada jenis beban kerja. Namun, kami masih dapat melihat beberapa overhead jika cache kueri tidak sepenuhnya dinonaktifkan saat MySQL dimulai Bagaimana cara memeriksa cache di MySQL?MySQL menentukan kueri untuk di-cache dengan memeriksa variabel query_cache_type . Menyetel nilai ini ke 0 atau MATI mencegah caching atau pengambilan kueri yang disimpan dalam cache. Anda juga dapat menyetelnya ke 1 untuk mengaktifkan caching untuk semua kueri kecuali yang dimulai dengan pernyataan SELECT SQL_NO_CACHE.
Bagaimana cara mengaktifkan cache MySQL?Keluar dari MySQL. Buka terminal dan jalankan perintah berikut untuk membuka file konfigurasi MySQL. Kami telah mengaktifkan cache kueri dengan menyetel variabel query_cache_type ke 1, dengan cache kueri individual sebesar 256Kb dan total cache sebesar 10Mb .
Bagaimana cara saya memeriksa apakah kueri MySQL sedang berjalan?Untuk melihat kueri mana yang aktif dijalankan untuk instans DB MySQL di Amazon RDS, ikuti langkah-langkah ini. . Sambungkan ke instans DB yang menjalankan MySQL Jalankan perintah berikut. TAMPILKAN DAFTAR PROSES LENGKAP\G. . Atau, jalankan kueri berikut untuk mengambil kumpulan hasil yang sama Bagaimana cara menonaktifkan cache MySQL?Jadi, satu-satunya cara untuk menghentikan aktivitas apa pun di sekitar cache kueri memerlukan memulai ulang MySQL dengan query_cache_type = 0 dan query_cache_size=0 . |