Amazon RDS for MySQL または MariaDB データベースで使用できるメモリが少ない問題を解決するにはどうすれば良いですか?

最終更新日: 2019 年 4 月 30 日

Amazon Relational Database Service (Amazon RDS) MariaDB または MySQL インスタンスを実行しています。使用可能なメモリが少ない、データベースのメモリが不足している、またはメモリが少ないためにアプリケーションでレイテンシー問題が発生しています。メモリ使用率の原因を特定するにはどうすれば良いですか? また、使用できるメモリが少ない問題を解決するにはどうすれば良いですか?

簡単な説明

MySQL はデータベース操作を実行するためにバッファとキャッシュを割り当てています。詳細については、MySQL によるメモリの使用方法に関する MySQL のドキュメントをご参照ください。Amazon RDS を使用している場合、インスタンスで利用可能なメモリの 80% から 90% がデフォルトのパラメータで割り当てられます。この割り当てはパフォーマンスには最適ですが、より多くのメモリを使用するパラメータを設定する場合は、他のパラメータを変更してより少ないメモリを使用するように補正してください。メモリを使用しているコンポーネントを特定したら、インスタンスおよびデータベースレベルでボトルネックを探すことができます。その後、最適なパフォーマンスが得られるようにセッションを設定できます。 

解決方法

MySQL によるメモリ使用の理解

グローバルなバッファとキャッシュには、Innodb_buffer_pool_sizeInnodb_log_buffer_sizekey_buffer_size、 および query_cache_size などのコンポーネントがあります。デフォルトでは、innodb_buffer_pool_size が RDS DB インスタンスメモリの 75% を使用します。最初にこのパラメータを確認して、メモリ使用量の原因を特定してください。それから、innodb_buffer_pool_size の値を減らすことを検討してください。たとえば、デフォルトの DBInstanceClassMemory*3/4 は* *5/8 または *1/2 に減らすことができます。インスタンスの BufferCacheHitRatio を調べて、比率が低すぎないことを確認してください。BufferCacheHitRatio が低い場合は、RAM を増やすためにインスタンスサイズを増やす必要があります。詳細については、「Amazon RDS for MySQL のパラメータを設定するためのベストプラクティス、パート 1: パフォーマンスに関するパラメータ」をご参照ください。

メモリは、MySQL DB インスタンスに接続されている各 MySQL スレッドにも割り当てられます。次のスレッドには割り当てられたメモリが必要です。

  • thread_stack
  • net_buffer_length
  • read_buffer_size
  • sort_buffer_size
  • join_buffer_size
  • max_heap_table_size
  • tmp_table_size

さらに、MySQL はいくつかの操作を実行するために内部一時テーブルを作成します。これらのテーブルは、最初はメモリベースのテーブルとして作成されます。これらのテーブルのサイズが tmp_table_size または max_heap_table_size で指定された値 (値が低い方) に達すると、テーブルはディスクベースのテーブルに変換されます。複数のセッションで内部一時テーブルを作成すると、メモリ使用率が増加することがあります。メモリ使用率を減らすために、クエリで一時テーブルを使用しないでください。

セッションが JOIN または SORT 操作を実行しているときに、join_buffer_size sort_buffer_size など、同じタイプの複数のバッファが割り当てられている場合も、メモリ使用率が増加することがあります。たとえば、MySQL は 2 つのテーブル間で JOIN を実行するために 1 つの JOIN バッファを割り当てます。クエリが複数テーブルの JOIN を含み、すべてのクエリが JOIN バッファを必要とする場合、MySQL は 1 つの JOIN バッファをテーブルの総数より少なく割り当てます。セッション変数を大きすぎる値に設定すると、クエリが最適化されていない場合に問題が発生する可能性があります。join_buffer_sizesort_buffer_size など、セッションレベルの変数に最小メモリを割り当てることができます。詳細については、「DB パラメータグループを使用する」をご参照ください。

MYISAM テーブルに一括挿入を実行すると、bulk_insert_buffer_size バイトのメモリを使用します。詳細については、「MySQL ストレージエンジンを使用するためのベストプラクティス」をご参照ください。

Amazon RDS for MySQL で Performance Insights のパフォーマンススキーマを有効にした場合、パフォーマンススキーマによってメモリが消費される可能性があります。パフォーマンススキーマが有効になっている場合、MySQL はインスタンスの起動時およびサーバー操作中に内部バッファを割り当てます。パフォーマンススキーマがメモリを使用する方法についての詳細は、パフォーマンススキーマのメモリ割り当てモデルに関する MySQL のドキュメントをご参照ください。

インスタンスのメモリ使用率におけるモニタリングとトラブルシューティング

使用可能なメモリが少ない場合は、DatabaseConnectionsCPUUtilizationReadIOPS、および WriteIOPSAmazon CloudWatch メトリクスをモニタリングします。メモリ負荷を確認するには、FreeableMemory に加えて SwapUsage の CloudWatch メトリクスをモニタリングします。大量のスワップが使用されていて FreeableMemory が低い場合は、DB インスタンスのメモリに負荷がかかっている可能性があるため、パフォーマンスが低下することがあります。詳細については、十分なメモリがあるのに Amazon RDS インスタンスがスワップメモリを使用するのはなぜですか?をご参照ください。

DB インスタンスのリソース使用率をモニタリングするには、拡張モニタリングを有効にします。次に、1 秒から 5 秒の詳細を設定します (デフォルトは 60 秒です)。

SHOW FULL PROCESSLIST を実行して、開いているすべての接続を確認します。次に、SHOW ENGINE INNODB STATUS を実行して、長時間実行するトランザクション、メモリ使用率統計、ロックなどの InnoDB 情報を確認します。BUFFER POOL AND MEMORY セクションで、空きページがあるかどうかを確認してください。

最後に、Performance Insights を有効にして、メモリを消費しているクエリを特定できるようにします。次に、FreeableMemory メトリクスに CloudWatch アラームを設定して、利用可能なメモリが減少したときに通知を受け取るようにします。少なくともインスタンスメモリの 5% を確保しておくことをお勧めします。使用率が 95% に達したときに通知する CloudWatch アラームを設定してください。

パフォーマンススキーマのメモリテーブルを使用して、メモリ使用率をモニタリングできます。また、単純化されたビューに MySQL sys スキーマを使用すると、パフォーマンススキーマテーブルと組み合わせて使用することもできます。たとえば、performance_schema イベントで、パフォーマンススキーマによって使用される内部バッファに割り当てられているメモリ量を表示できます。あるいは、次のようなクエリを実行して、割り当てられているメモリ量を確認することもできます。

SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE EVENT_NAME LIKE 'memory/performance_schema/%';

メモリ計器は setup_instruments テーブルに一覧表示されています。これらの計器には、memory/innodb/buf_buf_pool のように、memory/code_area/instrument_name に基づく名前が付けられています。メモリ計測を有効にするには、setup_instruments テーブルにある関連計器の ENABLED 列を更新してください。

UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'memory/%';

この記事はお役に立ちましたか?

改善できることはありますか?


さらにサポートが必要な場合