MySQLは広範であり、必要なパフォーマンスを得るために最適化および調整する領域がたくさんあります。動的に実行できる変更もあれば、サーバーの再起動が必要な変更もあります。デフォルト構成のMySQLインストールを見つけることはかなり一般的ですが、後者はワークロードとセットアップからそれ自体が適切でない場合があります。
これは、MySQLの世界のさまざまな専門家の情報源から取得したMySQLの主要な領域と、ここSevereninesでの私たち自身の経験です。このブログは、パフォーマンスを調整し、MySQLを再び素晴らしいものにするためのチートシートとして機能します:-)
MySQLの主要な領域の概要を説明して、これらを見てみましょう。
システム変数
MySQLには、変更を検討できる変数がたくさんあります。一部の変数は動的です。つまり、SETステートメントを使用して設定できます。その他の場合は、構成ファイル(/etc/my.cnfなど/mysql/my.cnf)で設定した後、サーバーを再起動する必要があります。ただし、サーバーを最適化するために調整するのに非常に一般的な一般的な事項について説明します。
sort_buffer_size
この変数は、ファイルソートバッファーのサイズを制御します。つまり、クエリで行をソートする必要がある場合は常に、この変数の値を使用して、割り当てる必要のあるサイズを制限します。この変数は、処理される(または接続ごとの)クエリごとであることに注意してください。これは、これを高く設定し、行の並べ替えが必要な複数の接続がある場合、メモリを大量に消費することを意味します。ただし、グローバルステータス変数Sort_merge_passesを確認することで、ニーズを監視できます。この値が大きい場合は、sort_buffer_sizeシステム変数の値を増やすことを検討する必要があります。それ以外の場合は、必要な適度な限界までそれを取ります。これを低く設定しすぎる場合、または処理するクエリが大きい場合は、ディスクダイブを実行してデータがランダムに取得されるため、行の並べ替えの効果が予想よりも遅くなる可能性があります。これにより、パフォーマンスが低下する可能性があります。ただし、クエリを修正することをお勧めします。それ以外の場合、アプリケーションが大きなクエリをプルするように設計されており、並べ替えが必要な場合は、Redisなどのクエリキャッシュを処理するツールを使用すると効率的です。デフォルトでは、MySQL 8.0では、現在設定されている値は256KiBです。ソートを頻繁に使用または呼び出すクエリがある場合にのみ、これを適宜設定してください。
read_buffer_size
MySQLのドキュメントには、テーブルのシーケンシャルスキャンを実行するリクエストごとに、読み取りバッファが割り当てられると記載されています。 read_buffer_sizeシステム変数は、バッファーサイズを決定します。 MyISAMにも役立ちますが、この変数はすべてのストレージエンジンにも影響します。 MEMORYテーブルの場合、メモリブロックサイズを決定するために使用されます。
基本的に、MyISAMテーブルのシーケンシャルスキャンを実行する各スレッドは、スキャンするテーブルごとにこのサイズ(バイト単位)のバッファーを割り当てます。これはすべてのストレージエンジン(InnoDBを含む)にも適用されるため、ORDER BYを使用して行を並べ替え、そのインデックスを一時ファイルにキャッシュするクエリに役立ちます。多数のシーケンシャルスキャンを実行する場合は、パーティションテーブルに一括挿入し、ネストされたクエリの結果をキャッシュしてから、その値を増やすことを検討してください。この変数の値は4KBの倍数である必要があります。 4KBの倍数ではない値に設定されている場合、その値は最も近い4KBの倍数に切り捨てられます。これをより高い値に設定すると、サーバーのメモリの大部分が消費されることを考慮に入れてください。環境の適切なベンチマークと監視なしにこれを使用しないことをお勧めします。
read_rnd_buffer_size
この変数は、キーソート操作に続いてソートされた順序でMyISAMテーブルから行を読み取ることを処理します。行は、ディスクシークを回避するために、このバッファーを介して読み取られます。ドキュメントによると、キーソート操作に続いて任意の順序で、またはMyISAMテーブルからソートされた順序で行を読み取る場合、ディスクシークを回避するために、行はこのバッファーを介して読み取られます(そしてこのバッファーサイズを介して決定されます)。変数を大きな値に設定すると、ORDERBYのパフォーマンスが大幅に向上します。ただし、これはクライアントごとに割り当てられるバッファであるため、グローバル変数を大きな値に設定しないでください。代わりに、大規模なクエリを実行する必要があるクライアント内からのみセッション変数を変更してください。ただし、特にMRRを利用する場合は、これがMariaDBには適用されないことを考慮に入れる必要があります。 MariaDBはmrr_buffer_sizeを使用し、MySQLはread_buffer_sizeread_rnd_buffer_sizeを使用します。
join_buffer_size
デフォルトでは、値は256Kです。プレーンインデックススキャン、範囲インデックススキャン、およびインデックスを使用せずに全表スキャンを実行する結合に使用されるバッファの最小サイズ。 BKA最適化でも使用されます(デフォルトでは無効になっています)。インデックスを追加できない場合は、値を増やして完全結合を高速化します。ただし、これを高く設定しすぎると、メモリの問題になる可能性があります。 2つのテーブル間の完全な結合ごとに1つの結合バッファーが割り当てられることに注意してください。インデックスが使用されていない複数のテーブル間の複雑な結合の場合、複数の結合バッファが必要になる場合があります。大規模な完全結合を必要とするセッションでは、グローバルにローのままにし、セッションでハイに設定するのが最適です(SET SESSION構文を使用)。 64ビットプラットフォームでは、Windowsは4GBを超える値を4GB-1に切り捨て、警告を表示します。
max_heap_table_size
これは、ユーザーが作成したMEMORYテーブルの拡張が許可されているバイト単位の最大サイズです。これは、アプリケーションがMEMORYストレージエンジンテーブルを処理している場合に役立ちます。サーバーがアクティブなときに変数を設定しても、再作成または変更されない限り、既存のテーブルには影響しません。 max_heap_table_sizeとtmp_table_sizeの小さい方も、内部メモリ内テーブルを制限します。この変数はtmp_table_sizeと組み合わせて、内部メモリ内テーブルのサイズを制限します(これは、max_heap_table_sizeのみを適用するため、Engine =MEMORYとして明示的に作成されたテーブルとは異なります)。2つの間に適用されるのは小さい方です。
tmp_table_size
メモリ内の一時テーブル(MEMORYテーブルではない)の最大サイズ。ただし、max_heap_table_sizeが小さい場合は、下限が適用されます。メモリ内の一時テーブルが制限を超えると、MySQLはそれをディスク上の一時テーブルに自動的に変換します。多くの高度なGROUPBYクエリを実行し、使用可能なメモリスペースが大きい場合は、tmp_table_size(および必要に応じてmax_heap_table_size)の値を増やします。 Created_tmp_disk_tables変数とCreated_tmp_tables変数の値を比較することにより、作成された内部ディスク上の一時テーブルの数を、作成された内部一時テーブルの総数と比較できます。 ClusterControlでは、ダッシュボード->一時オブジェクトグラフを介してこれを監視できます。
table_open_cache
データセットで頻繁にアクセスされるテーブルが多数ある場合は、この変数の値を増やすことができます。これはすべてのスレッドに適用されます。つまり、接続ごとに適用されます。この値は、サーバーが1つのテーブルキャッシュインスタンスで開いたままにできるテーブルの最大数を示します。この値を増やすと、mysqldが必要とするファイル記述子の数が増えるため、open_files_limit値を確認するか、*nixオペレーティングシステムで設定されているSOFTおよびHARDの制限の大きさを確認することをお勧めします。 Opened_tablesステータス変数をチェックすることにより、テーブルキャッシュを増やす必要があるかどうかを監視できます。 Opened_tablesの値が大きく、FLUSH TABLESを頻繁に使用しない場合(すべてのテーブルを強制的に閉じて再度開くだけ)、table_open_cache変数の値を増やす必要があります。 table_open_cacheの値が小さく、多数のテーブルに頻繁にアクセスする場合、これはサーバーのパフォーマンスに影響を与える可能性があります。 MySQLプロセスリストにステータスが「Openingtables」または「Closingtables」のエントリが多数ある場合は、この変数の値を調整しますが、前述の注意事項に注意してください。 ClusterControlでは、[ダッシュボード]->[テーブルオープンキャッシュステータス]または[ダッシュボード]->[テーブルを開く]でこれを確認できます。詳細については、こちらで確認できます。
table_open_cache_instances
この変数を設定すると、スケーラビリティが向上し、もちろん、セッション間の競合が減少するパフォーマンスが向上します。ここで設定する値は、開いているテーブルのキャッシュインスタンスの数を制限します。開いているテーブルのキャッシュは、table_open_cache/table_open_cache_instancesのサイズのいくつかの小さなキャッシュインスタンスに分割できます。セッションは、DMLステートメントでアクセスするために1つのインスタンスのみをロックする必要があります。これにより、インスタンス間でキャッシュアクセスがセグメント化され、テーブルにアクセスするセッションが多い場合にキャッシュを使用する操作のパフォーマンスが向上します。 (DDLステートメントは引き続きキャッシュ全体をロックする必要がありますが、そのようなステートメントの頻度はDMLステートメントよりもはるかに少なくなります。)16以上のコアを日常的に使用するシステムでは、8または16の値をお勧めします。
table_definition_cache
テーブル定義をキャッシュします。つまり、これは、テーブルのオープンを高速化し、テーブルごとに1つのエントリのみを高速化するためにCREATETABLEがキャッシュされる場所です。テーブルの数が多い場合は、値を増やすのが妥当です。テーブル定義キャッシュは、通常のテーブルキャッシュとは異なり、使用するスペースが少なく、ファイル記述子を使用しません。 PerconaのPeterZaitsevは、以下の式の設定を試すことができるかどうかを提案しています。
The number of user-defined tables + 10% unless 50K+ tables
ただし、デフォルト値は、2000の制限を上限とする次の式に基づいていることに注意してください。
MIN(400 + table_open_cache / 2, 2000)
したがって、デフォルトと比較してテーブルの数が多い場合は、その値を増やすのが妥当です。 InnoDBでは、この変数がデータディクショナリキャッシュのオープンテーブルインスタンス数のソフト制限として使用されることを考慮に入れてください。この変数の現在の値を超えると、LRUメカニズムが適用されます。この制限は、次のサーバーの再起動まで、めったに使用されないテーブルインスタンスをキャッシュするために大量のメモリが使用される状況に対処するのに役立ちます。したがって、外部キー関係を持つ親テーブルインスタンスと子テーブルインスタンスはLRUリストに配置されず、table_definition_cacheで定義された制限よりも高い値を課す可能性があり、LRU中にメモリ内で削除されることはありません。さらに、table_definition_cacheは、一度に開くことができるInnoDBファイル/テーブルテーブルスペースの数のソフト制限を定義します。これもinnodb_open_filesによって制御され、実際、両方が設定されている場合は、これらの変数間の最高の設定が使用されます。 。どちらの変数も設定されていない場合は、デフォルト値が高いtable_definition_cacheが使用されます。開いているテーブルスペースファイルハンドルの数がtable_definition_cacheまたはinnodb_open_filesで定義された制限を超えると、LRUメカニズムはテーブルスペースファイルのLRUリストを検索して、完全にフラッシュされ、現在拡張されていないファイルを探します。このプロセスは、新しい表領域が開かれるたびに実行されます。 「非アクティブな」表領域がない場合、表領域ファイルは閉じられません。したがって、これを覚えておいてください。
max_allowed_packet
これは、返されるSQLクエリまたは行の接続ごとの最大サイズです。この値は、MySQL5.6で最後に増加しました。ただし、MySQL 8.0(少なくとも8.0.3では)では、現在のデフォルト値は64MiBです。プルアウト(または読み取り)する必要のある大きなBLOB行がある場合は、これを調整することを検討してください。そうでない場合は、このデフォルト設定を8.0のままにしておくことができますが、古いバージョンでは、デフォルトは4 MiBであるため、 ER_NET_PACKET_TOO_LARGEエラーが発生します。 MySQL8.0サーバーまたはクライアントとの間で送受信できる最大のパケットは1GBです。
skip_name_resolve MySQLサーバーは、ホスト名解決によって着信接続を処理します。デフォルトでは、MySQLはホスト名解決を無効にしません。つまり、DNSルックアップを実行します。また、DNSが遅い場合は、データベースのパフォーマンスが低下する可能性があります。 DNS解決が必要ない場合はこれをオンにすることを検討し、このDNSルックアップが無効になっているときにMySQLのパフォーマンスを向上させることを利用してください。この変数は動的ではないことを考慮に入れてください。したがって、MySQL構成ファイルでこれを設定する場合は、サーバーを再起動する必要があります。オプションでmysqldデーモンを起動し、-skip-name-resolveオプションを渡してこれを有効にすることができます。max_connections
これは、MySQLサーバーで許可されている接続の数です。 MySQLの「接続が多すぎます」でエラーを見つけた場合は、それを高く設定することを検討してください。デフォルトでは、特に本番データベースでは151の値では不十分であり、サーバーのリソースが多いことを考慮すると(特に、専用のMySQLサーバーの場合はサーバーリソースを無駄にしないでください)。ただし、十分なファイル記述子が必要です。そうしないと、ファイル記述子が不足します。その場合は、* nixオペレーティングシステムのSOFTおよびHARD制限を調整し、MySQLでopen_files_limitの値を高く設定することを検討してください(5000がデフォルトの制限です)。アプリケーションがデータベースへの接続を正しく閉じないことが非常に頻繁にあることを考慮してください。max_connectionsを高く設定すると、サーバーの応答がないか、負荷が高くなる可能性があります。アプリケーションレベルで接続プールを使用すると、ここで問題を解決するのに役立ちます。
thread_cache_size
これは、過度のスレッド作成を防ぐためのキャッシュです。クライアントが切断すると、thread_cache_sizeスレッドよりも少ないスレッドがある場合、クライアントのスレッドはキャッシュに入れられます。スレッドの要求は、可能であればキャッシュから取得したスレッドを再利用することで満たされ、キャッシュが空の場合にのみ新しいスレッドが作成されます。新しい接続がたくさんある場合は、この変数を増やしてパフォーマンスを向上させることができます。通常、適切なスレッド実装がある場合、これによってパフォーマンスが大幅に向上することはありません。ただし、サーバーが1秒間に数百の接続を検出する場合は、通常、ほとんどの新しい接続がキャッシュされたスレッドを使用するように、thread_cache_sizeを十分に高く設定する必要があります。 ConnectionsとThreads_createdのステータス変数の違いを調べることで、スレッドキャッシュの効率を確認できます。ドキュメントに記載されている式を使用すると、8 +(max_connections / 100)で十分です。
query_cache_size
一部のセットアップでは、この変数が最悪の敵です。高負荷が発生し、高読み取りでビジー状態になっている一部のシステムでは、この変数によって問題が発生します。 Perconaなどによって十分にテストされたベンチマークがあります。この変数をオフにするには、query_cache_type=0とともに0に設定する必要があります。 MySQL 8.0の良いニュースは、この変数が実際にパフォーマンスの問題を引き起こす可能性があるため、MySQLチームがこれをサポートしなくなったことです。パフォーマンスの予測可能性を改善する可能性は低いという彼らのブログに同意する必要があります。クエリキャッシングを使用する場合は、RedisまたはProxySQLを使用することをお勧めします。
ストレージエンジン-InnoDB
InnoDBは、外部キーサポート(宣言型参照整合性)とともに提供するさまざまな機能を備えたACID準拠のストレージエンジンです。これにはここで言うことがたくさんありますが、チューニングのために考慮すべき特定の変数:
innodb_buffer_pool_size
この変数はMyISAMのキーバッファーのように機能しますが、提供できるものがたくさんあります。 InnoDBはバッファープールに大きく依存しているため、この値を通常はサーバーのメモリの70%〜80%に設定することを検討してください。また、データセットよりもメモリスペースが大きく、バッファプールに高い値を設定することもできますが、あまり多くは設定しません。 ClusterControlでは、これはダッシュボード->InnoDBメトリック->InnoDBバッファープールページグラフを使用して監視できます。変数Innodb_buffer_pool_pages*を使用してSHOWGLOBALSTATUSでこれを監視することもできます。
innodb_buffer_pool_instances
同時実行ワークロードの場合、この変数を設定すると、同時実行性が向上し、キャッシュされたページへの読み取り/書き込みの異なるスレッドとしての競合を減らすことができます。最小のinnodb_buffer_pool_instancesは、1(最小)と64(最大)の間にある必要があります。バッファプールに格納されている、またはバッファプールから読み取られている各ページは、ハッシュ関数を使用して、バッファプールインスタンスの1つにランダムに割り当てられます。各バッファープールは、独自の空きリスト、フラッシュリスト、LRU、およびバッファープールに接続されている他のすべてのデータ構造を管理し、独自のバッファープールミューテックスによって保護されます。このオプションは、innodb_buffer_pool_size> =1GiBであり、そのサイズがバッファープールインスタンス間で分割されている場合にのみ有効になることに注意してください。
innodb_log_file_size
この変数は、ロググループ内のログファイルです。ログファイルの合計サイズ(innodb_log_file_size * innodb_log_files_in_group)は、512GBよりわずかに小さい最大値を超えることはできません。 Vadimによると、パフォーマンスにはログファイルのサイズが大きいほど優れていますが、クラッシュ後の回復時間という、心配する必要のある欠点(重大な欠点)があります。クラッシュリカバリのまれなイベントでのリカバリ時間と、ピーク操作中のスループットの最大化のバランスをとる必要があります。この制限は、クラッシュリカバリプロセスが20倍長くなる可能性があります!
それを詳しく説明すると、InnoDBトランザクションログには大きな値が適切であり、良好で安定した書き込みパフォーマンスにとって重要です。値が大きいほど、バッファプールで必要なチェックポイントフラッシュアクティビティが少なくなり、ディスクI/Oが節約されます。ただし、データベースが異常にシャットダウンされると(OOMまたは偶発的にクラッシュまたは強制終了)、回復プロセスはかなり遅くなります。理想的には、本番環境で1〜2GiBを使用できますが、もちろんこれを調整することもできます。この変更のベンチマークは、特にクラッシュ後のパフォーマンスを確認するための大きな利点になります。
innodb_log_buffer_size
ディスクI/Oを節約するために、InnoDBは変更データをltのログバッファーに書き込み、デフォルト値が8MiBのinnodb_log_buffer_sizeの値を使用します。これは、トランザクションをコミットする前に変更のログをディスクに書き込む必要がないため、特に大規模なトランザクションに役立ちます。書き込みトラフィックが多すぎる場合(挿入、削除、更新)、バッファを大きくするとディスクI/Oが節約されます。
innodb_flush_log_at_trx_commit
innodb_flush_log_at_trx_commitが1に設定されている場合、ログバッファーは、ディスク上のログファイルへのトランザクションコミットごとにフラッシュされ、最大のデータ整合性を提供しますが、パフォーマンスにも影響します。 2に設定すると、トランザクションがコミットされるたびにログバッファがOSファイルキャッシュにフラッシュされます。 2の意味は最適であり、ACID要件を緩和でき、OSがクラッシュした場合に、最後の1〜2秒間トランザクションを失う余裕があれば、パフォーマンスが向上します。
innodb_thread_concurrency
InnoDBエンジンの改善に伴い、エンジンがデフォルト値(ゼロ)に維持することで同時実行性を制御できるようにすることをお勧めします。同時実行の問題が発生した場合は、この変数を調整できます。推奨値は、CPUの数とディスクの数の2倍です。動的変数は、MySQLサーバーを再起動せずに設定できることを意味します。
innodb_flush_method
ただし、この変数は、どのハードウェアが最適かを試してテストする必要があります。バッテリバックアップ式キャッシュを備えたRAIDを使用している場合、DIRECT_IOはI/Oの負荷を軽減するのに役立ちます。ダイレクトI/Oはキャッシュされないため、バッファプールとファイルシステムキャッシュによる二重バッファリングを回避します。ディスクがSANに保存されている場合、ほとんどがSELECTステートメントを使用する読み取り負荷の高いワークロードでは、O_DSYNCの方が高速になる可能性があります。
innodb_file_per_table
innodb_file_per_tableは、MySQL5.6からデフォルトでオンになっています。これは、巨大な共有表領域を回避し、表を削除または切り捨てるときにスペースを再利用できるため、通常は推奨されます。個別のテーブルスペースは、Xtrabackupの部分バックアップスキームにもメリットがあります。
innodb_stats_on_metadata
これはダーティページの割合を制御下に維持しようとします。Innodbプラグインの前は、これがダーティバッファーのフラッシュを調整する唯一の方法でした。ただし、3%のダーティバッファを備えたサーバーを見たことがあり、それらは最大チェックポイント経過時間に達しています。これによりダーティバッファフラッシングが増加する方法も、高IOサブシステムでは適切に拡張できません。ダーティページの割合がこの量を超えると、1秒あたりのダーティバッファフラッシングが実質的に2倍になります。
innodb_io_capacity
この設定は、Innodbがすべての操作でIOをより有効に活用できるようになるという大きな期待にもかかわらず、1秒あたりのダーティページのフラッシュ(および先読みなどの他のバックグラウンドタスク)の量を制御するだけです。これを大きくすると、1秒あたりのフラッシュ量が増えます。これは適応しません。フラッシュするダーティバッファがある場合は、毎秒多くのIOPSを実行します。書き込みワークロードが十分に低い場合(つまり、ダーティページがほぼ即座にフラッシュされるため、この場合はトランザクションログがない方がよい場合があります)、IO統合の最適化を効果的に排除します。また、これを高く設定しすぎると、データの読み取りとトランザクションログへの書き込みがすぐに不足する可能性があります。
innodb_write_io_threads
ディスクへの書き込みが進行中のスレッドの数を制御します。 LinuxネイティブAIOを使用できるのに、なぜこれがまだ役立つのかわかりません。これらは、複数のスレッドによる同じファイルへの並列書き込みを許可しないファイルシステムによっても役に立たなくなる可能性があります(特に、テーブルが比較的少ない場合やグローバルテーブルスペースを使用している場合)
innodb_adaptive_flushing
ワークロードに基づいて、InnoDBバッファープール内のダーティページをフラッシュする速度を動的に調整するかどうかを指定します。フラッシュレートを動的に調整することは、I/Oアクティビティのバーストを回避することを目的としています。通常、これはデフォルトで有効になっています。この変数を有効にすると、ダーティページの数とトランザクションログの増加率に基づいて、より積極的にフラッシュすることを賢く試みます。
innodb_dedicated_server
この変数はMySQL8.0の新機能であり、グローバルに適用され、動的変数ではないため、MySQLを再起動する必要があります。ただし、ドキュメントに記載されているように、この変数は、MySQLが専用サーバーで実行されている場合にのみ有効にする必要があります。それ以外の場合は、共有ホストでこれを有効にしたり、システムリソースを他のアプリケーションと共有したりしないでください。これを有効にすると、InnoDBは、変数innodb_buffer_pool_size、innodb_log_file_size、innodb_flush_methodで検出されたメモリ量の自動構成を行います。唯一の欠点は、言及された検出された変数に希望の値を適用する可能性がないことです。
MyISAM
key_buffer_size
InnoDBは現在MySQLのデフォルトのストレージエンジンです。アプリケーションの一部としてMyISAMを生産的に使用している場合を除いて、key_buffer_sizeのデフォルトはおそらく減らすことができます(ただし、現在、MyISAMを本番環境で使用しているのは誰ですか?)。より大きなメモリがあり、残りのメモリをOSキャッシュとInnoDBバッファプール専用にする場合は、最初にRAMの1%または256MiBを設定することをお勧めします。
パフォーマンスに関するその他の規定
slow_query_log
もちろん、この変数はMySQLサーバーのブーストには役立ちません。ただし、この変数は、パフォーマンスの遅いクエリの分析に役立ちます。値を0またはOFFに設定して、ロギングを無効にすることができます。これを有効にするには、1またはONに設定します。デフォルト値は、-slow_query_logオプションが指定されているかどうかによって異なります。ログ出力の宛先は、log_outputシステム変数によって制御されます。その値がNONEの場合、ログが有効になっていてもログエントリは書き込まれません。変数slow_query_log_fileを設定することにより、クエリログファイルのファイル名または宛先を設定できます。
long_query_time
クエリにこの秒数より長くかかる場合、サーバーはSlow_queriesステータス変数をインクリメントします。低速クエリログが有効になっている場合、クエリは低速クエリログファイルに記録されます。この値はCPU時間ではなくリアルタイムで測定されるため、負荷の軽いシステムではしきい値を下回っているクエリは、負荷の高いシステムではしきい値を上回っている可能性があります。 long_query_timeの最小値とデフォルト値はそれぞれ0と10です。変数min_examined_row_limitが>0に設定されている場合、返される行数がmin_examined_row_limitに設定されている値より少ない場合は、時間がかかりすぎてもクエリはログに記録されないことにも注意してください。
低速クエリログの調整の詳細については、こちらのドキュメントを確認してください。
sync_binlog
この変数は、MySQLがbinlogをディスクに同期する頻度を制御します。デフォルト(> =5.7.7)では、これは1に設定されています。これは、トランザクションがコミットされる前にディスクに同期されることを意味します。ただし、これは書き込み数の増加によりパフォーマンスに悪影響を及ぼします。ただし、スレーブと一緒に厳密にACIDに準拠する必要がある場合は、これが最も安全な設定です。または、ディスクの同期を無効にし、OSに依存してバイナリログをディスクに時々フラッシュする場合は、これを0に設定できます。 1より大きく設定すると、N個のバイナリログコミットグループが収集された後、binlogがディスクに同期されます。ここでNは>1です。
バッファプールのダンプ/復元
コールドスタート/リスタートから本番データベースをウォームアップする必要があるのは、かなり一般的なことです。再起動する前に現在のバッファプールをダンプすることにより、バッファプールからコンテンツが保存され、起動すると、コンテンツがバッファプールにロードされます。したがって、データベースをウォームアップして戻す必要がなくなります。キャッシュ。このバージョンは5.6で導入されてからですが、念のため、PerconaServer5.5ではすでに利用可能になっていることに注意してください。この機能を有効にするには、変数innodb_buffer_pool_dump_at_shutdown=ONとinnodb_buffer_pool_load_at_startup=ONの両方を設定します。
ハードウェア
2019年になりましたが、多くの新しいハードウェアの改善がありました。通常、MySQLに特定のハードウェアが必要であるという厳しい要件はありませんが、これはデータベースで何をする必要があるかによって異なります。 Intel Pentium 200 MHzで動作するかどうかをテストしているため、このブログを読んでいないと思います。
CPUの場合、少なくとも5.6以降の最新バージョンでは、複数のコアを備えたより高速なプロセッサがMySQLに最適です。 IntelのXeon/Itaniumプロセッサは高価になる可能性がありますが、スケーラブルで信頼性の高いコンピューティングプラットフォームでテストされています。 Amazonは、ARMアーキテクチャで実行されているEC2インスタンスを出荷しています。私は個人的にARMアーキテクチャでMySQLを実行したり、実行したことを思い出したりしていませんが、何年も前に作成されたベンチマークがあります。最新のCPUは、温度、負荷、およびOSの省電力ポリシーに基づいて周波数を増減できます。ただし、LinuxOSのCPU設定が別のガバナーに設定されている可能性があります。次の手順を実行することで、それを確認したり、「パフォーマンス」ガバナーを設定したりできます。
echo performance | sudo tee /sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor
メモリの場合、メモリが大きく、データセットのサイズと同じになることが非常に重要です。 swappiness =1であることを確認してください。sysctlをチェックするか、procfsのファイルをチェックすることでチェックアウトできます。これは、次のことを行うことで実現されます。
$ sysctl -e vm.swappiness
vm.swappiness = 1
または、次のように値を1に設定します
$ sudo sysctl vm.swappiness=1
vm.swappiness = 1
メモリ管理で考慮すべきもう1つの優れた点は、THP(Transparrent Huge Pages)をオフにすることを検討することです。過去に、CPU使用率でいくつかの奇妙な問題が発生し、それがディスクI/Oが原因であると考えたことを思い出します。問題は、実行時にメモリを動的に割り当てるカーネルkhugepagedスレッドにあることが判明しました。これだけでなく、カーネルがデフラグを実行している間、メモリはTHPに渡されるときにすぐに割り当てられます。標準のHugePagesメモリは起動時に事前に割り当てられており、実行時に変更されません。これを確認して無効にするには、次の手順を実行します。
$ cat /sys/kernel/mm/transparent_hugepage/enabled
$ echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
ディスクの場合、スループットが良好であることが重要です。 RAID10の使用は、バッテリーバックアップユニットを備えたデータベースに最適なセットアップです。読み取り/書き込み用に高いディスクスループットと高いディスクI/Oを提供するフラッシュドライブの出現により、高いディスク使用率とディスクI/Oを管理できることが重要です。
オペレーティングシステム
MySQLで実行されているほとんどの実稼働システムはLinuxで実行されています。これは、MySQLがLinuxでテストおよびベンチマークされており、MySQLインストールのデファクトスタンダードであるように思われるためです。ただし、もちろん、UnixまたはWindowsプラットフォームでの使用を妨げるものは何もありません。プラットフォームがテストされていて、問題が発生した場合に役立つ幅広いコミュニティがあれば、より簡単になります。ほとんどのセットアップは、RHEL / Centos/FedoraおよびDebian/Ubuntuシステムで実行されます。 AWSでは、AmazonにはAmazon Linuxがあり、一部の人が本番環境で使用していると思います。
セットアップで考慮する最も重要なことは、ファイルシステムがXFSまたはExt4のいずれかを使用していることです。確かに、これら2つのファイルシステムには長所と短所がありますが、ここでは詳細については説明しません。 XFSがExt4よりも優れていると言う人もいますが、Ext4がXFSよりも優れているという報告もあります。 ZFSは、代替ファイルシステムの優れた候補としても登場しています。 Jervin Real(Perconaから)はこれに関する優れたリソースを持っています。ZFS会議中にこのプレゼンテーションを確認できます。
外部リンク
https://developer.okta.com/blog/2015/05/22/tcmalloc
https://www.percona.com/blog/2012/07/05/impact-of-memory-allocators-on-mysql-performance/
https://www.percona.com/live/18/sessions/benchmark-noise-reduction-how-to-configure-your-machines-for-stable-results
https://zfs.datto.com/2018_slides/real.pdf
https://docs.oracle.com/en/database/oracle/oracle-database/12.2/ladbi/disabling-transparent-hugepages.html#GUID-02E9147D-D565-4AF8-B12A-8E6E9F74BEEA