

# Amazon Aurora MySQL データベースのパフォーマンスのトラブルシューティング
<a name="aurora-mysql-troubleshooting"></a>

このトピックでは、Aurora MySQL DB の一般的なパフォーマンス問題と、これらの問題を迅速に修正するためのトラブルシューティング方法または情報収集方法に焦点を当てます。データベースのパフォーマンスを次の 2 つのカテゴリに分類します。
+ サーバーパフォーマンス — データベースサーバー全体の動作が遅い。
+ クエリパフォーマンス — 1 つまたは複数のクエリの実行に時間がかかる。

## AWS モニタリングオプション
<a name="aurora-mysql-troubleshooting.monitoring"></a>

トラブルシューティングに役立てるため、次の AWS モニタリングオプションを使用することをお勧めします。
+ Amazon CloudWatch — Amazon CloudWatch は AWS で実行されている AWS リソースやアプリケーションをリアルタイムにモニタリングします。CloudWatch を使用してメトリクスを収集および追跡できます。メトリクスとは、リソースやアプリケーションについて測定できる変数です。詳細については、「[Amazon CloudWatch とは](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html)」を参照してください。

  DB インスタンスのすべてのシステムメトリクスとプロセス情報を AWS マネジメントコンソール に表示できます。Aurora MySQL DB クラスターを設定して、全般ログ、スローログ、監査ログおよびエラーログのデータを Amazon CloudWatch Logs のロググループに発行できます。これにより、傾向を確認したり、ホストが影響を受けた場合にログを維持したり、異常や変化を簡単に特定するための「通常の」パフォーマンスのベースラインを作成することができます。詳細については、「[Amazon CloudWatch Logs への Amazon Aurora MySQL ログの発行](AuroraMySQL.Integrating.CloudWatch.md)」を参照してください。
+ 拡張モニタリング — Aurora MySQL データベースに対して追加の Amazon CloudWatch メトリクスを有効にするには、拡張モニタリングを有効にします。Aurora DB クラスターを作成または変更するときは、**[拡張モニタリングを有効化**] を選択します。これにより、Aurora はパフォーマンスメトリクスを CloudWatch にパブリッシュできます。利用可能な主なメトリクスには、CPU 使用率、データベース接続、ストレージ使用量、クエリレイテンシーなどがあります。これらはパフォーマンスのボトルネックの特定に役立ちます。

  DB インスタンスに対して転送される情報量は、拡張モニタリング機能に対して定義された詳細度に正比例します。モニタリング間隔を短くすると、OS メトリクスのレポート回数が増え、モニタリングコストが高くなります。コストを管理するには、AWS アカウント 内のインスタンスごとに異なる詳細度を設定します。インスタンス作成時のデフォルトの精度は 60 秒です。詳細については、「[拡張モニタリングのコスト](USER_Monitoring.OS.md#USER_Monitoring.OS.cost)」を参照してください。
+ Performance Insights — すべてのデータベースコールメトリクスを表示できます。これには DB ロック、待機、処理された行数などがあり、これらはすべてトラブルシューティングに使用できます。Aurora DB クラスターを作成または変更するときは、**[Performance Insights を有効にする]** を選択します。デフォルトでは、Performance Insights のデータ保持期間は 7 日間ですが、長期的なパフォーマンスの傾向を分析するようにカスタマイズできます。7 日を超える保存期間については、有料プランにアップグレードする必要があります。詳細については、「[Performance Insights の料金](https://aws.amazon.com/rds/performance-insights/pricing/)」を参照してください。Aurora DB インスタンスごとにデータ保持期間を個別に設定できます。詳細については、「[Amazon Aurora での Performance Insights を使用したDB 負荷のモニタリング](USER_PerfInsights.md)」を参照してください。

## Aurora MySQL データベースのパフォーマンス問題の最も一般的な原因
<a name="aurora-mysql-troubleshooting-common"></a>

次の手順を使用して、Aurora MySQL データベースのパフォーマンス問題をトラブルシューティングできます。これらのステップは調査の論理的な順序で示していますが、直線的なものではありません。1 つの発見が複数のステップにまたがることもあり、それによって一連の調査パスが提供されます。

1. [ワークロード](aurora-mysql-troubleshooting-workload.md) — データベースのワークロードを理解します。

1. [ログ記録](aurora-mysql-troubleshooting-logging.md) — すべてのデータベースログを確認します。

1. [データベース接続 ](mysql-troubleshooting-dbconn.md) — アプリケーションとデータベース間の接続が信頼できることを確認します。

1. [クエリパフォーマンス](aurora-mysql-troubleshooting-query.md) — クエリ実行プランが変更されていないか確認します。コードを変更すると、プランが変更される可能性があります。

# Aurora MySQL データベースのワークロードに関する問題のトラブルシューティング
<a name="aurora-mysql-troubleshooting-workload"></a>

データベースワークロードは読み取りおよび書き込みとして見なすことができます。「通常の」データベースワークロードを理解していれば、需要の変化に合わせてクエリとデータベースサーバーを調整できます。パフォーマンスが変化する理由は多く存在するため、最初のステップは何が変わったのかを理解することです。
+ メジャーバージョンまたはマイナーバージョンのアップグレードは行われましたか?

  メジャーバージョンアップグレードには、エンジンコード、特にオプティマイザの変更が含まれ、それによってクエリ実行プランが変更される可能性があります。データベースバージョン、特にメジャーバージョンをアップグレードするときは、データベースのワークロードを分析し、それに応じて調整することが非常に重要です。調整には、テストの結果に応じて、クエリの最適化と書き換え、またはパラメータ設定の追加と更新が含まれる場合があります。何が影響を引き起こしているのかを理解することで、その特定の分野に集中できるようになります。

  詳細については、MySQL ドキュメントの「[MySQL 8.0 の新機能](https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html)」と「[MySQL 8.0 で追加、廃止、または削除されたサーバー変数とステータス変数とオプション](https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html)」、および「[Aurora MySQL バージョン 2 と Aurora MySQL バージョン 3 の比較](AuroraMySQL.Compare-v2-v3.md)」を参照してください。
+ 処理中のデータ (行数) は増加しましたか?
+ 同時に実行されているクエリは他にもありますか?
+ スキーマやデータベースに変更はありますか?
+ コードに欠陥や修正はありましたか?

**Contents**
+ [インスタンスホストｘメトリクス](#ams-workload-instance)
  + [CPU の使用](#ams-workload-cpu)
  + [メモリ使用量](#ams-workload-instance-memory)
  + [ネットワークスループット](#ams-workload-network)
+ [データベースメトリクス](#ams-workload-db)
+ [Aurora MySQL データベースのメモリ使用量に関する問題のトラブルシューティング](ams-workload-memory.md)
  + [例 1: 連続的に高いメモリ使用量](ams-workload-memory.md#ams-workload-memory.example1)
  + [例 2: 一時的なメモリスパイク](ams-workload-memory.md#ams-workload-memory.example2)
  + [例 3: 解放可能なメモリが継続的に減少し、再利用されない](ams-workload-memory.md#ams-workload-memory.example3)
+ [Aurora MySQL データベースのメモリ不足の問題のトラブルシューティング](AuroraMySQLOOM.md)

## インスタンスホストｘメトリクス
<a name="ams-workload-instance"></a>

CPU、メモリ、ネットワークアクティビティなどのインスタンスホストのメトリクスをモニタリングして、ワークロードが変更されたかどうかを把握します。ワークロードの変化を理解するには、主に 2 つの概念があります。
+ 使用率 — CPU やディスクなどのデバイスの使用状況。時間ベースの場合とキャパシティベースの場合があります。
  + 時間ベース — 特定の観測期間にリソースがビジー状態である時間です。
  + キャパシティベース — システムまたはコンポーネントが提供できるスループットの量 (キャパシティに対する割合)。
+ 飽和度 — リソースで処理できる量よりも多くの作業が必要となる度合い。キャパシティベースの使用率が 100% に達すると、余分な作業は処理できなくなり、キューに入れる必要があります。

### CPU の使用
<a name="ams-workload-cpu"></a>

次のツールを使用して、CPU の使用状況と飽和度を識別できます。
+ CloudWatch が `CPUUtilization` メトリクスを提供します。この値が 100% に達すると、インスタンスは飽和状態になります。ただし、CloudWatch メトリクスは 1 分間で平均化され、詳細さに欠けています。

  CloudWatch のメトリクスの詳細については、「[Amazon Aurora のインスタンスレベルのメトリクス](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)」を参照してください。
+ 拡張モニタリングは、オペレーティングシステム `top` コマンドによって返されるメトリクスを提供します。負荷平均と次の CPU 状態が 1 秒単位で表示されます。
  + `Idle (%)` = アイドル時間
  + `IRQ (%)` = ソフトウェア割り込み
  + `Nice (%)` = 優先順位が [niced](https://en.wikipedia.org/wiki/Nice_(Unix)) のプロセスの良好な時間。
  + `Steal (%)` = 他のテナントへのサービス提供に費やした時間 (仮想化関連)
  + `System (%)` = システム時刻
  + `User (%)` = ユーザー時間
  + `Wait (%)` = I/O 待機

  拡張モニタリングのメトリクスの詳細については、「[Aurora の OS メトリクス](USER_Monitoring-Available-OS-Metrics.md#USER_Monitoring-Available-OS-Metrics-RDS)」を参照してください。

### メモリ使用量
<a name="ams-workload-instance-memory"></a>

システムがメモリ不足に陥っていて、リソース消費が飽和状態に達しつつある場合は、ページスキャン、ページング、スワップ、メモリ不足などのエラーが頻繁に発生しているはずです。

次のツールを使用して、メモリの使用状況と飽和度を識別できます。

CloudWatch は、一部の OS キャッシュと現在の空きメモリをフラッシュすることで再利用できるメモリを示す `FreeableMemory` メトリクスを提供します。

CloudWatch のメトリクスの詳細については、「[Amazon Aurora のインスタンスレベルのメトリクス](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)」を参照してください。

拡張モニタリングでは、メモリ使用量の問題を特定するのに役立つ以下のメトリクスが提供されます。
+ `Buffers (KB)` - ストレージデバイスへの書き込み前に I/O バッファリングリクエストに使用されたメモリの量 (キロバイト単位)。
+ `Cached (KB)` - ファイルシステムベースの I/O のキャッシュに使用されたメモリの量。
+ `Free (KB)` - 未割り当てのメモリの量 (キロバイト単位)。
+ `Swap` - キャッシュ、フリー、および合計。

例えば、DB インスタンスが `Swap` メモリを使用していることがわかった場合、ワークロードの合計メモリ量は、インスタンスで現在使用可能なメモリ量よりも多くなっています。DB インスタンスのサイズを増やすか、使用するメモリ量が少なくなるようにワークロードを調整することをお勧めします。

拡張モニタリングのメトリクスの詳細については、「[Aurora の OS メトリクス](USER_Monitoring-Available-OS-Metrics.md#USER_Monitoring-Available-OS-Metrics-RDS)」を参照してください。

パフォーマンススキーマと `sys` スキーマを使用して、どの接続やコンポーネントがメモリを使用しているかを見極める方法の詳細については、「[Aurora MySQL データベースのメモリ使用量に関する問題のトラブルシューティング](ams-workload-memory.md)」を参照してください。

### ネットワークスループット
<a name="ams-workload-network"></a>

CloudWatch は、ネットワークスループットの合計について、すべて 1 分間の平均値として次のメトリクスを提供します。
+ `NetworkReceiveThroughput` - Aurora DB クラスター内の各インスタンスが各クライアントから受信したネットワークスループットの量。
+ `NetworkTransmitThroughput` - Aurora DB クラスター内の各インスタンスが各クライアントに対して送信したネットワークスループットの量。
+ `NetworkThroughput` - Aurora DB クラスター内の各インスタンスが各クライアントで送受信したネットワークスループットの量。
+ `StorageNetworkReceiveThroughput` - DB クラスター内の各インスタンスが、Aurora のストレージサブシステムから受信した、ネットワークスループットの量。
+ `StorageNetworkTransmitThroughput` - Aurora DB クラスター内の各インスタンスが、Aurora のストレージサブシステムに送信した、ネットワークスループットの量。
+ `StorageNetworkThroughput` - Aurora DB クラスター内の各インスタンスが、Aurora のストレージサブシステムとの間で送受信した、ネットワークスループットの量。

CloudWatch のメトリクスの詳細については、「[Amazon Aurora のインスタンスレベルのメトリクス](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)」を参照してください。

拡張モニタリングでは、`network` が受信した (**RX**) および送信した (**TX**) グラフが最大 1 秒の精度で表示されます。

拡張モニタリングのメトリクスの詳細については、「[Aurora の OS メトリクス](USER_Monitoring-Available-OS-Metrics.md#USER_Monitoring-Available-OS-Metrics-RDS)」を参照してください。

## データベースメトリクス
<a name="ams-workload-db"></a>

以下の CloudWatch メトリクスを調べて、ワークロードの変化を確認します。
+ `BlockedTransactions` - 1 秒あたりのブロックされたデータベース内のトランザクションの平均数。
+ `BufferCacheHitRatio` – バッファキャッシュから提供されたリクエストの割合 (パーセント)。
+ `CommitThroughput` - 1 秒あたりのコミット操作の平均回数。
+ `DatabaseConnections` - データベースインスタンスへのクライアントネットワーク接続の数。
+ `Deadlocks` - 1 秒あたりのデータベース内のデッドロックの平均回数。
+ `DMLThroughput` - 1 秒あたりの挿入、更新、削除の平均回数。
+ `ResultSetCacheHitRatio` - クエリキャッシュから提供されたリクエストの割合 (パーセント)。
+ `RollbackSegmentHistoryListLength` - コミットされたトランザクションが削除とマークされたレコードを記録する UNDO ログ。
+ `RowLockTime` - InnoDB テーブルのローロックの取得にかかった合計時間。
+ `SelectThroughput` - 1 秒あたりの選択クエリの平均回数。

CloudWatch のメトリクスの詳細については、「[Amazon Aurora のインスタンスレベルのメトリクス](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)」を参照してください。

ワークロードを調べる際には、以下の点を考慮してください。

1. DB インスタンスクラスに最近変更があったか。例えば、インスタンスサイズを 8xlarge から 4xlarge に減らしたり、db.r5 から db.r6 に変更したりしたか？ 

1. クローンを作成して問題を再現できますか? それとも 1 つのインスタンスでのみ発生していますか?

1. サーバーリソースの消耗、CPU 使用率の上昇、またはメモリの消耗は発生していますか? 「はい」の場合は、ハードウェアの追加が必要な場合があります。

1. 1 つまたは複数のクエリに時間がかかりますか?

1. 変化の原因はアップグレード、特にメジャーバージョンアップグレードですか? 「はい」の場合は、アップグレード前とアップグレード後のメトリクスを比較してください。

1. リーダー DB インスタンスの数に変更はありますか?

1. 一般ロギング、監査ロギング、またはバイナリロギングを有効にしましたか? 詳細については、「[Aurora MySQL データベースのログ記録](aurora-mysql-troubleshooting-logging.md)」を参照してください。

1. バイナリログ (binlog) レプリケーションの使用を有効化、無効化、または変更しましたか?

1. 長時間実行されるトランザクションで、多数の行ロックが発生していませんか? InnoDB 履歴リストの長さ (HLL) を調べて、トランザクションが長時間実行されているかどうかを確認してください。

   詳細については、「[InnoDB 履歴リストの長さが大幅に増加しました](proactive-insights.history-list.md)」および「[Amazon Aurora MySQL DB クラスターで SELECT クエリの実行が遅いのはなぜですか?](https://repost.aws/knowledge-center/aurora-mysql-slow-select-query)」というブログ記事を参照してください。

   1. 書き込みトランザクションが原因で HLL が大きくなっている場合は、`UNDO` ログが蓄積されている (定期的にクリーンアップされていない) ことを意味します。書き込みトランザクションが多いと、この蓄積が急速に増加する可能性があります。MySQL では、`UNDO` は [SYSTEM テーブルスペース](https://dev.mysql.com/doc/refman/5.7/en/innodb-system-tablespace.html)に保存されます。`SYSTEM` テーブルスペースは圧縮できません。`UNDO` ログにより、`SYSTEM` テーブルスペースが数 GB、さらには TB にまで増えることもあります。削除後、データの論理バックアップ (ダンプ) を作成して割り当てられたスペースを解放し、そのダンプを新しい DB インスタンスにインポートします。

   1. 読み取りトランザクション (実行時間の長いクエリ) が原因で HLL が大きくなっている場合は、クエリが大量の一時スペースを使用している可能性があります。再起動して一時スペースを解放します。`Temp` セクションで Performance Insights の DB メトリクスに変更 (`created_tmp_tables` など) がないかを調べます。詳細については、「[Amazon Aurora での Performance Insights を使用したDB 負荷のモニタリング](USER_PerfInsights.md)」を参照してください。

1. 長時間実行されるトランザクションを、変更される行数が少ないより小さなトランザクションに分割できますか?

1. ブロックされたトランザクションの変化やデッドロックの増加はありませんか? `Locks` セクションで Performance Insights の DB メトリクスにステータス変数の変更 (`innodb_row_lock_time`、` innodb_row_lock_waits`、および ` innodb_dead_locks` など) がないかを調べます。1 分または 5 分間隔を使用します。

1. 増加した待機イベントがあるか？ Performance Insights の待機イベントと待機タイプを 1 分または 5 分間隔で調べます。上位の待機イベントを分析し、それらがワークロードの変化やデータベースの競合と相関関係があるかどうかを確認します。例えば、`buf_pool mutex` はバッファプールの競合を示しています。詳細については、「[待機イベントを使用した Aurora MySQL のチューニング](AuroraMySQL.Managing.Tuning.wait-events.md)」を参照してください。

# Aurora MySQL データベースのメモリ使用量に関する問題のトラブルシューティング
<a name="ams-workload-memory"></a>

CloudWatch、拡張モニタリング、Performance Insights は、オペレーティングシステムレベルでのメモリ使用量 (データベースプロセスによるメモリ使用量など) の概要を提供しますが、エンジン内の接続やコンポーネント別のメモリ使用量を詳しく知ることはできません。

このトラブルシューティングには、パフォーマンススキーマと `sys` スキーマを使用できます。Aurora MySQL バージョン 3 では、パフォーマンススキーマを有効にすると、追加の計測がデフォルトで有効になります。Aurora MySQL バージョン 2 では、パフォーマンススキーマのメモリ使用量の計測のみがデフォルトで有効になります。パフォーマンススキーマでメモリ使用量を追跡するために使用できるテーブルと、パフォーマンススキーマのメモリ計測の有効化の詳細については、MySQL ドキュメントの「[Memory summary tables](https://dev.mysql.com/doc/refman/8.3/en/performance-schema-memory-summary-tables.html)」を参照してください。パフォーマンススキーマと Performance Insights の詳細については、「[Aurora MySQL における Performance Insights のPerformance Schema の概要](USER_PerfInsights.EnableMySQL.md)」を参照してください。

パフォーマンススキーマでは、現在のメモリ使用量を追跡するための詳細情報を参照できます。一方、MySQL の [sys スキーマ](https://dev.mysql.com/doc/refman/8.0/en/sys-schema.html)では、パフォーマンススキーマテーブルの上部のビューで、どこでメモリが使用されているかをすばやく特定できます。

`sys` スキーマには、接続、コンポーネント、クエリ別にメモリ使用量を追跡できる以下のビューがあります。


| ビュー | 説明 | 
| --- | --- | 
|  [memory\$1by\$1host\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-host-by-current-bytes.html)  |  ホスト別にエンジンメモリ使用量に関する情報を表示します。どのアプリケーションサーバーまたはクライアントホストがメモリを消費しているかを特定するのに役立ちます。  | 
|  [memory\$1by\$1thread\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-thread-by-current-bytes.html)  |  スレッド ID 別にエンジンメモリ使用量に関する情報を表示します。MySQL のスレッド ID は、クライアント接続またはバックグラウンドスレッドである場合があります。[sys.processlist](https://dev.mysql.com/doc/refman/8.0/en/sys-processlist.html) ビューまたは [performance\$1schema.threads](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-threads-table.html) テーブルを使用して、スレッド ID を MySQL 接続 ID にマッピングできます。  | 
|  [memory\$1by\$1user\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-user-by-current-bytes.html)  |  ユーザー別のエンジンメモリ使用量に関する情報を表示します。どのユーザーアカウントまたはクライアントがメモリを消費しているかを特定するのに役立ちます。  | 
|  [memory\$1global\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-global-by-current-bytes.html)  |  エンジンコンポーネント別のエンジンメモリ使用量に関する情報を表示します。エンジンバッファまたはコンポーネント別にメモリ使用量をグローバルに特定するのに役立ちます。例えば、InnoDB バッファプールの `memory/innodb/buf_buf_pool` イベントやプリペアドステートメントの `memory/sql/Prepared_statement::main_mem_root` イベントが表示される場合があります。  | 
|  [memory\$1global\$1total](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-global-total.html)  |  データベースエンジンで追跡している合計メモリ使用量の概要を表示します。  | 

Aurora MySQL バージョン 3.05 以降では、[パフォーマンススキーマのステートメント概要テーブル](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html)でステートメントダイジェスト別の最大メモリ使用量を追跡することもできます。ステートメント概要テーブルには、正規化されたステートメントダイジェストとその実行に関する集約統計が表示されます。`MAX_TOTAL_MEMORY` 列は、統計の最後のリセット後またはデータベースインスタンスの再起動後の最大メモリ使用量をクエリダイジェスト別に特定するのに利用できます。大量のメモリを消費している可能性がある特定のクエリを特定するのに役立ちます。

**注記**  
パフォーマンススキーマと `sys` スキーマには、サーバーの現在のメモリ使用量と、接続およびエンジンコンポーネント別のメモリ使用量のハイウォーターマークが表示されます。パフォーマンススキーマはメモリ内に保持されるため、DB インスタンスを再起動すると情報がリセットされます。履歴を長期にわたって保持するには、このデータの取得と保存をパフォーマンススキーマの外部に設定することをお勧めします。

**Topics**
+ [例 1: 連続的に高いメモリ使用量](#ams-workload-memory.example1)
+ [例 2: 一時的なメモリスパイク](#ams-workload-memory.example2)
+ [例 3: 解放可能なメモリが継続的に減少し、再利用されない](#ams-workload-memory.example3)

## 例 1: 連続的に高いメモリ使用量
<a name="ams-workload-memory.example1"></a>

CloudWatch の `FreeableMemory` を概観すると、2024-03-26 02:59 UTC にメモリ使用量の大幅増を確認できます。

![\[高いメモリ使用量を示す FreeableMemory グラフ。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/images/ams-freeable-memory.png)


このグラフでは、詳細がわかりません。どのコンポーネントのメモリ使用量が最も多いかを判断するには、データベースにログインして `sys.memory_global_by_current_bytes` を確認できます。このテーブルには、MySQL が追跡するメモリイベントのリストと、イベント別のメモリ割り当てに関する情報が表示されます。各メモリ追跡イベントは `memory/%` で始まり、その後にイベントに関連するエンジンコンポーネントや機能に関する他の情報が続きます。

例えば、`memory/performance_schema/%` はパフォーマンススキーマに関連するメモリイベントであり、`memory/innodb/%` は InnoDB に関連するイベントです。イベントの命名規則の詳細については、MySQL ドキュメントの「[Performance Schema instrument naming conventions](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-instrument-naming.html)」を参照してください。

次のクエリから、`current_alloc` に基づいて有力な原因を確認できますが、`memory/performance_schema/%` イベントも多数あることがわかります。

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                                                  | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root                                |        512817 | 4.91 GiB      | 10.04 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
| memory/performance_schema/prepared_statements_instances                     |           252 | 488.25 MiB    | 1.94 MiB          |        252 | 488.25 MiB | 1.94 MiB       |
| memory/innodb/hash0hash                                                     |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/performance_schema/events_errors_summary_by_thread_by_error          |          1028 | 52.27 MiB     | 52.06 KiB         |       1028 | 52.27 MiB  | 52.06 KiB      |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name |             4 | 47.25 MiB     | 11.81 MiB         |          4 | 47.25 MiB  | 11.81 MiB      |
| memory/performance_schema/events_statements_summary_by_digest               |             1 | 40.28 MiB     | 40.28 MiB         |          1 | 40.28 MiB  | 40.28 MiB      |
| memory/performance_schema/memory_summary_by_thread_by_event_name            |             4 | 31.64 MiB     | 7.91 MiB          |          4 | 31.64 MiB  | 7.91 MiB       |
| memory/innodb/memory                                                        |         15227 | 27.44 MiB     | 1.85 KiB          |      20619 | 33.33 MiB  | 1.66 KiB       |
| memory/sql/String::value                                                    |         74411 | 21.85 MiB     |  307 bytes        |      76867 | 25.54 MiB  |  348 bytes     |
| memory/sql/TABLE                                                            |          8381 | 21.03 MiB     | 2.57 KiB          |       8381 | 21.03 MiB  | 2.57 KiB       |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.02 sec)
```

パフォーマンススキーマはメモリに保存されることを以前に説明しました。つまり、パフォーマンススキーマも `performance_schema` メモリ計測で追跡されます。

**注記**  
パフォーマンススキーマが大量のメモリを使用していることがわかった場合、そのメモリ使用量を制限するには、要件に応じてデータベースパラメータを調整できます。詳細については、MySQL ドキュメントの「[The Performance Schema memory-allocation model](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-memory-model.html)」を参照してください。

見やすくするために、パフォーマンススキーマイベントを除外して同じクエリを再実行できます。出力は、次のように表示されます。
+ メモリ使用量が多いのは `memory/sql/Prepared_statement::main_mem_root` です。
+ `current_alloc` 列を見ると、MySQL では、このイベントに現在 4.91 GiB が割り当てられていることがわかります。
+ `high_alloc column` によると、4.91 GiB は、統計の最後のリセット後またはサーバーの再起動後からの `current_alloc` のハイウォーターマークであることがわかります。つまり、`memory/sql/Prepared_statement::main_mem_root` は最高値になっています。

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name NOT LIKE 'memory/performance_schema/%' LIMIT 10;

+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                    | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root  |        512817 | 4.91 GiB      | 10.04 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
| memory/innodb/hash0hash                       |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/innodb/memory                          |         17096 | 31.68 MiB     | 1.90 KiB          |      22498 | 37.60 MiB  | 1.71 KiB       |
| memory/sql/String::value                      |        122277 | 27.94 MiB     |  239 bytes        |     124699 | 29.47 MiB  |  247 bytes     |
| memory/sql/TABLE                              |          9927 | 24.67 MiB     | 2.55 KiB          |       9929 | 24.68 MiB  | 2.55 KiB       |
| memory/innodb/lock0lock                       |          8888 | 19.71 MiB     | 2.27 KiB          |       8888 | 19.71 MiB  | 2.27 KiB       |
| memory/sql/Prepared_statement::infrastructure |        257623 | 16.24 MiB     |   66 bytes        |     257631 | 16.24 MiB  |   66 bytes     |
| memory/mysys/KEY_CACHE                        |             3 | 16.00 MiB     | 5.33 MiB          |          3 | 16.00 MiB  | 5.33 MiB       |
| memory/innodb/sync0arr                        |             3 | 7.03 MiB      | 2.34 MiB          |          3 | 7.03 MiB   | 2.34 MiB       |
| memory/sql/THD::main_mem_root                 |           815 | 6.56 MiB      | 8.24 KiB          |        849 | 7.19 MiB   | 8.67 KiB       |
+-----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.06 sec)
```

イベントの名前から、このメモリはプリペアドステートメントに使用されていることがわかります。このメモリを使用している接続を確認したい場合は、[memory\$1by\$1thread\$1by\$1current\$1bytes](https://dev.mysql.com/doc/refman/8.0/en/sys-memory-by-thread-by-current-bytes.html) を参照できます。

次の例では、各接続に約 7 MiB が割り当てられ、ハイウォーターマークは約 6.29 MiB (`current_max_alloc`) です。この例では、プリペアドステートメントで 80 のテーブルと 800 の接続に `sysbench` を使用しているため、これは当然と言えます。このシナリオでメモリ使用量を減らしたい場合は、アプリケーションによるプリペアドステートメントの使用を最適化してメモリ消費量を削減できます。

```
mysql> SELECT * FROM sys.memory_by_thread_by_current_bytes;

+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
| thread_id | user                                      | current_count_used | current_allocated | current_avg_alloc | current_max_alloc | total_allocated |
+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
|        46 | rdsadmin@localhost                        |                405 | 8.47 MiB          | 21.42 KiB         | 8.00 MiB          | 155.86 MiB      |
|        61 | reinvent@10.0.4.4                         |               1749 | 6.72 MiB          | 3.93 KiB          | 6.29 MiB          | 14.24 MiB       |
|       101 | reinvent@10.0.4.4                         |               1845 | 6.71 MiB          | 3.72 KiB          | 6.29 MiB          | 14.50 MiB       |
|        55 | reinvent@10.0.4.4                         |               1674 | 6.68 MiB          | 4.09 KiB          | 6.29 MiB          | 14.13 MiB       |
|        57 | reinvent@10.0.4.4                         |               1416 | 6.66 MiB          | 4.82 KiB          | 6.29 MiB          | 13.52 MiB       |
|       112 | reinvent@10.0.4.4                         |               1759 | 6.66 MiB          | 3.88 KiB          | 6.29 MiB          | 14.17 MiB       |
|        66 | reinvent@10.0.4.4                         |               1428 | 6.64 MiB          | 4.76 KiB          | 6.29 MiB          | 13.47 MiB       |
|        75 | reinvent@10.0.4.4                         |               1389 | 6.62 MiB          | 4.88 KiB          | 6.29 MiB          | 13.40 MiB       |
|       116 | reinvent@10.0.4.4                         |               1333 | 6.61 MiB          | 5.08 KiB          | 6.29 MiB          | 13.21 MiB       |
|        90 | reinvent@10.0.4.4                         |               1448 | 6.59 MiB          | 4.66 KiB          | 6.29 MiB          | 13.58 MiB       |
|        98 | reinvent@10.0.4.4                         |               1440 | 6.57 MiB          | 4.67 KiB          | 6.29 MiB          | 13.52 MiB       |
|        94 | reinvent@10.0.4.4                         |               1433 | 6.57 MiB          | 4.69 KiB          | 6.29 MiB          | 13.49 MiB       |
|        62 | reinvent@10.0.4.4                         |               1323 | 6.55 MiB          | 5.07 KiB          | 6.29 MiB          | 13.48 MiB       |
|        87 | reinvent@10.0.4.4                         |               1323 | 6.55 MiB          | 5.07 KiB          | 6.29 MiB          | 13.25 MiB       |
|        99 | reinvent@10.0.4.4                         |               1346 | 6.54 MiB          | 4.98 KiB          | 6.29 MiB          | 13.24 MiB       |
|       105 | reinvent@10.0.4.4                         |               1347 | 6.54 MiB          | 4.97 KiB          | 6.29 MiB          | 13.34 MiB       |
|        73 | reinvent@10.0.4.4                         |               1335 | 6.54 MiB          | 5.02 KiB          | 6.29 MiB          | 13.23 MiB       |
|        54 | reinvent@10.0.4.4                         |               1510 | 6.53 MiB          | 4.43 KiB          | 6.29 MiB          | 13.49 MiB       |
.                                                                                                                                                          .
.                                                                                                                                                          .
.                                                                                                                                                          .
|       812 | reinvent@10.0.4.4                         |               1259 | 6.38 MiB          | 5.19 KiB          | 6.29 MiB          | 13.05 MiB       |
|       214 | reinvent@10.0.4.4                         |               1279 | 6.38 MiB          | 5.10 KiB          | 6.29 MiB          | 12.90 MiB       |
|       325 | reinvent@10.0.4.4                         |               1254 | 6.38 MiB          | 5.21 KiB          | 6.29 MiB          | 12.99 MiB       |
|       705 | reinvent@10.0.4.4                         |               1273 | 6.37 MiB          | 5.13 KiB          | 6.29 MiB          | 13.03 MiB       |
|       530 | reinvent@10.0.4.4                         |               1268 | 6.37 MiB          | 5.15 KiB          | 6.29 MiB          | 12.92 MiB       |
|       307 | reinvent@10.0.4.4                         |               1263 | 6.37 MiB          | 5.17 KiB          | 6.29 MiB          | 12.87 MiB       |
|       738 | reinvent@10.0.4.4                         |               1260 | 6.37 MiB          | 5.18 KiB          | 6.29 MiB          | 13.00 MiB       |
|       819 | reinvent@10.0.4.4                         |               1252 | 6.37 MiB          | 5.21 KiB          | 6.29 MiB          | 13.01 MiB       |
|        31 | innodb/srv_purge_thread                   |              17810 | 3.14 MiB          |  184 bytes        | 2.40 MiB          | 205.69 MiB      |
|        38 | rdsadmin@localhost                        |                599 | 1.76 MiB          | 3.01 KiB          | 1.00 MiB          | 25.58 MiB       |
|         1 | sql/main                                  |               3756 | 1.32 MiB          |  367 bytes        | 355.78 KiB        | 6.19 MiB        |
|       854 | rdsadmin@localhost                        |                 46 | 1.08 MiB          | 23.98 KiB         | 1.00 MiB          | 5.10 MiB        |
|        30 | innodb/clone_gtid_thread                  |               1596 | 573.14 KiB        |  367 bytes        | 254.91 KiB        | 970.69 KiB      |
|        40 | rdsadmin@localhost                        |                235 | 245.19 KiB        | 1.04 KiB          | 128.88 KiB        | 808.64 KiB      |
|       853 | rdsadmin@localhost                        |                 96 | 94.63 KiB         | 1009 bytes        | 29.73 KiB         | 422.45 KiB      |
|        36 | rdsadmin@localhost                        |                 33 | 36.29 KiB         | 1.10 KiB          | 16.08 KiB         | 74.15 MiB       |
|        33 | sql/event_scheduler                       |                  3 | 16.27 KiB         | 5.42 KiB          | 16.04 KiB         | 16.27 KiB       |
|        35 | sql/compress_gtid_table                   |                  8 | 14.20 KiB         | 1.77 KiB          | 8.05 KiB          | 18.62 KiB       |
|        25 | innodb/fts_optimize_thread                |                 12 | 1.86 KiB          |  158 bytes        |  648 bytes        | 1.98 KiB        |
|        23 | innodb/srv_master_thread                  |                 11 | 1.23 KiB          |  114 bytes        |  361 bytes        | 24.40 KiB       |
|        24 | innodb/dict_stats_thread                  |                 11 | 1.23 KiB          |  114 bytes        |  361 bytes        | 1.35 KiB        |
|         5 | innodb/io_read_thread                     |                  1 |  144 bytes        |  144 bytes        |  144 bytes        |  144 bytes      |
|         6 | innodb/io_read_thread                     |                  1 |  144 bytes        |  144 bytes        |  144 bytes        |  144 bytes      |
|         2 | sql/aws_oscar_log_level_monitor           |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         4 | innodb/io_ibuf_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         7 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         8 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|         9 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        10 | innodb/io_write_thread                    |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        11 | innodb/srv_lra_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        12 | innodb/srv_akp_thread                     |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        18 | innodb/srv_lock_timeout_thread            |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |  248 bytes      |
|        19 | innodb/srv_error_monitor_thread           |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        20 | innodb/srv_monitor_thread                 |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        21 | innodb/buf_resize_thread                  |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        22 | innodb/btr_search_sys_toggle_thread       |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        32 | innodb/dict_persist_metadata_table_thread |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
|        34 | sql/signal_handler                        |                  0 |    0 bytes        |    0 bytes        |    0 bytes        |    0 bytes      |
+-----------+-------------------------------------------+--------------------+-------------------+-------------------+-------------------+-----------------+
831 rows in set (2.48 sec)
```

前に述べたように、ここでスレッド ID (`thd_id`) 値は、サーバーのバックグラウンドスレッドまたはデータベース接続を参照できます。スレッド ID 値をデータベース接続 ID にマッピングする場合は、`performance_schema.threads` テーブルまたは `sys.processlist` ビューを使用できます。`conn_id` は接続 ID です。

```
mysql> SELECT thd_id,conn_id,user,db,command,state,time,last_wait FROM sys.processlist WHERE user='reinvent@10.0.4.4';

+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
| thd_id | conn_id | user              | db       | command | state          | time | last_wait                                       |
+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
|    590 |     562 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    578 |     550 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    579 |     551 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    580 |     552 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    581 |     553 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    582 |     554 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    583 |     555 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    584 |     556 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    585 |     557 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    586 |     558 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    587 |     559 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
.                                                                                                                                     .
.                                                                                                                                     .
.                                                                                                                                     .
|    323 |     295 | reinvent@10.0.4.4 | sysbench | Sleep   | NULL           |    0 | idle                                            |
|    324 |     296 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    325 |     297 | reinvent@10.0.4.4 | sysbench | Execute | closing tables |    0 | wait/io/redo_log_flush                          |
|    326 |     298 | reinvent@10.0.4.4 | sysbench | Execute | updating       |    0 | wait/io/table/sql/handler                       |
|    438 |     410 | reinvent@10.0.4.4 | sysbench | Execute | System lock    |    0 | wait/lock/table/sql/handler                     |
|    280 |     252 | reinvent@10.0.4.4 | sysbench | Sleep   | starting       |    0 | wait/io/socket/sql/client_connection            |
|     98 |      70 | reinvent@10.0.4.4 | sysbench | Query   | freeing items  |    0 | NULL                                            |
+--------+---------+-------------------+----------+---------+----------------+------+-------------------------------------------------+
804 rows in set (5.51 sec)
```

次に `sysbench` ワークロードを停止し、接続を終了してメモリを解放します。イベントをもう一度確認すると、メモリが解放されたことを確認できますが、`high_alloc` には以前としてハイウォーターマークが表示されています。`high_alloc` 列は、メモリ使用量の急増を特定するのに非常に役立ちます。`current_alloc` は、現在割り当てられているメモリのみを示すため、使用量の急増をすぐに特定できない場合があります。

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name='memory/sql/Prepared_statement::main_mem_root' LIMIT 10;

+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                   | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root |            17 | 253.80 KiB    | 14.93 KiB         |     512823 | 4.91 GiB   | 10.04 KiB      |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
1 row in set (0.00 sec)
```

`performance_schema` をリセットする場合は、`high_alloc` のメモリ概要テーブルを切り捨てることができますが、これに伴ってすべてのメモリ計測がリセットされます。詳細については、MySQL ドキュメントの「[Performance Schema general table characteristics](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-table-characteristics.html)」を参照してください。

次の例では、切り捨て後に `high_alloc` がリセットされていることがわかります。

```
mysql> TRUNCATE `performance_schema`.`memory_summary_global_by_event_name`;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM sys.memory_global_by_current_bytes WHERE event_name='memory/sql/Prepared_statement::main_mem_root' LIMIT 10;

+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                   | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/sql/Prepared_statement::main_mem_root |            17 | 253.80 KiB    | 14.93 KiB         |         17 | 253.80 KiB | 14.93 KiB      |
+----------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
1 row in set (0.00 sec)
```

## 例 2: 一時的なメモリスパイク
<a name="ams-workload-memory.example2"></a>

もう 1 つのよくある現象は、データベースサーバーでメモリ使用量が短時間に急増することです。これは空きメモリの定期的な低下を示している場合があります。メモリは解放済みであるため、`sys.memory_global_by_current_bytes` の `current_alloc` を使用したトラブルシューティングは困難です。

**注記**  
パフォーマンススキーマの統計をリセットしたり、データベースインスタンスを再起動したりすると、この情報は `sys` または p`erformance_schema` で使用できなくなります。この情報を保持するには、外部メトリクス収集を設定することをお勧めします。

次のグラフに示す拡張モニタリングの `os.memory.free` メトリクスでは、メモリ使用量が 7 秒間だけ急増したことがわかります。拡張モニタリングでは、1 秒という短い間隔で監視できるため、このような一時的なスパイクを検出するのに最適です。

![\[一時的なメモリ使用量の経時的な急増と、潜在的なメモリ管理の問題を示す周期的なパターンを示すグラフ。\]](http://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/images/ams-free-memory-spikes.png)


ここでメモリ消費の原因を診断しやすくするために、`sys` メモリの概要ビューの `high_alloc` と、[パフォーマンススキーマのステートメント概要テーブル](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html)を組み合わせて使用し、問題のあるセッションや接続を特定できます。

予想どおり、現在のメモリ使用量は多くないため、`current_alloc` の `sys` スキーマビューでは大きな問題を確認できません。

```
mysql> SELECT * FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| event_name                                                                  | current_count | current_alloc | current_avg_alloc | high_count | high_alloc | high_avg_alloc |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
| memory/innodb/hash0hash                                                     |             4 | 79.07 MiB     | 19.77 MiB         |          4 | 79.07 MiB  | 19.77 MiB      |
| memory/innodb/os0event                                                      |        439372 | 60.34 MiB     |  144 bytes        |     439372 | 60.34 MiB  |  144 bytes     |
| memory/performance_schema/events_statements_summary_by_digest               |             1 | 40.28 MiB     | 40.28 MiB         |          1 | 40.28 MiB  | 40.28 MiB      |
| memory/mysys/KEY_CACHE                                                      |             3 | 16.00 MiB     | 5.33 MiB          |          3 | 16.00 MiB  | 5.33 MiB       |
| memory/performance_schema/events_statements_history_long                    |             1 | 14.34 MiB     | 14.34 MiB         |          1 | 14.34 MiB  | 14.34 MiB      |
| memory/performance_schema/events_errors_summary_by_thread_by_error          |           257 | 13.07 MiB     | 52.06 KiB         |        257 | 13.07 MiB  | 52.06 KiB      |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name |             1 | 11.81 MiB     | 11.81 MiB         |          1 | 11.81 MiB  | 11.81 MiB      |
| memory/performance_schema/events_statements_summary_by_digest.digest_text   |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
| memory/performance_schema/events_statements_history_long.digest_text        |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
| memory/performance_schema/events_statements_history_long.sql_text           |             1 | 9.77 MiB      | 9.77 MiB          |          1 | 9.77 MiB   | 9.77 MiB       |
+-----------------------------------------------------------------------------+---------------+---------------+-------------------+------------+------------+----------------+
10 rows in set (0.01 sec)
```

ビューを `high_alloc` の順に並べ替えると、`memory/temptable/physical_ram` コンポーネントにまさに問題があることがわかります。使用量の最高値が 515.00 MiB になっています。

その名前が示すように、`memory/temptable/physical_ram` は、MySQL 8.0 で MySQL に導入された `TEMP` ストレージエンジンのメモリ使用量を計測します。MySQL で一時テーブルを使用する方法の詳細については、MySQL ドキュメントの「[Internal temporary table use in MySQL](https://dev.mysql.com/doc/refman/8.0/en/internal-temporary-tables.html)」を参照してください。

**注記**  
この例では、`sys.x$memory_global_by_current_bytes` ビューを使用しています。

```
mysql> SELECT event_name, format_bytes(current_alloc) AS "currently allocated", sys.format_bytes(high_alloc) AS "high-water mark"  
FROM sys.x$memory_global_by_current_bytes ORDER BY high_alloc DESC LIMIT 10;

+-----------------------------------------------------------------------------+---------------------+-----------------+
| event_name                                                                  | currently allocated | high-water mark |
+-----------------------------------------------------------------------------+---------------------+-----------------+
| memory/temptable/physical_ram                                               | 4.00 MiB            | 515.00 MiB      |
| memory/innodb/hash0hash                                                     | 79.07 MiB           | 79.07 MiB       |
| memory/innodb/os0event                                                      | 63.95 MiB           | 63.95 MiB       |
| memory/performance_schema/events_statements_summary_by_digest               | 40.28 MiB           | 40.28 MiB       |
| memory/mysys/KEY_CACHE                                                      | 16.00 MiB           | 16.00 MiB       |
| memory/performance_schema/events_statements_history_long                    | 14.34 MiB           | 14.34 MiB       |
| memory/performance_schema/events_errors_summary_by_thread_by_error          | 13.07 MiB           | 13.07 MiB       |
| memory/performance_schema/events_statements_summary_by_thread_by_event_name | 11.81 MiB           | 11.81 MiB       |
| memory/performance_schema/events_statements_summary_by_digest.digest_text   | 9.77 MiB            | 9.77 MiB        |
| memory/performance_schema/events_statements_history_long.sql_text           | 9.77 MiB            | 9.77 MiB        |
+-----------------------------------------------------------------------------+---------------------+-----------------+
10 rows in set (0.00 sec)
```

[例 1: 連続的に高いメモリ使用量](#ams-workload-memory.example1) では、各接続の現在のメモリ使用量を調べて、どの接続が問題のメモリを使用しているかを判断しました。この例では、メモリは解放済みであるため、現在の接続のメモリ使用量を調べても役に立ちません。

より深く掘り下げて問題の原因であるステートメント、ユーザー、ホストを見つけるには、パフォーマンススキーマを使用します。パフォーマンススキーマには、イベント名、ステートメントダイジェスト、ホスト、スレッド、ユーザーなど、さまざまな次元で分類された複数のステートメント概要テーブルがあります。各ビューでは、特定のステートメントの実行場所や実行内容をより深く掘り下げることができます。このセクションでは、主に `MAX_TOTAL_MEMORY` について説明していますが、「[パフォーマンススキーマのステートメント概要テーブル](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html)」ですべての例に関する詳細を参照できます。

```
mysql> SHOW TABLES IN performance_schema LIKE 'events_statements_summary_%';

+------------------------------------------------------------+
| Tables_in_performance_schema (events_statements_summary_%) |
+------------------------------------------------------------+
| events_statements_summary_by_account_by_event_name         |
| events_statements_summary_by_digest                        |
| events_statements_summary_by_host_by_event_name            |
| events_statements_summary_by_program                       |
| events_statements_summary_by_thread_by_event_name          |
| events_statements_summary_by_user_by_event_name            |
| events_statements_summary_global_by_event_name             |
+------------------------------------------------------------+
7 rows in set (0.00 sec)
```

まず、`events_statements_summary_by_digest` を調べて `MAX_TOTAL_MEMORY` を確認します。

これにより、以下がわかります。
+ メモリ使用量が多い筆頭は、ダイジェスト `20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a` を使用するクエリのようです。`MAX_TOTAL_MEMORY` は 537450710 で、`sys.x$memory_global_by_current_bytes` の `memory/temptable/physical_ram` イベントで確認したハイウォーターマークと一致しています。
+ これまでに 4 回 (`COUNT_STAR`) 実行されており、最初は 2024-03-26 04:08:34.943256、最後は 2024-03-26 04:43:06.998310 です。

```
mysql> SELECT SCHEMA_NAME,DIGEST,COUNT_STAR,MAX_TOTAL_MEMORY,FIRST_SEEN,LAST_SEEN
FROM performance_schema.events_statements_summary_by_digest ORDER BY MAX_TOTAL_MEMORY DESC LIMIT 5;

+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
| SCHEMA_NAME | DIGEST                                                           | COUNT_STAR | MAX_TOTAL_MEMORY | FIRST_SEEN                 | LAST_SEEN                  |
+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
| sysbench    | 20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a |          4 |        537450710 | 2024-03-26 04:08:34.943256 | 2024-03-26 04:43:06.998310 |
| NULL        | f158282ea0313fefd0a4778f6e9b92fc7d1e839af59ebd8c5eea35e12732c45d |          4 |          3636413 | 2024-03-26 04:29:32.712348 | 2024-03-26 04:36:26.269329 |
| NULL        | 0046bc5f642c586b8a9afd6ce1ab70612dc5b1fd2408fa8677f370c1b0ca3213 |          2 |          3459965 | 2024-03-26 04:31:37.674008 | 2024-03-26 04:32:09.410718 |
| NULL        | 8924f01bba3c55324701716c7b50071a60b9ceaf17108c71fd064c20c4ab14db |          1 |          3290981 | 2024-03-26 04:31:49.751506 | 2024-03-26 04:31:49.751506 |
| NULL        | 90142bbcb50a744fcec03a1aa336b2169761597ea06d85c7f6ab03b5a4e1d841 |          1 |          3131729 | 2024-03-26 04:15:09.719557 | 2024-03-26 04:15:09.719557 |
+-------------+------------------------------------------------------------------+------------+------------------+----------------------------+----------------------------+
5 rows in set (0.00 sec)
```

問題があるダイジェストがわかったので、クエリテキスト、実行したユーザー、実行場所などの詳細を取得できます。返されたダイジェストテキストから、これは 4 つの一時テーブルを作成して 4 つのテーブルスキャンを実行する一般的なテーブル式 (CTE) であり、非常に効率の悪いものであることがわかります。

```
mysql> SELECT SCHEMA_NAME,DIGEST_TEXT,QUERY_SAMPLE_TEXT,MAX_TOTAL_MEMORY,SUM_ROWS_SENT,SUM_ROWS_EXAMINED,SUM_CREATED_TMP_TABLES,SUM_NO_INDEX_USED
FROM performance_schema.events_statements_summary_by_digest
WHERE DIGEST='20676ce4a690592ff05debcffcbc26faeb76f22005e7628364d7a498769d0c4a'\G;

*************************** 1. row ***************************
           SCHEMA_NAME: sysbench
           DIGEST_TEXT: WITH RECURSIVE `cte` ( `n` ) AS ( SELECT ? FROM `sbtest1` UNION ALL SELECT `id` + ? FROM `sbtest1` ) SELECT * FROM `cte`
     QUERY_SAMPLE_TEXT: WITH RECURSIVE cte (n) AS (   SELECT 1  from sbtest1 UNION ALL   SELECT id + 1 FROM sbtest1) SELECT * FROM cte
      MAX_TOTAL_MEMORY: 537450710
         SUM_ROWS_SENT: 80000000
     SUM_ROWS_EXAMINED: 80000000
SUM_CREATED_TMP_TABLES: 4
     SUM_NO_INDEX_USED: 4
1 row in set (0.01 sec)
```

`events_statements_summary_by_digest` テーブルとその他のパフォーマンススキーマのステートメント概要テーブルの詳細については、MySQL ドキュメントの「[Statement summary tables](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-statement-summary-tables.html)」を参照してください。

[EXPLAIN](https://dev.mysql.com/doc/refman/8.0/en/explain.html) または [EXPLAIN ANALYZE](https://dev.mysql.com/doc/refman/8.0/en/explain.html#explain-analyze) ステートメントを実行して詳細を確認することもできます。

**注記**  
`EXPLAIN ANALYZE` は、`EXPLAIN` よりも多くの情報を提供できますが、クエリも実行するので注意する必要があります。

```
-- EXPLAIN
mysql> EXPLAIN WITH RECURSIVE cte (n) AS (SELECT 1  FROM sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte;

+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
| id | select_type | table      | partitions | type  | possible_keys | key  | key_len | ref  | rows     | filtered | Extra       |
+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
|  1 | PRIMARY     | <derived2> | NULL       | ALL   | NULL          | NULL | NULL    | NULL | 19221520 |   100.00 | NULL        |
|  2 | DERIVED     | sbtest1    | NULL       | index | NULL          | k_1  | 4       | NULL |  9610760 |   100.00 | Using index |
|  3 | UNION       | sbtest1    | NULL       | index | NULL          | k_1  | 4       | NULL |  9610760 |   100.00 | Using index |
+----+-------------+------------+------------+-------+---------------+------+---------+------+----------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)

-- EXPLAIN format=tree 
mysql> EXPLAIN format=tree WITH RECURSIVE cte (n) AS (SELECT 1 FROM sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte\G;

*************************** 1. row ***************************
EXPLAIN: -> Table scan on cte  (cost=4.11e+6..4.35e+6 rows=19.2e+6)
    -> Materialize union CTE cte  (cost=4.11e+6..4.11e+6 rows=19.2e+6)
        -> Index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6)
        -> Index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6)
1 row in set (0.00 sec)

-- EXPLAIN ANALYZE 
mysql> EXPLAIN ANALYZE WITH RECURSIVE cte (n) AS (SELECT 1 from sbtest1 UNION ALL SELECT id + 1 FROM sbtest1) SELECT * FROM cte\G;

*************************** 1. row ***************************
EXPLAIN: -> Table scan on cte  (cost=4.11e+6..4.35e+6 rows=19.2e+6) (actual time=6666..9201 rows=20e+6 loops=1)
    -> Materialize union CTE cte  (cost=4.11e+6..4.11e+6 rows=19.2e+6) (actual time=6666..6666 rows=20e+6 loops=1)
        -> Covering index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6) (actual time=0.0365..2006 rows=10e+6 loops=1)
        -> Covering index scan on sbtest1 using k_1  (cost=1.09e+6 rows=9.61e+6) (actual time=0.0311..2494 rows=10e+6 loops=1)
1 row in set (10.53 sec)
```

ここで、クエリを実行したユーザーがわかるでしょうか。パフォーマンススキーマを見ると、`destructive_operator` ユーザーの `MAX_TOTAL_MEMORY` が 537450710 になっており、前の結果と一致しています。

**注記**  
パフォーマンススキーマはメモリに保存されるため、監査の唯一のソースとして依存すべきではありません。実行したステートメントやユーザーの履歴を保持する必要がある場合は、[[Aurora の高度な監査]](AuroraMySQL.Auditing.md) を有効にすることをお勧めします。メモリ使用量に関する情報も保持する必要がある場合は、これらの値をエクスポートして保存するようにモニタリングを設定することをお勧めします。

```
mysql> SELECT USER,EVENT_NAME,COUNT_STAR,MAX_TOTAL_MEMORY FROM performance_schema.events_statements_summary_by_user_by_event_name
ORDER BY MAX_CONTROLLED_MEMORY DESC LIMIT 5;

+----------------------+---------------------------+------------+------------------+
| USER                 | EVENT_NAME                | COUNT_STAR | MAX_TOTAL_MEMORY |
+----------------------+---------------------------+------------+------------------+
| destructive_operator | statement/sql/select      |          4 |        537450710 |
| rdsadmin             | statement/sql/select      |       4172 |          3290981 |
| rdsadmin             | statement/sql/show_tables |          2 |          3615821 |
| rdsadmin             | statement/sql/show_fields |          2 |          3459965 |
| rdsadmin             | statement/sql/show_status |         75 |          1914976 |
+----------------------+---------------------------+------------+------------------+
5 rows in set (0.00 sec)

mysql> SELECT HOST,EVENT_NAME,COUNT_STAR,MAX_TOTAL_MEMORY FROM performance_schema.events_statements_summary_by_host_by_event_name
WHERE HOST != 'localhost' AND COUNT_STAR>0 ORDER BY MAX_CONTROLLED_MEMORY DESC LIMIT 5;

+------------+----------------------+------------+------------------+
| HOST       | EVENT_NAME           | COUNT_STAR | MAX_TOTAL_MEMORY |
+------------+----------------------+------------+------------------+
| 10.0.8.231 | statement/sql/select |          4 |        537450710 |
+------------+----------------------+------------+------------------+
1 row in set (0.00 sec)
```

## 例 3: 解放可能なメモリが継続的に減少し、再利用されない
<a name="ams-workload-memory.example3"></a>

InnoDB データベースエンジンは、異なるコンポーネントに対してさまざまな特殊なメモリ追跡イベントを使用します。これらの特定のイベントにより、主要な InnoDB サブシステムのメモリ使用量を詳細に追跡できます。次に例を示します。
+ `memory/innodb/buf0buf` – InnoDB バッファプールのメモリ割り当てのモニタリング専用。
+ `memory/innodb/ibuf0ibuf` – 特に、InnoDB 変更バッファに関連するメモリの変化を追跡します。

メモリの上位コンシューマーを特定するには、`sys.memory_global_by_current_bytes` をクエリします。

```
mysql> SELECT event_name,current_alloc FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------+---------------+
| event_name                                                      | current_alloc |
+-----------------------------------------------------------------+---------------+
| memory/innodb/memory                                            | 5.28 GiB      |
| memory/performance_schema/table_io_waits_summary_by_index_usage | 495.00 MiB    |
| memory/performance_schema/table_shares                          | 488.00 MiB    |
| memory/sql/TABLE_SHARE::mem_root                                | 388.95 MiB    |
| memory/innodb/std                                               | 226.88 MiB    |
| memory/innodb/fil0fil                                           | 198.49 MiB    |
| memory/sql/binlog_io_cache                                      | 128.00 MiB    |
| memory/innodb/mem0mem                                           | 96.82 MiB     |
| memory/innodb/dict0dict                                         | 96.76 MiB     |
| memory/performance_schema/rwlock_instances                      | 88.00 MiB     |
+-----------------------------------------------------------------+---------------+
10 rows in set (0.00 sec)
```

結果は、`memory/innodb/memory` が上位コンシューマーであり、現在割り当てられているメモリの 5.28 GiB を使用していることを示しています。このイベントは、前述の `memory/innodb/buf0buf` のように、より具体的な待機イベントに関連付けられていない、さまざまな InnoDB コンポーネント全体でのメモリ割り当てのカテゴリとして機能します。

InnoDB コンポーネントがメモリの主要コンシューマーであることが確認できたので、次の MySQL コマンドを使用して、詳細を掘り下げて調べることができます。

```
SHOW ENGINE INNODB STATUS \G;
```

[SHOW ENGINE INNODB STATUS](https://dev.mysql.com/doc/refman/8.4/en/show-engine.html) コマンドは、さまざまな InnoDB コンポーネントの詳細なメモリ使用量統計など、InnoDB ストレージエンジンの包括的なステータスレポートを提供します。このレポートを基に、どの特定の InnoDB 構造またはオペレーションが最もメモリを消費しているかを確認できます。詳細については、MySQL ドキュメントの「[InnoDB in-memory structures](https://dev.mysql.com/doc/refman/8.0/en/innodb-in-memory-structures.html)」を参照してください。

InnoDB ステータスレポートの `BUFFER POOL AND MEMORY` セクションを分析すると、5,051,647,748 バイト (4.7 GiB) が[ディクショナリオブジェクトキャッシュ](https://dev.mysql.com/doc/refman/8.0/en/data-dictionary-object-cache.html)に割り当てられ、`memory/innodb/memory` が追跡するメモリの 89% を占めていることがわかります。

```
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 0
Dictionary memory allocated 5051647748
Buffer pool size 170512
Free buffers 142568
Database pages 27944
Old database pages 10354
Modified db pages 6
Pending reads 0
```

ディクショナリオブジェクトキャッシュは、以前アクセスしたデータディクショナリオブジェクトをメモリに保存し、オブジェクトの再利用を可能にしてパフォーマンスを向上させる、共有グローバルキャッシュです。ディクショナリオブジェクトキャッシュへの高いメモリ割り当ては、データディクショナリキャッシュ内のデータベースオブジェクトが多いことを示唆しています。

これで、データディクショナリキャッシュが主要コンシューマーであることがわかりました。次に、データディクショナリキャッシュで開いているテーブルを調べます。テーブル定義キャッシュ内のテーブル数を確認するには、グローバルステータス変数 [open\$1table\$1definitions](https://dev.mysql.com/doc/refman/8.4/en/server-status-variables.html#statvar_Open_table_definitions) をクエリします。

```
mysql> show global status like 'open_table_definitions';

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Open_table_definitions | 20000 |
+------------------------+-------+
1 row in set (0.00 sec)
```

詳細については、MySQL ドキュメントの「[MySQL でのテーブルのオープンとクローズの方法](https://dev.mysql.com/doc/refman/8.0/en/table-cache.html)」を参照してください。

DB クラスターまたは DB インスタンスパラメータグループの `table_definition_cache` パラメータを制限することで、データディクショナリキャッシュ内のテーブル定義の数を制限できます。Aurora MySQL の場合、この値はテーブル定義キャッシュ内のテーブル数のソフト制限として機能します。デフォルト値はインスタンスクラスに依存し、次のように設定されています。

```
LEAST({DBInstanceClassMemory/393040}, 20000)
```

テーブルの数が `table_definition_cache` 制限を超えると、LRU (least recently used) メカニズムはキャッシュからテーブルをエビクションして削除します。ただし、外部キー関係に関連するテーブルは LRU リストに配置されないため、削除されません。

現在のシナリオでは、[FLUSH TABLES](https://dev.mysql.com/doc/refman/8.4/en/flush.html) を実行してテーブル定義キャッシュをクリアします。このアクションにより、次に示すように、[Open\$1table\$1definitions](https://dev.mysql.com/doc/refman/8.0/en/server-status-variables.html#statvar_Open_table_definitions) グローバルステータス変数が 20,000 から 12 に大幅に減少します。

```
mysql> show global status like 'open_table_definitions';

+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Open_table_definitions | 12    |
+------------------------+-------+
1 row in set (0.00 sec)
```

この減少にもかかわらず、`memory/innodb/memory` のメモリ割り当ては 5.18 GiB と高いままであり、割り当てられたディクショナリメモリにも変化がないことがわかります。これは、次のクエリ結果から明らかです。

```
mysql> SELECT event_name,current_alloc FROM sys.memory_global_by_current_bytes LIMIT 10;

+-----------------------------------------------------------------+---------------+
| event_name                                                      | current_alloc |
+-----------------------------------------------------------------+---------------+
| memory/innodb/memory                                            | 5.18 GiB      |
| memory/performance_schema/table_io_waits_summary_by_index_usage | 495.00 MiB    |
| memory/performance_schema/table_shares                          | 488.00 MiB    |
| memory/sql/TABLE_SHARE::mem_root                                | 388.95 MiB    |
| memory/innodb/std                                               | 226.88 MiB    |
| memory/innodb/fil0fil                                           | 198.49 MiB    |
| memory/sql/binlog_io_cache                                      | 128.00 MiB    |
| memory/innodb/mem0mem                                           | 96.82 MiB     |
| memory/innodb/dict0dict                                         | 96.76 MiB     |
| memory/performance_schema/rwlock_instances                      | 88.00 MiB     |
+-----------------------------------------------------------------+---------------+
10 rows in set (0.00 sec)
```

```
----------------------
BUFFER POOL AND MEMORY
----------------------
Total large memory allocated 0
Dictionary memory allocated 5001599639
Buffer pool size 170512
Free buffers 142568
Database pages 27944
Old database pages 10354
Modified db pages 6
Pending reads 0
```

この持続的に高いメモリ使用量は、外部キー関係に関連するテーブルに起因する可能性があります。これらのテーブルは、削除のために LRU リストに配置されません。これは、テーブル定義キャッシュをフラッシュした後もメモリ割り当てが高いままである理由の説明となります。

この問題に対応するには:

1. データベーススキーマ、特に外部キー関係を確認して最適化します。

1. ディクショナリオブジェクトに対応するため、より多くのメモリを持つより大きな DB インスタンスクラスへの移行を検討してください。

これらのステップに従い、メモリ割り当てパターンを理解することで、Aurora MySQL DB インスタンスのメモリ使用量をより適切に管理し、メモリ負荷による潜在的なパフォーマンスの問題を防ぐことができます。

# Aurora MySQL データベースのメモリ不足の問題のトラブルシューティング
<a name="AuroraMySQLOOM"></a>

Aurora MySQL `aurora_oom_response` インスタンスレベルパラメータは、DB インスタンスによって、システムメモリをモニタリングしてさまざまなステートメントおよび接続で消費されるメモリを推測できるようにします。システムでメモリ不足が発生した場合、メモリを解放するためのアクションリストを実行できます。これは、メモリ不足 (OOM) を原因とするデータベースの再起動を避ける目的で実行されます。このインスタンスレベルのパラメータでは、メモリが少ない場合に DB インスタンスが実行すべきアクションを、カンマ区切りの文字列で指定できます。この `aurora_oom_response` パラメータは、Aurora MySQL バージョン 2 および 3 でサポートされています。

`aurora_oom_response` パラメータには、以下の値とそれらの組み合わせを使用できます。空の文字列はアクションが実行されないことを意味し、実質的にこの機能はオフになります。そのため、データベースは OOM の再起動が発生しやすくなります。
+ `decline` – DB インスタンスのメモリが少なくなった場合、新しいクエリを拒否します。
+ `kill_connect` – 大量のメモリを消費しているデータベース接続を閉じ、現在のトランザクションとデータ定義言語 (DDL) ステートメントを終了します。この応答は、Aurora MySQL バージョン 2 ではサポートされていません。

  詳細については、MySQL ドキュメントの「[KILL ステートメント](https://dev.mysql.com/doc/refman/8.0/en/kill.html)」を参照してください。
+ `kill_query` – インスタンスのメモリが低しきい値を超えるまで、メモリ使用量の高い順にクエリを終了します。DDL ステートメントは終了されません。

  詳細については、MySQL ドキュメントの「[KILL ステートメント](https://dev.mysql.com/doc/refman/8.0/en/kill.html)」を参照してください。
+ `print` – 大量のメモリを使用するクエリのみを出力します。
+ `tune` - 内部テーブルキャッシュを調整して、メモリをシステムに戻します。Aurora MySQL は、メモリが少ない状態では `table_open_cache` や `table_definition_cache` などのキャッシュに使用されるメモリを低減します。最終的に、Aurora MySQL は、システムのメモリ不足がなくなると、メモリ使用量を通常に戻します。

  詳細については、MySQL ドキュメントの「[table\$1open\$1cache](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_table_open_cache)」と「[table\$1definition\$1cache](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_table_definition_cache)」を参照してください。
+ `tune_buffer_pool` – バッファプールのサイズを小さくしてメモリを解放し、データベースサーバーが接続を処理できるようにします。この応答は、Aurora MySQL バージョン 3.06 以降でサポートされています。

  `tune_buffer_pool` を `kill_query` または `aurora_oom_response` パラメータ値の `kill_connect` とペアにする必要があります。そうしない場合、パラメータ値に `tune_buffer_pool` を含めても、バッファプールのサイズ変更は行われません。

3.06 以前のバージョンの Aurora MySQL の場合は、メモリが 4 GiB 以下の DB インスタンスクラスでメモリプレッシャーがかかっているときのデフォルトアクションに `print`、`tune`、`decline`、`kill_query` があります。4 GiB を超えるメモリがある DB インスタンスクラスでは、このパラメータ値はデフォルトで空 (無効) になっています。

Aurora MySQL バージョン 3.06 以降では、メモリが 4 GiB 以下の DB インスタンスクラスの場合、Aurora MySQL は最もメモリ消費量の多い接続 (`kill_connect`) も閉じます。4 GiB を超えるメモリがある DB インスタンスクラスでは、このパラメータ値はデフォルトで `print` になっています。

Aurora MySQL バージョン 3.09 以降では、4 GiB を超えるメモリがある DB インスタンスクラスの場合、デフォルトのパラメータ値は `print,decline,kill_connect` です。

メモリ不足の問題が頻繁に発生する場合は、`performance_schema` が有効になっていれば[メモリのサマリーテーブル](https://dev.mysql.com/doc/refman/8.3/en/performance-schema-memory-summary-tables.html)を使用してメモリ使用量をモニタリングできます。

OOM に関連する Amazon CloudWatch メトリクスについては、「[Amazon Aurora のインスタンスレベルのメトリクス](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances)」を参照してください。OOM に関連するグローバルステータス変数については、「[Aurora MySQL グローバルステータス変数](AuroraMySQL.Reference.GlobalStatusVars.md)」を参照してください。

# Aurora MySQL データベースのログ記録
<a name="aurora-mysql-troubleshooting-logging"></a>

Aurora MySQL ログは、データベースのアクティビティとエラーに関する重要な情報を提供します。これらのログを有効にすることで、問題の特定とトラブルシューティング、データベースパフォーマンスの把握、データベースアクティビティの監査が可能になります。データベースのパフォーマンスと可用性を最適化するために、すべての Aurora MySQL DB インスタンスでこれらのログを有効にすることをお勧めします。次のタイプのログを有効にできます。各ログには、データベース処理への影響を明らかにするのに役立つ特定の情報が含まれています。
+ エラー - Aurora MySQL ではスタートアップ時、シャットダウン時、およびエラー検出時にのみ、エラーログへの書き込みが行われます。DB インスタンスでは、新しいエントリがエラーログに書き込まれないまま、数時間または数日が経過することがあります。最近のエントリがない場合、それは、サーバーにログエントリになり得るエラーが発生しなかったためです。エラーロギングはデフォルトで有効になっています。詳細については、「[Aurora MySQL エラーログ](USER_LogAccess.MySQL.LogFileSize.md#USER_LogAccess.MySQL.Errorlog)」を参照してください。
+ 一般 — 一般ログには、データベースエンジンによって実行されたすべての SQL ステートメントを含む、データベースアクティビティに関する詳細情報が含まれます。一般的なロギングの有効化とロギングパラメータの設定の詳細については、「[Aurora MySQL のスロークエリと一般ログ](USER_LogAccess.MySQL.LogFileSize.md#USER_LogAccess.MySQL.Generallog)」、および MySQL ドキュメントの「[一般クエリログ](https://dev.mysql.com/doc/refman/8.0/en/query-log.html)」を参照してください。
**注記**  
一般ログは非常に大きくなり、ストレージを消費する可能性があります。詳細については、「[Aurora MySQL のログのローテーションと保持](USER_LogAccess.MySQL.LogFileSize.md#USER_LogAccess.AMS.LogFileSize.retention)」を参照してください。
+ スロークエリ — スロークエリログは、実行に [long\$1query\$1time](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_long_query_time)​ 秒を超える時間がかかり、検証に [min\$1examined\$1row\$1limit](https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_min_examined_row_limit) 行以上を要した SQL ステートメントで構成されています。スロークエリログを使用すると、実行に時間がかかるため最適化の対象となるクエリを見つけることができます。

  `long_query_time` のデフォルト値は 10 (秒) です。高い値から始めて最も遅いクエリを特定し、その後微調整することをおすすめします。

  `log_slow_admin_statements` や `log_queries_not_using_indexes` などの関連パラメータを使用することもできます。`rows_examined` と `rows_returned` を比較します。`rows_examined` が `rows_returned` よりはるかに大きい場合は、それらのクエリがブロックする可能性があります。

  Aurora MySQL バージョン 3 では、`log_slow_extra` を有効にしてより詳細な情報を取得することができます。詳細については、MySQL ドキュメントの「[スロークエリログの内容](https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html#slow-query-log-contents)」を参照してください。クエリ実行をインタラクティブにデバッグするようにセッションレベルで `long_query_time` を変更することもできます。これは `log_slow_extra` がグローバルに有効になっている場合に特に便利です。

  スロークエリロギングの有効化とロギングパラメータの設定の詳細については、「[Aurora MySQL のスロークエリと一般ログ](USER_LogAccess.MySQL.LogFileSize.md#USER_LogAccess.MySQL.Generallog)」、および MySQL ドキュメントの「[スロークエリログ](https://dev.mysql.com/doc/refman/8.0/en/slow-query-log.html)」を参照してください。
+ 監査 — 監査ログはデータベースのアクティビティをモニタリングして記録します。Aurora MySQL の監査ログは、高度な監査と呼ばれます。高度な監査を有効にするには、特定の DB クラスターパラメータを設定します。詳細については、「[Amazon Aurora MySQL DB クラスターでのアドバンストな監査の使用](AuroraMySQL.Auditing.md)」を参照してください。
+ バイナリ — バイナリログ (binlog) には、テーブル作成操作やテーブルデータへの変更など、データベースの変更を説明するイベントが含まれます。また、行ベースのロギングが使用されていない限り、変更を加えた可能性のあるステートメント (行と一致しない [DELETE](https://dev.mysql.com/doc/refman/8.0/en/delete.html) など) のイベントも含まれます。バイナリログには、各ステートメントがデータの更新にかかった時間に関する情報も含まれています。

  バイナリロギングを有効にしてサーバーを実行させると、パフォーマンスがわずかに低下します。ただし、一般に、レプリケーションや復元操作を設定できるバイナリログの利点は、このわずかなパフォーマンスの低下よりも上回ります。
**注記**  
Aurora MySQL では、復元操作にバイナリロギングは必要ありません。

  バイナリロギングの有効化とバイナリログ形式の設定の詳細については、「[シングル AZ データベースの Aurora MySQL バイナリログの設定](USER_LogAccess.MySQL.BinaryFormat.md)」、MySQL ドキュメントの「[バイナリログ](https://dev.mysql.com/doc/refman/8.0/en/binary-log.html)」を参照してください。

エラーログ、一般ログ、スローログ、クエリログ、監査ログを Amazon CloudWatch Logs にパブリッシュできます。詳細については、「[Amazon CloudWatch Logs へのデータベースログの発行](USER_LogAccess.Procedural.UploadtoCloudWatch.md)」を参照してください。

スローログ、一般ログ、バイナリログファイルを要約するもう 1 つの便利なツールは [pt-query-digest](https://docs.percona.com/percona-toolkit/pt-query-digest.html) です。

# Aurora MySQL データベースの接続問題のトラブルシューティング
<a name="mysql-troubleshooting-dbconn"></a>

アプリケーションと RDS DB インスタンスの間で信頼性の高い接続を確保することは、ワークロードのスムーズな運用に不可欠です。ただし、ネットワーク設定、認証の問題、リソースの制約など、さまざまな要因によって接続の問題が発生する場合があります。このガイドでは、Aurora MySQL の接続問題のトラブルシューティングに役立つ包括的なアプローチを提供します。

**Contents**
+ [Aurora MySQL のデータベース接続問題の特定](#mysql-dbconn-identify)
+ [Aurora MySQL の接続問題に関するデータの収集](#mysql-dbconn-gather)
+ [Aurora MySQL のデータベース接続のモニタリング](#mysql-dbconn-monitor)
  + [Aurora MySQL の追加モニタリング](#mysql-dbconn-monitor-ams)
+ [Aurora MySQL の接続エラーコード](#mysql-dbconn-errors)
+ [Aurora MySQL のパラメータチューニングの推奨事項](#mysql-dbconn-params)
+ [Aurora MySQL のデータベース接続問題のトラブルシューティングの例](#mysql-dbconn-examples)
  + [例 1: 失敗した接続試行のトラブルシューティング](#mysql-dbconn-example1)
  + [例 2: 異常なクライアント切断のトラブルシューティング](#mysql-dbconn-example2)
  + [例 3: IAM 接続試行失敗のトラブルシューティング](#mysql-dbconn-example3)

## Aurora MySQL のデータベース接続問題の特定
<a name="mysql-dbconn-identify"></a>

接続問題のカテゴリを特定することは、潜在的な原因を絞り込み、トラブルシューティングプロセスを進めるのに役立ちます。カテゴリごとに、診断や解決のアプローチと手法は異なる場合があります。データベース接続の問題は、以下のカテゴリに大別できます。

**接続エラーと例外**  
接続エラーと例外は、接続文字列の誤り、認証の失敗、ネットワークの中断、データベースサーバーの問題など、さまざまな原因で発生する場合があります。原因には、接続パラメータの設定ミス、無効な認証情報、ネットワーク停止、データベースサーバーのクラッシュや再起動が含まれます。セキュリティグループ、仮想プライベートクラウド (VPC) 設定、ネットワークアクセスコントロールリスト (ACL)、サブネットに関連付けられたルートテーブルの設定ミスも、接続問題につながる可能性があります。

**接続制限の到達**  
この問題は、データベースサーバーへの同時接続数が最大許容数を超えた場合に発生します。データベースサーバーには、通常、クラスターとインスタンスパラメータグループのパラメータ max\$1connections で定義される設定可能な最大接続制限があります。データベースサーバーは、接続制限を課すことで、既存の接続を効率的に処理して許容可能なパフォーマンスを提供するための十分なリソース (メモリ、CPU、ファイルハンドルなど) を確保します。原因としては、アプリケーションの接続リーク、非効率的な接続プール、接続リクエストの予期しない急増などが考えられます。

**接続タイムアウト**  
接続タイムアウトは、クライアントアプリケーションが指定のタイムアウト時間内にデータベースサーバーとの接続を確立できない場合に発生します。一般的な原因には、ネットワークの問題、サーバーの過負荷、ファイアウォールルール、接続設定の構成ミスなどがあります。

**アイドル接続のタイムアウト**  
アイドル接続が長時間非アクティブのままになっていると、リソースを節約するために、データベースサーバーによって自動的に閉じられる場合があります。このタイムアウトは通常、`wait_timeout` と `interactive_timeout parameters` を使用して設定可能であり、アプリケーションの接続の使用パターンに基づいて調整する必要があります。原因としては、接続を長期間アイドル状態にするアプリケーションロジックや、不適切な接続管理などがあります。

**既存の接続の断続的な切断**  
このクラスのエラーは、クライアントアプリケーションとデータベースの間に確立した接続が、アクティブかつ使用中であっても、予期せず終了したり、不規則な間隔で断続したりする場合に発生します。これらの切断は断続的に発生します。つまり、不規則な間隔で発生し、一貫していません。以下のような原因が挙げられます。  
+ 再起動やフェイルオーバーなどのデータベースサーバーの問題
+ アプリケーション接続の不適切な処理
+ 負荷分散とプロキシの問題
+ ネットワークの不安定性
+ 接続パスに関連したサードパーティのコンポーネントやミドルウェアの問題
+ クエリ実行タイムアウト
+ サーバー側またはクライアント側のリソース制約
包括的なモニタリング、ログ記録、分析を通じて根本原因を特定することが重要であるとともに、適切なエラー処理、接続プール、再試行メカニズムを実装することで、これらの断続的な切断がアプリケーションの機能とユーザーエクスペリエンスにもたらす影響を軽減できます。

## Aurora MySQL の接続問題に関するデータの収集
<a name="mysql-dbconn-gather"></a>

アプリケーション、データベース、ネットワーク、インフラストラクチャコンポーネントに関する包括的なデータを収集することが、アプリケーションと Aurora MySQL データベースの間の接続問題の効果的なトラブルシューティングに不可欠です。関連するログ、設定、診断情報を収集することで、接続問題の根本原因の特定と、適切な解決策に役立つ貴重なインサイトが得られます。

セキュリティグループルール、VPC 設定、ルートテーブルなどのネットワークログと設定は、アプリケーションとデータベースとの正常な接続の確立を妨げる可能性があるネットワーク関連のボトルネックや設定ミスを特定するうえで不可欠です。これらのネットワークコンポーネントを分析することで、必要なポートが開いていること、IP アドレスが許可されていること、ルーティング設定が正しくセットアップされていることを確認できます。

**タイムスタンプ**  
接続問題が発生したときの正確なタイムスタンプを記録します。これは、パターンを特定したり、問題を他のイベントやアクティビティと関連付けたりするのに役立ちます。

**DB エンジンログ**  
一般的なデータベースログに加えて、データベースエンジンログ (MySQL エラーログやスロークエリログなど) を通じて、断続的な接続問題に関連していると思われる情報やエラーを確認します。詳細については、「[Aurora MySQL データベースのログ記録](aurora-mysql-troubleshooting-logging.md)」を参照してください。

**クライアントアプリケーションログ**  
データベースに接続するクライアントアプリケーションから詳細なログを収集します。アプリケーションログは、接続試行、エラー、関連情報をアプリケーションの視点から可視化します。これにより、接続文字列、認証情報、またはアプリケーションレベルの接続処理に関連する問題が明らかになる場合があります。  
一方、データベースログは、データベース側のエラー、スロークエリ、または接続問題の原因の可能性があるイベントに関するインサイトを提供します。詳細については、「[Aurora MySQL データベースのログ記録](aurora-mysql-troubleshooting-logging.md)」を参照してください。

**クライアント環境変数**  
プロキシ設定、SSL/TLS 設定、その他の関連変数など、クライアント側の環境変数や構成設定がデータベース接続に影響を与えていないかどうかを確認します。

**クライアントライブラリのバージョン**  
クライアントがデータベース接続に最新バージョンのデータベースドライバー、ライブラリ、またはフレームワークを使用していることを確認します。古いバージョンには、既知の問題や互換性の問題が含まれている可能性があります。

**クライアントネットワークキャプチャ**  
接続の問題の発生時に Wireshark や `tcpdump` などのツールを使用してクライアント側でネットワークキャプチャを実行します。これにより、クライアント側でネットワーク関連の問題や異常を特定できます。

**クライアントネットワークトポロジ**  
クライアントのネットワークトポロジを構成するファイアウォール、ロードバランサー、その他のコンポーネント (クライアントがデータベースに直接接続せずに、RDS Proxy や Proxy SQL を介して接続する場合など) を理解します。

**クライアントオペレーティングシステムの設定**  
ファイアウォールルール、ネットワークアダプター設定、その他の関連設定など、ネットワーク接続に影響を与える可能性があるクライアントのオペレーティングシステムの設定を確認します。

**接続プール設定**  
アプリケーションで接続プールメカニズムを使用している場合は、構成設定を確認し、プールメトリクス (アクティブな接続、アイドル接続、接続タイムアウトなど) をモニタリングして、プールが正しく機能していることを確認します。また、最大プールサイズ、最小プールサイズ、接続検証設定などのプール設定を参照し、正しく設定されていることを確認します。

**接続文字列**  
接続文字列には、通常、ホスト名やエンドポイント、ポート番号、データベース名、認証情報などのパラメータが含まれます。接続文字列を分析すると、接続問題を引き起こす可能性がある設定ミスや不正な設定を特定するのに役立ちます。例えば、ホスト名やポート番号が間違っていると、クライアントがデータベースインスタンスにアクセスできない場合があります。また、認証情報が無効であると、認証エラーや接続拒否になる可能性があります。さらに、接続文字列から、接続プール、タイムアウト、その他接続問題を起こす可能性がある接続固有の設定に関連する問題が明らかになる場合があります。クライアントアプリケーションで使用する完全な接続文字列を提供することは、クライアントの設定ミスを正確に特定するのに役立ちます。

**データベースメトリクス**  
接続の問題が発生したときに、CPU 使用率、メモリ使用率、ディスク I/O などのデータベースメトリクスをモニタリングします。これらのメトリクスは、DB インスタンスでリソースの競合やパフォーマンスの問題が発生していないかどうかを確認するのに役立ちます。

**DB エンジンバージョン**  
Aurora MySQL DB エンジンのバージョンに注意してください。AWS は、既知の問題やセキュリティの脆弱性に対処し、パフォーマンスの強化をもたらす更新を定期的にリリースしています。したがって、利用可能な最新バージョンにアップグレードすることを強くお勧めします。これらの更新には、接続、パフォーマンス、安定性に特に関連するバグ修正や機能強化が含まれることが多いためです。データベースのバージョン情報やその他の詳細を収集して提供することは、サポートが接続問題を効果的に診断して解決するのに役立ちます。

**ネットワークメトリクス**  
接続の問題が発生したときに、レイテンシー、パケット損失、スループットなどのネットワークメトリクスを収集します。`ping`、`traceroute`、ネットワークモニタリングツールなどのツールは、このようなデータの収集に役立ちます。

**ソースとクライアントの詳細**  
データベース接続を開始するアプリケーションサーバー、ロードバランサー、その他のコンポーネントの IP アドレスを確認します。これは、単一の IP アドレスであるか、IP アドレスの範囲 (CIDR 表記) である場合があります。ソースが Amazon EC2 インスタンスの場合、インスタンスタイプ、アベイラビリティーゾーン、サブネット ID、インスタンスに関連付けられたセキュリティグループ、プライベート IP アドレスやパブリック IP アドレスなどのネットワークインターフェイスの詳細を確認することも役立ちます。

収集したデータを徹底的に分析することで、設定ミス、リソースの制約、ネットワークの中断、その他断続的または永続的な接続問題の原因となっている根本的な問題を特定できます。この情報により、設定の調整、ネットワーク問題の解決、アプリケーションレベルの接続処理への対応など、ターゲットを絞ったアクションを実行できます。

## Aurora MySQL のデータベース接続のモニタリング
<a name="mysql-dbconn-monitor"></a>

接続問題のモニタリングおよびトラブルシューティングを行うには、以下のメトリクスと機能を使用できます。

**CloudWatch メトリクス**  
+ `CPUUtilization` – DB インスタンスの CPU 使用率が高いと、クエリの実行が遅くなり、接続のタイムアウトや拒否が発生する可能性があります。
+ `DatabaseConnections` – DB インスタンスへのアクティブな接続数をモニタリングします。接続数が多く、設定された最大許容数に近いと、接続の問題や接続プールの枯渇につながる可能性を示している場合があります。
+ `FreeableMemory` – 使用可能なメモリが少ないと、リソースの制約により、パフォーマンスの問題や接続の問題が発生する可能性があります。
+ `NetworkReceiveThroughput` および `NetworkTransmitThroughput` – ネットワークスループットの異常な急増や低下は、接続の問題やネットワークのボトルネックを示している可能性があります。

**Performance Insights メトリクス**  
Performance Insights を使用して Aurora MySQL の接続問題のトラブルシューティングを行うには、以下のようなデータベースメトリクスを分析します。  
+ Aborted\$1clients
+ Aborted\$1connects
+ Connections
+ max\$1connections
+ Threads\$1connected
+ Threads\$1created
+ Threads\$1running
これらのメトリクスは、接続のボトルネックの特定、ネットワークまたは認証の問題の検出、接続プールの最適化、効率的なスレッド管理の確保に役立ちます。詳細については、「[Aurora MySQL の Performance Insights のカウンター](USER_PerfInsights_Counters.md#USER_PerfInsights_Counters.Aurora_MySQL)」を参照してください。

**Performance Insights の機能**  
+ **データベース負荷** – データベース負荷を時間の経過とともに視覚化し、接続の問題やパフォーマンスの低下と関連付けます。
+ **SQL 統計** – SQL 統計を分析して、接続問題の原因の可能性がある非効率的なクエリやデータベースオペレーションを特定します。
+ **上位のクエリ** – リソース集約度の最も高いクエリを特定して分析します。これにより、接続問題を引き起こしている可能性があるパフォーマンスのボトルネックや長時間実行されているクエリを特定できます。

これらのメトリクスをモニタリングして Performance Insights を活用することで、データベースインスタンスのパフォーマンス、リソースの使用状況、接続問題を引き起こしている可能性があるボトルネックを可視化できます。以下に例を示します。
+ `DatabaseConnections` が最大許容数に近い場合は、接続プールの枯渇や不適切な接続処理を示しており、接続問題につながる可能性があります。
+ `CPUUtilization` が高いか、`FreeableMemory` が低い場合は、リソースの制約を示していることがあり、クエリの実行が遅くなり、接続のタイムアウトや拒否が発生する可能性があります。
+ **上位のクエリ**や **SQL 統計**を分析すると、接続問題の原因となっている可能性がある非効率的なクエリやリソース集約度の高いクエリを特定するのに役立ちます。

さらに、CloudWatch Logs をモニタリングしてアラームを設定することは、接続問題が深刻化する前に未然に特定して対応するのに役立ちます。

以上のメトリクスやツールは貴重なインサイトを提供できますが、他のトラブルシューティングステップと組み合わせて使用する必要があることに注意してください。ネットワーク設定、セキュリティグループのルール、アプリケーションレベルの接続処理も確認することで、Aurora MySQL DB インスタンスの接続問題を包括的に診断して解決できます。

### Aurora MySQL の追加モニタリング
<a name="mysql-dbconn-monitor-ams"></a>

**CloudWatch メトリクス**  
+ `AbortedClients` – 適切に閉じられていないクライアント接続の数を追跡します。
+ `AuroraSlowConnectionHandleCount` – 接続問題やパフォーマンスのボトルネックの可能性を示す、接続処理の遅延回数を追跡します。
+ `AuroraSlowHandshakeCount` – 接続問題の可能性を示している場合もある、低速ハンドシェイクオペレーションの数を測定します。
+ `ConnectionAttempts` – Aurora MySQL DB インスタンスへの接続試行回数を測定します。

**グローバルステータス変数**  
`Aurora_external_connection_count` – DB インスタンスへのデータベース接続の数を示します。ただし、データベースのヘルスチェックに使用した RDS サービス接続は除きます。

これらのメトリクスとグローバルステータス変数をモニタリングすることで、Amazon Aurora MySQL インスタンスで接続問題を引き起こしている可能性がある接続パターン、エラー、潜在的なボトルネックを可視化できます。

例えば、`AbortedClients` または `AuroraSlowConnectionHandleCount` の数が多い場合は、接続問題を示している可能性があります。

さらに、CloudWatch アラームと通知を設定すると、接続問題が深刻化してアプリケーションのパフォーマンスに影響を与える前に未然に特定して対応できます。

## Aurora MySQL の接続エラーコード
<a name="mysql-dbconn-errors"></a>

Aurora MySQL データベースの一般的な接続エラーおよびエラーコードと説明を以下に示します。

**エラーコード 1040: 接続数が多すぎる**  
このエラーは、データベースサーバーが許可する最大数を超えてクライアントが接続を確立しようとすると発生します。次の原因が考えられます。  
+ 接続プールの設定ミス – 接続プールメカニズムを使用している場合は、最大プールサイズの設定が高すぎないこと、および接続が適切にプールに戻されていることを確認します。
+ データベースインスタンス設定 – データベースインスタンスの最大許容接続数の設定を確認し、必要に応じて `max_connections` パラメータを設定して調整します。
+ 高い同時実行数 – 複数のクライアントやアプリケーションがデータベースに同時に接続している場合、最大許容接続数の制限に達している可能性があります。

**エラーコード 1045: ユーザー '...'@'...' に対するアクセス拒否 (パスワードの使用: YES/NO）**  
このエラーは、データベースに接続しようとして認証に失敗したことを示します。次の原因が考えられます。  
+ 認証プラグインの互換性 – クライアントが使用している認証プラグインがデータベースサーバーの認証メカニズムと互換性があるかどうかを確認します。
+ ユーザー名またはパスワードが正しくない – 接続文字列または認証メカニズムで正しいユーザー名とパスワードを使用していることを確認します。
+ ユーザーアクセス許可 – 指定したホストまたはネットワークからデータベースインスタンスに接続するために必要なアクセス許可をユーザーが持っていることを確認します。

**エラーコード 1049: 不明なデータベース '...'**  
このエラーは、クライアントがサーバーに存在しないデータベースに接続しようとしていることを示します。次の原因が考えられます。  
+ データベースが作成されていない – 指定したデータベースがデータベースサーバーに作成されていることを確認します。
+ データベース名が正しくない — 接続文字列またはクエリで使用しているデータベース名が正しいことを再確認します。
+ ユーザーアクセス許可 – 指定したデータベースにアクセスするために必要なアクセス許可をユーザーが持っていることを確認します。

**エラーコード 1153: 'max\$1allowed\$1packet' バイトを超えるパケットを取得した**  
このエラーは、データベースサーバーが許可する最大パケットサイズを超えるデータをクライアントが送受信しようとすると発生します。次の原因が考えられます。  
+ 大量のクエリまたは結果セット – 大量のデータを含むクエリを実行する場合、パケットサイズ制限を超える可能性があります。
+ パケットサイズの設定ミス – データベースサーバーの `max_allowed_packet` 設定を確認し、必要に応じて調整します。
+ ネットワーク設定の問題 – 必要なパケットサイズがネットワーク設定 (MTU サイズなど) で許可されていることを確認します。

**エラーコード 1226: ユーザー '...' が 'max\$1user\$1connections' リソースを超えた (現在の値: ...)**  
このエラーは、データベースサーバーが許可する同時接続の最大数をユーザーが超えたことを示します。次の原因が考えられます。  
+ 接続プールの設定ミス – 接続プールメカニズムを使用している場合は、ユーザーの接続制限に対してプールの最大サイズを高すぎないように設定します。
+ データベースインスタンスの設定 — データベースインスタンス `max_user_connections` 設定を確認し、必要に応じて調整します。
+ 高い同時実行数 – 複数のクライアントやアプリケーションが同じユーザーを使用してデータベースに同時に接続している場合、ユーザー別の接続制限に達している可能性があります。

**エラーコード 2003: '...' で MySQL サーバーに接続できない (10061)**  
このエラーは通常、クライアントがデータベースサーバーとの TCP/IP 接続を確立できない場合に発生します。以下のような、さまざまな問題が原因である可能性があります。  
+ データベースインスタンスのステータス – データベースインスタンスが `available` 状態であり、メンテナンスやバックアップオペレーション中でないことを確認します。
+ ファイアウォールルール – ファイアウォール (オペレーティングシステム、ネットワーク、またはセキュリティグループ) が、指定したポート (MySQL の場合は通常 3306) で接続をブロックしていないかどうかを確認します。
+ ホスト名またはエンドポイントが正しくない — 接続文字列で使用しているホスト名またはエンドポイントが正しいこと、およびデータベースインスタンスと一致していることを確認します。
+ ネットワーク接続の問題 – クライアントマシンがネットワーク経由でデータベースインスタンスにアクセスできることを確認します。ネットワークの停止、ルーティングの問題、VPC またはサブネットの設定ミスがないことを確認します。

**エラーコード 2005: 不明な MySQL サーバーホスト '...' (11001)**  
このエラーは、クライアントがデータベースサーバーのホスト名またはエンドポイントを IP アドレスに解決できない場合に発生します。次の原因が考えられます。  
+ DNS 解決の問題 – クライアントマシンが DNS を使用してホスト名を正しく解決できることを確認します。DNS 設定、DNS キャッシュを確認し、ホスト名の代わりに IP アドレスを使用してみます。
+ ホスト名またはエンドポイントが正しくない — 接続文字列で使用しているホスト名またはエンドポイントが正しいことを再確認します。
+ ネットワーク設定の問題 – クライアントのネットワーク設定 (VPC、サブネット、ルートテーブルなど) で、DNS 解決とデータベースインスタンスへの接続が許可されていることを確認します。

**エラーコード 2026: SSL 接続エラー**  
このエラーは、接続の試行中に SSL/TLS 設定または証明書の検証に問題がある場合に発生します。次の原因が考えられます。  
+ 証明書の有効期限 – サーバーで使用している SSL/TLS 証明書が期限切れで更新する必要があるかどうかを確認します。
+ 証明書の検証の問題 – クライアントがサーバーの SSL/TLS 証明書を正しく検証できること、および証明書が信頼できることを確認します。
+ ネットワーク設定の問題 – ネットワーク設定で SSL/TLS 接続が許可されており、SSL/TLS ハンドシェイクプロセスがブロックまたは干渉されていないことを確認します。
+ SSL/TLS 設定の不一致 – クライアントとサーバーの SSL/TLS 設定 (暗号スイートやプロトコルバージョンなど) に互換性があることを確認します。

各エラーコードの詳細な説明と潜在的な原因を理解することで、Aurora MySQL データベースを使用する際の接続問題をより適切にトラブルシューティングして解決できます。

## Aurora MySQL のパラメータチューニングの推奨事項
<a name="mysql-dbconn-params"></a>

**最大接続数**  
これらのパラメータを調整すると、最大許容接続数に達したために発生する接続問題を防止できます。これらの値がアプリケーションの同時実行の要件とリソースの制約に基づいて適切に設定されていることを確認します。  
+ `max_connections` – このパラメータは、DB インスタンスに許可される同時接続の最大数を指定します。
+ `max_user_connections` – このパラメータは、ユーザーの作成時や変更時に指定でき、特定のユーザーアカウントに許可される同時接続の最大数を設定します。

**ネットワークバッファサイズ**  
これらの値を増やすと、特に大規模なデータ転送や結果セットを伴うワークロードの場合、ネットワークパフォーマンスを向上させることができます。ただし、バッファサイズが大きいほどメモリ消費量も増える可能性があるので、注意してください。  
+ `net_buffer_length` – このパラメータは、クライアント接続と結果バッファの初期サイズを設定し、メモリ使用量とクエリパフォーマンスのバランスを取ります。
+ `max_allowed_packet` – このパラメータは、DB インスタンスが送受信できる単一のネットワークパケットの最大サイズを指定します。

**ネットワーク圧縮 (クライアント側）**  
ネットワーク圧縮を有効にすると、ネットワーク帯域幅の使用量を減らすことができますが、クライアント側とサーバー側の両方で CPU オーバーヘッドが増加する可能性があります。  
+ `compress` – このパラメータは、クライアント/サーバー通信のネットワーク圧縮を有効または無効にします。
+ `compress_protocol` – このパラメータは、ネットワーク通信に使用する圧縮プロトコルを指定します。

**ネットワークパフォーマンスのチューニング**  
これらのタイムアウトを調整すると、アイドル状態の接続を管理し、リソースの枯渇を防ぐのに役立ちますが、値が低いと接続が早期に終了する可能性があるため、注意が必要です。  
+ `interactive_timeout` – このパラメータは、サーバーがインタラクティブ接続でアクティビティを待機し始めてから接続を閉じるまでの秒数を指定します。
+ `wait_timeout` – このパラメータは、サーバーが非インタラクティブ接続でアクティビティを待機し始めてから接続を閉じるまでの秒数を決定します。

**ネットワークタイムアウト設定**  
これらのタイムアウトを調整すると、接続の遅延や応答不良に関連する問題に対処できます。ただし、設定を短くしすぎると、接続が早期に失敗する可能性があるため、注意してください。  
+ `net_read_timeout` – このパラメータは、読み取りオペレーションを終了するまでに、接続からの追加データを待機する秒数を指定します。
+ `net_write_timeout` – このパラメータは、書き込みオペレーションを終了するまでに、ブロックが接続に書き込まれるのを待機する秒数を決定します。

## Aurora MySQL のデータベース接続問題のトラブルシューティングの例
<a name="mysql-dbconn-examples"></a>

以下の例は、Aurora MySQL のデータベース接続問題を特定してトラブルシューティングを行う方法を示しています。

### 例 1: 失敗した接続試行のトラブルシューティング
<a name="mysql-dbconn-example1"></a>

接続の試行は、認証の失敗、SSL/TLS ハンドシェイクの失敗、`max_connections` 制限の到達、DB インスタンスでのリソース制約など、いくつかの理由で失敗する可能性があります。

失敗した接続の数は、Performance Insights または次のコマンドを使用して追跡できます。

```
mysql> show global status like 'aborted_connects';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| Aborted_connects | 7     |
+------------------+-------+
1 row in set (0.00 sec)
```

`Aborted_connects` の数が時間とともに増える場合、アプリケーションに断続的な接続の問題があることが考えられます。

[Aurora の高度な監査機能](AuroraMySQL.Auditing.md)を使用して、クライアント接続の接続数と切断数をログ記録できます。これを行うには、DB クラスターパラメータグループで以下のパラメータを設定します。
+ `server_audit_logging` = `1`
+ `server_audit_events` = `CONNECT`

 次に示すのは、失敗したログインの監査ログからの抜粋です。

```
1728498527380921,auora-mysql-node1,user_1,172.31.49.222,147189,0,FAILED_CONNECT,,,1045
1728498527380940,auora-mysql-node1,user_1,172.31.49.222,147189,0,DISCONNECT,,,0
```

コードの説明は以下のとおりです。
+ `1728498527380921` — ログイン失敗が発生したときのエポックタイムスタンプ
+ `aurora-mysql-node1` – 接続が失敗した Aurora MySQL クラスターのノードのインスタンス識別子
+ `user_1` — ログインが失敗したデータベースユーザーの名前
+ `172.31.49.222` – 接続を確立したクライアントのプライベート IP アドレス
+ `147189` – 失敗したログインの接続 ID
+ `FAILED_CONNECT` – 接続が失敗したことを示します。
+ `1045` – リターンコード。ゼロ以外の値はエラーを示します。この場合、`1045` はアクセス拒否に対応します。

詳細については、MySQL ドキュメントの「[サーバーエラーコード](https://dev.mysql.com/doc/mysql-errors/5.7/en/server-error-reference.html)」と「[クライアントエラーコード](https://dev.mysql.com/doc/mysql-errors/5.7/en/client-error-reference.html)」を参照してください。

 また、Aurora MySQL エラーログを調べて、次のような関連するエラーメッセージを確認することもできます。

```
2024-10-09T19:26:59.310443Z 220 [Note] [MY-010926] [Server] Access denied for user 'user_1'@'172.31.49.222' (using password: YES) (sql_authentication.cc:1502)
```

### 例 2: 異常なクライアント切断のトラブルシューティング
<a name="mysql-dbconn-example2"></a>

Performance Insights または次のコマンドを使用して、異常なクライアント切断の数を追跡できます。

```
mysql> show global status like 'aborted_clients';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| Aborted_clients | 9     |
+-----------------+-------+
1 row in set (0.01 sec)
```

`Aborted_clients` の数が時間とともに増える場合、アプリケーションはデータベースへの接続を正しく閉じていません。接続が適切に閉じられていないと、リソースのリークやパフォーマンスの問題が発生する可能性があります。接続を不必要に開いたままにすると、メモリやファイル記述子などのシステムリソースが消費され、最終的にはアプリケーションやサーバーが応答しなくなるか再起動する可能性があります。

次のクエリを使用して、接続を適切に閉じていないアカウントを特定できます。このクエリは、ユーザーアカウント名、ユーザーの接続元のホスト、閉じていない接続の数、閉じていない接続の割合を取得します。

```
SELECT
    ess.user,
    ess.host,
    (a.total_connections - a.current_connections) - ess.count_star AS not_closed,
    (((a.total_connections - a.current_connections) - ess.count_star) * 100) / (a.total_connections - a.current_connections) AS pct_not_closed
FROM
    performance_schema.events_statements_summary_by_account_by_event_name AS ess
    JOIN performance_schema.accounts AS a ON (ess.user = a.user AND ess.host = a.host)
WHERE
    ess.event_name = 'statement/com/quit'
    AND (a.total_connections - a.current_connections) > ess.count_star;

+----------+---------------+------------+----------------+
| user     | host          | not_closed | pct_not_closed |
+----------+---------------+------------+----------------+
| user1    | 172.31.49.222 |          1 |        33.3333 |
| user1    | 172.31.93.250 |       1024 |        12.1021 |
| user2    | 172.31.93.250 |         10 |        12.8551 |
+----------+---------------+------------+----------------+
3 rows in set (0.00 sec)
```

接続を閉じていないユーザーアカウントとホストを特定したら、接続を正常に閉じていないコードのチェックに進むことができます。

例えば、Python の MySQL コネクタでは、接続オブジェクトの `close()` メソッドを使用して接続を閉じます。データベースへの接続を確立して、クエリを実行し、接続を閉じる関数の例を次に示します。

```
import mysql.connector

def execute_query(query):
    # Establish a connection to the database
    connection = mysql.connector.connect(
        host="your_host",
        user="your_username",
        password="your_password",
        database="your_database"
    )

    try:
        # Create a cursor object
        cursor = connection.cursor()

        # Execute the query
        cursor.execute(query)

        # Fetch and process the results
        results = cursor.fetchall()
        for row in results:
            print(row)

    finally:
        # Close the cursor and connection
        cursor.close()
        connection.close()
```

この例では、例外が発生するかどうかにかかわらず、`connection.close()` メソッドを `finally` ブロックで呼び出して接続が閉じられていることを確認しています。

### 例 3: IAM 接続試行失敗のトラブルシューティング
<a name="mysql-dbconn-example3"></a>

AWS Identity and Access Management (IAM) ユーザーとの接続は、次のようないくつかの理由で失敗する可能性があります。
+ IAM ポリシー設定が正しくない
+ 期限切れのセキュリティ認証情報
+ ネットワーク接続の問題
+ データベースのアクセス許可の不一致

これらの認証エラーをトラブルシューティングするには、Amazon Relational Database Service (RDS) または Aurora データベースで `iam-db-auth-error` ログエクスポート機能を有効にします。これにより、Amazon RDS または Amazon Aurora クラスターの CloudWatch Log グループで詳細な認証エラーメッセージを表示できます。

有効にすると、これらのログを確認して、IAM 認証失敗の具体的な原因を特定して解決できます。

例えば、次のようになります。

```
2025-09-22T12:02:30,806 [ERROR] Failed to authorize the connection request for user 'user_1' due to an internal IAM DB Auth error. (Status Code: 500, Error Code: InternalError)
```

and

```
2025-09-22T12:02:51,954 [ERROR] Failed to authenticate the connection request for user 'user_2' because the provided token is malformed or otherwise invalid. (Status Code: 400, Error Code: InvalidToken)
```

トラブルシューティングのガイダンスについては、IAM DB 認証の [Aurora](UsingWithRDS.IAMDBAuth.Troubleshooting.md) トラブルシューティングガイドを参照してください。

# Aurora MySQL データベースのクエリパフォーマンスのトラブルシューティング
<a name="aurora-mysql-troubleshooting-query"></a>

MySQL は、クエリプランの評価方法に影響するシステム変数、切り替え可能な最適化、オプティマイザとインデックスのヒント、オプティマイザのコストモデルを通じて[クエリオプティマイザの制御](https://dev.mysql.com/doc/refman/8.0/en/controlling-optimizer.html)を提供します。これらのデータポイントは、さまざまな MySQL 環境を比較するときだけでなく、以前のクエリ実行プランを現在の実行プランと比較したり、任意の時点の MySQL クエリの全体的な実行状況を把握したりするのに役立ちます。

クエリのパフォーマンスは、実行プラン、テーブルスキーマとサイズ、統計、リソース、インデックス、パラメータ設定など、さまざまな要因に左右されます。クエリの調整には、ボトルネックの特定と実行パスの最適化が必要です。
+ クエリの実行プランを見つけ、クエリが適切なインデックスを使用しているかどうかを確認します。`EXPLAIN` を使用し、各プランの詳細を確認することで、クエリを最適化できます。
+ Aurora MySQL バージョン 3 (MySQL 8.0 コミュニティエディションと互換性あり) は `EXPLAIN ANALYZE` ステートメントを使用します。`EXPLAIN ANALYZE` ステートメントは、MySQL がクエリのどこで時間を費やしているのか、またその理由を示すプロファイリングツールです。`EXPLAIN ANALYZE` を使用すると、Aurora MySQL はクエリを計画、準備、実行しつつ、行をカウントし、実行プランのさまざまなポイントで費やされた時間を測定します。クエリが完了すると、`EXPLAIN ANALYZE` は、クエリ結果の代わりにプランとその測定値を印刷します。
+ `ANALYZE` ステートメントを使用してスキーマの統計情報を最新の状態に維持してください。クエリオプティマイザは、統計が古いと不適切な実行プランを選択することがあります。これにより、テーブルとインデックスの両方のカーディナリティの推定が不正確になり、クエリのパフォーマンスが低下する可能性があります。[innodb\$1table\$1stats](https://dev.mysql.com/doc/refman/8.0/en/innodb-persistent-stats.html#innodb-persistent-stats-tables) テーブルの `last_update` 列には、スキーマ統計が最後に更新された時刻が表示されます。これは「古くなっている」ことを示す良い指標です。
+ データの分布の歪みなど、テーブルのカーディナリティに考慮されていないその他の問題が発生することもあります。詳細については、MySQL ドキュメントの「[InnoDB テーブルの ANALYZE TABLE の複雑度の推定](https://dev.mysql.com/doc/refman/8.0/en/innodb-analyze-table-complexity.html)」と「[MySQL のヒストグラム統計](https://dev.mysql.com/blog-archive/histogram-statistics-in-mysql/)」を参照してください。

## クエリにかかった時間の確認
<a name="ams-query-time"></a>

クエリにかかった時間を決定する方法は次のとおりです。
+ [プロファイリング](https://dev.mysql.com/doc/refman/8.0/en/show-profile.html)
+ [パフォーマンススキーマ](https://dev.mysql.com/doc/refman/8.0/en/performance-schema.html)
+ [クエリオプティマイザ](https://dev.mysql.com/doc/refman/8.0/en/controlling-optimizer.html)

**プロファイリング**  
デフォルトでは、プロファイリングは無効です。プロファイリングを有効にし、スロークエリを実行してプロファイルを確認します。  

```
SET profiling = 1;
Run your query.
SHOW PROFILE;
```

1. 最も多くの時間が費やされているステージを特定します。MySQL ドキュメントの「[一般的なスレッド状態](https://dev.mysql.com/doc/refman/8.0/en/general-thread-states.html)」によると、`SELECT` ステートメントの行の読み取りと処理は、多くの場合、特定のクエリの存続期間中で最も長い実行状態です。`EXPLAIN` ステートメントを使用すると、MySQL がこのクエリを実行する方法を理解できます。

1. スロークエリログを確認して `rows_examined` と `rows_sent` を評価し、各環境でワークロードが類似していることを確認します。詳細については、「[Aurora MySQL データベースのログ記録](aurora-mysql-troubleshooting-logging.md)」を参照してください。

1. 特定されたクエリの一部であるテーブルに対して、以下のコマンドを実行します。

   ```
   SHOW TABLE STATUS\G;
   ```

1. 各環境でクエリを実行する前と後に、次の出力をキャプチャします。

   ```
   SHOW GLOBAL STATUS;
   ```

1. 各環境で以下のコマンドを実行して、このサンプルクエリのパフォーマンスに影響する他のクエリ/セッションがないかどうかを確認します。

   ```
   SHOW FULL PROCESSLIST;
   
   SHOW ENGINE INNODB STATUS\G;
   ```

   サーバー上のリソースがビジー状態になると、クエリを含むサーバー上の他のすべての操作に影響することがあります。また、クエリの実行時に定期的に情報をキャプチャしたり、有用な間隔で情報をキャプチャする `cron` ジョブを設定することもできます。

**Performance Schema**  
パフォーマンススキーマは、パフォーマンスへの影響を最小限に抑えながら、サーバーのランタイムパフォーマンスに関する有用な情報を提供します。これは DB インスタンスに関するスキーマ情報を提供する `information_schema` とは異なります。詳細については、「[Aurora MySQL における Performance Insights のPerformance Schema の概要](USER_PerfInsights.EnableMySQL.md)」を参照してください。

**クエリオプティマイザトレース**  
特定の[クエリプランが実行対象として選択された](https://dev.mysql.com/doc/refman/8.0/en/execution-plan-information.html)理由を理解するために、MySQL クエリオプティマイザにアクセスするように `optimizer_trace` をセットアップできます。  
オプティマイザトレースを実行すると、オプティマイザが使用できるすべてのパスとその選択に関する詳細な情報が表示されます。  

```
SET SESSION OPTIMIZER_TRACE="enabled=on"; 
SET optimizer_trace_offset=-5, optimizer_trace_limit=5;

-- Run your query.
SELECT * FROM table WHERE x = 1 AND y = 'A';

-- After the query completes:
SELECT * FROM information_schema.OPTIMIZER_TRACE;
SET SESSION OPTIMIZER_TRACE="enabled=off";
```

## クエリオプティマイザ設定の確認
<a name="ams-query-parameters"></a>

Aurora MySQL バージョン 3 (MySQL 8.0 コミュニティエディションと互換性あり) には、Aurora MySQL バージョン 2 (MySQL 5.7 コミュニティエディションと互換性あり) と比較して、オプティマイザ関連の多くの変更があります。`optimizer_switch` にカスタム値がある場合は、デフォルトの違いを確認して、ワークロードに最適な `optimizer_switch` 値を設定することをお勧めします。また、Aurora MySQL バージョン 3 で使用できるオプションをテストして、クエリがどのように実行されるかを調べることをお勧めします。

**注記**  
Aurora MySQL バージョン 3 では、[innodb\$1stats\$1persistent\$1sample\$1pages](https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_stats_persistent_sample_pages) パラメータのコミュニティデフォルト値である 20 を使用しています。

`optimizer_switch` 値を表示するには、次のコマンドを使用できます。

```
SELECT @@optimizer_switch\G;
```

次の表は、Aurora MySQL バージョン 2 および 3 のデフォルトの `optimizer_switch` 値を示しています。


| 設定 | Aurora MySQL バージョン 2 | Aurora MySQL バージョン 3 | 
| --- | --- | --- | 
| batched\$1key\$1access | 化 | 化 | 
| block\$1nested\$1loop | オン | オン | 
| condition\$1fanout\$1filter | オン | オン | 
| derived\$1condition\$1pushdown | – | オン | 
| derived\$1merge | オン | オン | 
| duplicateweedout | オン | オン | 
| engine\$1condition\$1pushdown | オン | オン | 
| firstmatch | オン | オン | 
| hash\$1join | 化 | オン | 
| hash\$1join\$1cost\$1based | オン | – | 
| hypergraph\$1optimizer | – | 化 | 
| index\$1condition\$1pushdown | オン | オン | 
| index\$1merge | オン | オン | 
| index\$1merge\$1intersection | オン | オン | 
| index\$1merge\$1sort\$1union | オン | オン | 
| index\$1merge\$1union | オン | オン | 
| loosescan | オン | オン | 
| materialization | オン | オン | 
| mrr | オン | オン | 
| mrr\$1cost\$1based | オン | オン | 
| prefer\$1ordering\$1index | オン | オン | 
| semijoin | オン | オン | 
| skip\$1scan | – | オン | 
| subquery\$1materialization\$1cost\$1based | オン | オン | 
| subquery\$1to\$1derived | – | 化 | 
| use\$1index\$1extensions | オン | オン | 
| use\$1invisible\$1indexes | – | 化 | 

詳細については、MySQL ドキュメントの「[切り替え可能な最適化 (MySQL 5.7)](https://dev.mysql.com/doc/refman/5.7/en/switchable-optimizations.html)」と「[切り替え可能な最適化 (MySQL 8.0)](https://dev.mysql.com/doc/refman/8.0/en/switchable-optimizations.html)」を参照してください。