ある日、実稼働環境(データベースインスタンス)がアラームを発し、ディスク使用率が高すぎます!
検査の結果、mysqlデータディレクトリのibtmp1ファイルが大きすぎて30GBに達していることがわかりました。
1. ibtmp1ファイルは何をしますか?
mysql公式ドキュメント:https://dev.mysql.com/doc/refman/5.7/en/innodb-temporary-tablespace.html
一時テーブルをクエリするときにデータを格納するために使用されます。
2. ibtmp1が成長した理由は何ですか?
主にSQLに関連しており、特に多数のグループ化集計、並べ替え、結合クエリSQLに関連しています。
通常、次の条件によりiptmp1が上昇します。
- クエリステートメントは、最初にtemp_table_size(メモリ割り当て)の量をクエリし、一時ストレージの量がこのパラメータ制限を超えると、iptmp1のスペースに適用されます。
- GROUPBYによるselectorder groupにインデックスフィールドがない場合、またはgroup by + orderbyの句フィールドが異なる場合。
- 選択(選択)サブクエリ
- select ... from ...テーブルデータコピーに挿入
- select union selectunionステートメント
注:一時テーブルが解放された後、スペースは解放されますが、ディスクスペースは解放されず、空きスペースは再利用できます。ディスクスペースの解放は再起動のみ可能
三、解決策
1. SQLを確認してください!
遅いクエリログから遅いSQLを見つけます(サブクエリを含むSQLに焦点が当てられています)。サブクエリの結果セットが大きすぎない(返される行が多すぎる)こと、および結果セットを減らすことができることを確認してください。ここで、サブクエリの条件。
または、図に示すように、showprocesslistを介してクエリを実行します。
SQLが遅すぎて、サブクエリの結果セットが大きすぎてmysqlスレッドがスタックするため、ここにいます。最適化後、iptmp1のファイルサイズは正常です。
2.My.cnfは一時ファイルのサイズ制限を構成します
[mysqld]
innodb_temp_data_file_path=ibtmp1:12M:autoextend:max:500M
一時ファイルが500Mに増加すると、一時テーブルを必要とするSQLクエリ(サブクエリなど)を実行すると、エラーが報告されるため、お勧めしません。