私は、サイズが約5GBのInnoDBテーブルのみを使用する多忙なデータベースを使用しています。データベースはSSDディスクを使用してDebianサーバー上で実行され、最大接続数= 800に設定しましたが、飽和してサーバーを停止して停止することがあります。 1秒あたりの平均クエリは約2.5Kです。したがって、メモリの使用を最適化して、可能な限り最大の接続のためのスペースを確保する必要があります。
私はinnodb_buffer_pool_sizeが合計メモリの最大80%であるべきだという提案を見てきました。一方、チューニングプライマースクリプトから次の警告が表示されます。
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
これが私の現在のinnodb変数です:
| 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 |
関連する可能性がある副次的な注意:Drupal(これは別のWebサーバー上にあります))からデータベースに大きな投稿(たとえば10KBを超える)を挿入しようとすると、永久に続くそして、ページは正しく戻りません。
これらに関して、最適なパフォーマンスを得るには、私のinnodb_buffer_pool_sizeはどうあるべきだと思います。このシナリオに最適なこのパラメータおよびその他のパラメータを設定するための提案に感謝します。
あなたの innodb_buffer_pool_size は巨大です。 20971520000
に設定されています。それは19.5135 GBです。 5 GBのInnoDBデータとインデックスしかない場合は、約8 GBしかありません。これでも高すぎるかもしれません。
これがあなたがすべきことです。最初にこのクエリを実行する
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;
これにより、すべてのInnoDBデータとインデックスに基づくRIBPS、推奨InnoDBバッファープールサイズ、さらに60%が得られます。
例えば
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>
この出力では、/ etc/my.cnfに次のように設定します。
[mysqld]
innodb_buffer_pool_size=8G
次に、service mysql restart
再起動後、MySQLを1〜2週間実行します。次に、このクエリを実行します。
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;
これにより、現時点でInnoDBバッファープール内のInnoDBデータによって使用されている実際のGBのメモリ数がわかります。
私はこれについて以前に書いたことがあります: innodb_buffer_poolに設定するものと理由..?
このDataGB
クエリは、再構成して再起動し、1週間待つのではなく、今すぐ実行できます。
この値DataGB
は、InnoDBバッファープールの大きさ+(innodb_change_buffer_max_sizeで指定されたパーセンテージ)に非常によく似ています。これは、現在予約している20000Mよりはるかに少ないと思います。 RAMの節約は、以下のような他の調整に使用できます
これは非常に重要なことです。InnoDBでは、 innodb_buffer_pool_size の値よりも10%高い値が必要になる場合があります。これは MySQL Documentation がこれについて言っていることです:
この値を大きく設定すると、テーブル内のデータにアクセスするために必要なディスクI/Oが少なくなります。専用データベースサーバーでは、これをマシンの物理メモリサイズの最大80%に設定できます。これらの他の問題が発生した場合は、この値を縮小する準備をしてください。
物理メモリの競合により、オペレーティングシステムでページングが発生する可能性があります。
InnoDBは、バッファーと制御構造用に追加のメモリを予約するため、割り当てられたスペースの合計は、指定されたサイズよりも約10%大きくなります。
アドレス空間は連続している必要があります。これは、特定のアドレスでロードされるDLLを備えたWindowsシステムで問題になる可能性があります。
バッファプールを初期化する時間は、そのサイズにほぼ比例します。大規模なインストールでは、この初期化に時間がかかる場合があります。たとえば、最新のLinux x86_64サーバーでは、10GBのバッファープールの初期化には約6秒かかります。セクション8.9.1、 「InnoDBバッファープール」 を参照してください。
my.cnf
に次の値が表示されます
| innodb_io_capacity | 200 |
| innodb_read_io_threads | 4 |
| innodb_thread_concurrency | 4 |
| innodb_write_io_threads | 4 |
これらの数は、InnoDBが複数のコアにアクセスするのを妨げます
以下を設定してください:
[mysqld]
innodb_io_capacity = 2000
innodb_read_io_threads = 64
innodb_thread_concurrency = 0
innodb_write_io_threads = 64
以前、DBA StackExchangeでこれについて書いています
より簡潔な式を使用して、サーバー障害で このような質問 と答えました。
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;
このようなもの? SHOW VARIABLES
およびSHOW GLOBAL STATUS
の使用:
式: innodb_buffer_pool_size / _ram
意味: %= RAM InnoDB buffer_poolに使用
推奨範囲: 60〜80%
式: Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
意味: ディスクをヒットする必要があった読み取り要求
推奨範囲: 0〜2%
範囲外の場合の対処方法: 十分なRAMがある場合は、innodb_buffer_pool_sizeを増やします。
式: Innodb_pages_read / Innodb_buffer_pool_read_requests
意味: ディスクをヒットする必要があった読み取り要求
推奨範囲: 0〜2%
範囲外の場合の対処方法: 十分なRAMがある場合は、innodb_buffer_pool_sizeを増やします。
式: Innodb_pages_written / Innodb_buffer_pool_write_requests
意味: ディスクをヒットする必要があった書き込み要求
推奨範囲: 0〜15%
範囲外の場合の対処方法: innodb_buffer_pool_sizeを確認してください
式: Innodb_buffer_pool_reads / Uptime
意味: 読む
推奨範囲: 0-100 /秒。
範囲外の場合の対処方法: innodb_buffer_pool_sizeを増やしますか?
式: (Innodb_buffer_pool_reads + Innodb_buffer_pool_pages_flushed) / Uptime
意味: InnoDB I/O
推奨範囲: 0-100 /秒。
範囲外の場合の対処方法: innodb_buffer_pool_sizeを増やしますか?
式: Innodb_buffer_pool_pages_flushed / Uptime
意味: 書き込み(フラッシュ)
推奨範囲: 0-100 /秒。
範囲外の場合の対処方法: innodb_buffer_pool_sizeを増やしますか?
式: Innodb_buffer_pool_wait_free / Uptime
意味: buffer_poolに空きページがない場合のカウンター。つまり、すべてのページがダーティです。
推奨範囲: 0-1 /秒。
範囲外の場合の対処方法: まず、innodb_buffer_pool_sizeが適切に設定されていることを確認してください。それでも問題が解決しない場合は、innodb_max_dirty_pages_pctを減らします
あなたのタイトルはinnodb_buffer_pool_sizeについて尋ねていますが、それは本当の問題ではないようです。 (Rolandoは、なぜあなたがそれを十分な大きさに設定したのか、大きすぎたのかについてコメントしました。)
最大接続数= 800に設定しましたが、サーバーが飽和して、サーバーを停止して停止することがあります。
それは不明確です。 「スリープ」モードの800人のユーザーがシステムに与える影響はほとんどありません。 800のアクティブスレッドは障害になります。 「実行中」のスレッドはいくつありますか?
スレッドはお互いをブロックしていますか?デッドロックなどの手がかりについては、SHOW ENGINE INNODB STATUSを参照してください。
スローログにクエリが表示されていますか?それらを最適化しましょう。
どのバージョンを使用していますか? XtraDB(InnoDBのドロップイン代替品)は、複数のコアを使用することにより優れた機能を発揮します。 5.6.7はさらに良い仕事をします。
innodb_buffer_pool_instances-これを8に変更します(20G buffer_poolを想定)。ミューテックスの競合を少し減らします。
I/Oバウンドですか、それともCPUバウンドですか?あなたの答えに応じて、解決策は根本的に異なります。
SSD-すべてのログファイルがSSD以外のドライブにある方が良い場合があります。
メモリが多いほど良いですが、私の経験では、ほとんどの場合、バッファープールのサイズはデータサイズに適合しません。多くのテーブルは、周りにあるバックアップテーブルのように、ほとんどの場合非アクティブです。そのため、innodbバッファープールのサイズは、実際のデータサイズに適しています。
アクティブページに指定する時間枠はパフォーマンスに影響しますが、バッファーサイズを大きくしてもパフォーマンスが向上しない最適なポイントがあります。 show engine innodb status
によってそれを推定/計算/測定できます