Seberapa besar seharusnya mysql innodb_buffer_pool_size?

170

Saya memiliki database sibuk dengan tabel InnoDB semata-mata yang berukuran sekitar 5GB. Basis data berjalan pada server Debian menggunakan disk SSD dan saya telah mengatur koneksi maks = 800 yang kadang-kadang menjenuhkan dan menggiling server untuk berhenti. Permintaan rata-rata per detik adalah sekitar 2,5 ribu. Jadi saya perlu mengoptimalkan penggunaan memori untuk memberikan ruang bagi koneksi maksimum yang mungkin.

Saya telah melihat saran bahwa innodb_buffer_pool_size seharusnya hingga% 80 dari total memori. Di sisi lain saya mendapatkan peringatan ini dari skrip tuning-primer:

Max Memory Ever Allocated : 91.97 G
Configured Max Per-thread Buffers : 72.02 G
Configured Max Global Buffers : 19.86 G
Configured Max Memory Limit : 91.88 G
Physical Memory : 94.58 G

Berikut adalah variabel innodb saya saat ini:

| innodb_adaptive_flushing                          | ON                                                                                                                     |
| innodb_adaptive_hash_index                        | ON                                                                                                                     |
| innodb_additional_mem_pool_size                   | 20971520                                                                                                               |
| innodb_autoextend_increment                       | 8                                                                                                                      |
| innodb_autoinc_lock_mode                          | 1                                                                                                                      |
| innodb_buffer_pool_instances                      | 1                                                                                                                      |
| innodb_buffer_pool_size                           | 20971520000                                                                                                            |
| innodb_change_buffering                           | all                                                                                                                    |
| innodb_checksums                                  | ON                                                                                                                     |
| innodb_commit_concurrency                         | 0                                                                                                                      |
| innodb_concurrency_tickets                        | 500                                                                                                                    |
| innodb_data_file_path                             | ibdata1:10M:autoextend                                                                                                 |
| innodb_data_home_dir                              |                                                                                                                        |
| innodb_doublewrite                                | ON                                                                                                                     |
| innodb_fast_shutdown                              | 1                                                                                                                      |
| innodb_file_format                                | Antelope                                                                                                               |
| innodb_file_format_check                          | ON                                                                                                                     |
| innodb_file_format_max                            | Antelope                                                                                                               |
| innodb_file_per_table                             | ON                                                                                                                     |
| innodb_flush_log_at_trx_commit                    | 2                                                                                                                      |
| innodb_flush_method                               | O_DIRECT                                                                                                               |
| innodb_force_load_corrupted                       | OFF                                                                                                                    |
| innodb_force_recovery                             | 0                                                                                                                      |
| innodb_io_capacity                                | 200                                                                                                                    |
| innodb_large_prefix                               | OFF                                                                                                                    |
| innodb_lock_wait_timeout                          | 50                                                                                                                     |
| innodb_locks_unsafe_for_binlog                    | OFF                                                                                                                    |
| innodb_log_buffer_size                            | 4194304                                                                                                                |
| innodb_log_file_size                              | 524288000                                                                                                              |
| innodb_log_files_in_group                         | 2                                                                                                                      |
| innodb_log_group_home_dir                         | ./                                                                                                                     |
| innodb_max_dirty_pages_pct                        | 75                                                                                                                     |
| innodb_max_purge_lag                              | 0                                                                                                                      |
| innodb_mirrored_log_groups                        | 1                                                                                                                      |
| innodb_old_blocks_pct                             | 37                                                                                                                     |
| innodb_old_blocks_time                            | 0                                                                                                                      |
| innodb_open_files                                 | 300                                                                                                                    |
| innodb_purge_batch_size                           | 20                                                                                                                     |
| innodb_purge_threads                              | 0                                                                                                                      |
| innodb_random_read_ahead                          | OFF                                                                                                                    |
| innodb_read_ahead_threshold                       | 56                                                                                                                     |
| innodb_read_io_threads                            | 4                                                                                                                      |
| innodb_replication_delay                          | 0                                                                                                                      |
| innodb_rollback_on_timeout                        | OFF                                                                                                                    |
| innodb_rollback_segments                          | 128                                                                                                                    |
| innodb_spin_wait_delay                            | 6                                                                                                                      |
| innodb_stats_method                               | nulls_equal                                                                                                            |
| innodb_stats_on_metadata                          | ON                                                                                                                     |
| innodb_stats_sample_pages                         | 8                                                                                                                      |
| innodb_strict_mode                                | OFF                                                                                                                    |
| innodb_support_xa                                 | ON                                                                                                                     |
| innodb_sync_spin_loops                            | 30                                                                                                                     |
| innodb_table_locks                                | ON                                                                                                                     |
| innodb_thread_concurrency                         | 4                                                                                                                      |
| innodb_thread_sleep_delay                         | 10000                                                                                                                  |
| innodb_use_native_aio                             | ON                                                                                                                     |
| innodb_use_sys_malloc                             | ON                                                                                                                     |
| innodb_version                                    | 1.1.8                                                                                                                  |
| innodb_write_io_threads                           | 4                                                                                                                      |

Catatan tambahan yang mungkin relevan: Saya melihat bahwa ketika saya mencoba memasukkan posting besar (katakanlah lebih dari 10KB) dari Drupal (yang duduk di server web terpisah) ke basis data, ia akan bertahan selamanya dan halaman tidak kembali dengan benar.

Mengenai ini, saya bertanya-tanya apa yang seharusnya menjadi innodb_buffer_pool_size saya untuk kinerja yang optimal. Saya menghargai saran Anda untuk mengatur ini dan parameter lain secara optimal untuk skenario ini.

alfish
sumber

Jawaban:

252

Innodb_buffer_pool_size Anda sangat besar. Anda mengaturnya di 20971520000. Itu 19.5135 GB. Jika Anda hanya 5GB data dan indeks InnoDB, maka Anda seharusnya hanya memiliki sekitar 8GB. Bahkan ini mungkin terlalu tinggi.

Inilah yang harus Anda lakukan. Pertama jalankan query ini

SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
(SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
FROM information_schema.tables WHERE engine='InnoDB') A;

Ini akan memberi Anda RIBPS, Ukuran Kolam Penyangga InnoDB yang Direkomendasikan berdasarkan semua Data dan Indeks InnoDB dengan tambahan 60%.

Sebagai contoh

mysql>     SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
    ->     (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
    ->     FROM information_schema.tables WHERE engine='InnoDB') A;
+-------+
| RIBPS |
+-------+
|     8 |
+-------+
1 row in set (4.31 sec)

mysql>

Dengan output ini, Anda akan mengatur yang berikut ini di /etc/my.cnf

[mysqld]
innodb_buffer_pool_size=8G

Lanjut, service mysql restart

Setelah restart, jalankan mysql selama satu atau dua minggu. Kemudian, jalankan kueri ini:

SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM
(SELECT variable_value PagesData
FROM information_schema.global_status
WHERE variable_name='Innodb_buffer_pool_pages_data') A,
(SELECT variable_value PageSize
FROM information_schema.global_status
WHERE variable_name='Innodb_page_size') B;

Ini akan memberi Anda berapa banyak GB memori aktual yang digunakan oleh Data InnoDB di Pool Buffer InnoDB saat ini.

Saya telah menulis tentang ini sebelumnya: Apa yang harus ditetapkan innodb_buffer_pool dan mengapa ..?

Anda bisa menjalankan DataGBkueri ini sekarang daripada mengkonfigurasi ulang, memulai kembali dan menunggu seminggu.

Nilai ini DataGBlebih menyerupai seberapa besar Pool Buffer InnoDB seharusnya + (persentase yang ditentukan dalam innodb_change_buffer_max_size). Saya yakin ini akan jauh kurang dari 20.000 juta yang telah Anda pesan sekarang. Penghematan dalam RAM dapat digunakan untuk mengatur hal-hal lain seperti

CAVEAT # 1

Ini sangat penting untuk dicatat: Kadang-kadang, InnoDB mungkin memerlukan tambahan 10% dari nilai untuk innodb_buffer_pool_size . Inilah yang dikatakan Dokumentasi MySQL tentang ini:

Semakin besar Anda menetapkan nilai ini, semakin sedikit disk I / O yang diperlukan untuk mengakses data dalam tabel. Pada server database khusus, Anda dapat mengatur ini hingga 80% dari ukuran memori fisik mesin. Bersiaplah untuk mengurangi nilai ini jika masalah lain ini terjadi:

Persaingan untuk memori fisik dapat menyebabkan paging di sistem operasi.

InnoDB menyimpan memori tambahan untuk buffer dan struktur kontrol, sehingga total ruang yang dialokasikan sekitar 10% lebih besar dari ukuran yang ditentukan.

Ruang alamat harus bersebelahan, yang bisa menjadi masalah pada sistem Windows dengan DLL yang memuat pada alamat tertentu.

Waktu untuk menginisialisasi kumpulan buffer kira-kira sebanding dengan ukurannya. Pada instalasi besar, waktu inisialisasi ini mungkin signifikan. Misalnya, pada server Linux x86_64 modern, inisialisasi kumpulan buffer 10GB membutuhkan waktu sekitar 6 detik. Lihat Bagian 8.9.1, “Kelompok Penyangga InnoDB” .

CAVEAT # 2

Saya Lihat nilai-nilai berikut di Anda my.cnf

| innodb_io_capacity                                | 200 |
| innodb_read_io_threads                            | 4   |
| innodb_thread_concurrency                         | 4   |
| innodb_write_io_threads                           | 4   |

Angka ini akan menghalangi InnoDB mengakses beberapa core

Silakan atur yang berikut ini:

[mysqld]
innodb_io_capacity = 2000
innodb_read_io_threads = 64
innodb_thread_concurrency = 0
innodb_write_io_threads = 64

Saya telah menulis tentang ini sebelumnya di DBA StackExchange

Saya baru saja menjawab pertanyaan seperti ini di ServerFault menggunakan rumus yang lebih ringkas :

SELECT CONCAT(CEILING(RIBPS/POWER(1024,pw)),SUBSTR(' KMGT',pw+1,1))
Recommended_InnoDB_Buffer_Pool_Size FROM
(
    SELECT RIBPS,FLOOR(LOG(RIBPS)/LOG(1024)) pw
    FROM
    (
        SELECT SUM(data_length+index_length)*1.1*growth RIBPS
        FROM information_schema.tables AAA,
        (SELECT 1.25 growth) BBB
        WHERE ENGINE='InnoDB'
    ) AA
) A;
RolandoMySQLDBA
sumber
1
Terima kasih untuk posting yang luar biasa ini! Rumus Anda dimulai dengan SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM...menghasilkan kesalahan berikut pada MySQL 5.7: " Fitur 'INFORMATION_SCHEMA.GLOBAL_STATUS' dinonaktifkan; lihat dokumentasi untuk 'show_compatibility_56' ". Apakah Anda memiliki versi yang diperbarui?
Benjamin
Saya mendapatkan 307 RIBPS dan 264G. Itu berarti saya perlu 307GB RAM?
E_Blue
Lebih mirip 264G. Tetapi Anda harus memiliki RAM yang cukup untuk itu, atau berikan 80% dari RAM Anda ke mysql, tergantung pada apa lagi yang berjalan pada sistem.
sjas
2
Posting terbesar yang pernah saya baca! Saya memiliki ~ database besar sekitar 3GB. Setelah membaca jawaban / artikel Anda dan kecepatan tautan naik hingga 2x
fat_mike
4
@Benjamin: Pada MySQL 5.7.6, information_schema digabung menjadi performance_schema. Jadi, ubah saja "information_schema" menjadi "performance_schema" di kueri untuk membuatnya berfungsi. Sumber: dev.mysql.com/doc/refman/5.7/en/status-table.html
Ralph Bolton
11

Sesuatu seperti ini? Menggunakan SHOW VARIABLESdan SHOW GLOBAL STATUS:

Ekspresi: innodb_buffer_pool_size / _ram
Artinya: % dari RAM yang digunakan untuk InnoDB buffer_pool
Kisaran yang disarankan: 60 ~ 80%

Ekspresi: Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
Arti: Baca permintaan yang harus mencapai disk
Kisaran yang disarankan: 0-2%
Apa yang harus dilakukan jika di luar jangkauan: Tingkatkan innodb_buffer_pool_size jika Anda memiliki cukup RAM

Ekspresi: Innodb_pages_read / Innodb_buffer_pool_read_requests
Artinya: Baca permintaan yang harus mencapai disk
Kisaran yang disarankan: 0-2%
Apa yang harus dilakukan jika di luar kisaran: Tingkatkan innodb_buffer_pool_size jika Anda memiliki RAM yang cukup.

Ekspresi: Innodb_pages_written / Innodb_buffer_pool_write_requests
Artinya: Menulis permintaan yang harus mencapai disk
Kisaran yang disarankan: 0-15%
Apa yang harus dilakukan jika di luar kisaran: Periksa innodb_buffer_pool_size

Ekspresi: Innodb_buffer_pool_reads / Uptime
Artinya: Baca
Rentang yang disarankan: 0-100 / dtk.
Apa yang harus dilakukan jika di luar jangkauan: Tambah innodb_buffer_pool_size?

Ekspresi: (Innodb_buffer_pool_reads + Innodb_buffer_pool_pages_flushed) / Uptime
Artinya: InnoDB I / O
Kisaran yang disarankan: 0-100 / dtk.
Apa yang harus dilakukan jika di luar jangkauan: Tambah innodb_buffer_pool_size?

Ekspresi: Innodb_buffer_pool_pages_flushed / Uptime
Artinya: Menulis (flushes)
Kisaran yang disarankan: 0-100 / dtk.
Apa yang harus dilakukan jika di luar jangkauan: Tambah innodb_buffer_pool_size?

Ekspresi: Innodb_buffer_pool_wait_free / Uptime
Artinya: Counter untuk ketika tidak ada halaman gratis di buffer_pool. Artinya, semua halaman itu kotor.
Kisaran yang disarankan: 0-1 / dtk.
Apa yang harus dilakukan jika di luar jangkauan: Pertama-tama pastikan innodb_buffer_pool_size disetel secara wajar; jika masih bermasalah, kurangi innodb_max_dirty_pages_pct

Rick James
sumber
Terima kasih @Rick untuk komentar yang bagus. innodb_buffer_pool_sizeNilai apa yang ditentukan? Ukuran aktual atau yang dikonfigurasi?
Joker
1
@ joker - innodb_buffer_pool_sizemenunjukkan ukuran maksimal. Dalam server tipikal, "kolam penyangga" mulai kecil, tetapi dengan cepat tumbuh dengan ukuran maksimal dan tetap di sana. Catatan: Jika itu lebih besar dari RAM (atau bahkan dekat), maka itu mengarah ke swapping, yang mengerikan untuk kinerja.
Rick James
7

Judul Anda menanyakan tentang innodb_buffer_pool_size, tapi saya kira itu bukan masalah sebenarnya. (Rolando mengomentari mengapa Anda menetapkannya cukup besar, bahkan terlalu besar.)

Saya telah mengatur koneksi maks = 800 yang kadang-kadang menjenuhkan dan menggiling server untuk berhenti.

Itu tidak jelas. 800 pengguna dalam mode "Tidur" hampir tidak memiliki dampak pada sistem. 800 utas aktif akan menjadi bencana. Berapa banyak utas yang "berjalan"?

Apakah utas saling menghalangi? Lihat SHOW ENGINE INNODB STATUS untuk beberapa petunjuk tentang deadlock, dll.

Apakah ada pertanyaan yang muncul di slowlog? Mari kita optimalkan.

Versi apa yang Anda gunakan? XtraDB (pengganti drop-in untuk InnoDB) melakukan pekerjaan yang lebih baik dalam menggunakan beberapa core. 5.6.7 melakukan pekerjaan yang lebih baik.

innodb_buffer_pool_instances - ubah ini menjadi 8 (dengan asumsi 20G buffer_pool); itu akan mengurangi sedikit pada pertikaian Mutex.

Apakah Anda I / O terikat atau apakah Anda terikat CPU? Solusinya sangat berbeda, tergantung pada jawaban Anda.

SSD - Mungkin lebih baik jika semua file log berada di drive non-SSD.

Rick James
sumber
6

Lebih banyak memori selalu lebih baik, tetapi dalam pengalaman saya sebagian besar ukuran buffer pool seharusnya tidak sesuai dengan ukuran data Anda. Banyak tabel tidak aktif sebagian besar waktu, seperti tabel cadangan tergeletak di sekitar, jadi ukuran kolam penyangga innodb lebih cocok untuk Anda ukuran data acive.

Kerangka waktu yang Anda tentukan untuk halaman aktif memengaruhi kinerja, tetapi ada titik optimal, di mana Anda tidak akan mendapatkan lebih banyak kinerja untuk ukuran buffer yang lebih besar. Anda dapat memperkirakan / menghitung / mengukurnya denganshow engine innodb status

pengguna77376
sumber