ApsaraDB RDS for MySQL インスタンスのストレージが一時ファイルによって枯渇すると、システムはデータ損失を防ぐために自動的にインスタンスをロックします。本ドキュメントでは、この現象が発生する原因と、インスタンスのロック解除方法、および再発防止策について説明します。
インスタンスがロックされる原因
MySQL がデータのソートやグループ化、テーブル結合を伴う SQL ステートメントを実行すると、一時ファイルが蓄積されます。また、大規模トランザクションのバイナリログ (binlog) キャッシュファイルも、トランザクションが進行中でまだコミットされていない間、ストレージを消費します。
ストレージが枯渇すると、システムはデータ損失を防ぐために RDS インスタンスを自動的にロックし、ご利用の RDS インスタンスへのデータ書き込みができなくなります。
インスタンスのロック解除
以下のオプションを順に試してください。インスタンスのロックが解除された時点で作業を終了します。
オプション 1:ストレージ容量の拡張
インスタンスのストレージ容量を拡張します。拡張後、システムは約 5 分以内に自動的にインスタンスのロックを解除します。詳細については、「ApsaraDB RDS for MySQL インスタンスの仕様変更」をご参照ください。
オプション 2:インスタンスを再起動して一時ファイルを解放
ストレージ拡張が不可能な場合は、インスタンスの MySQL メジャーバージョンに応じて以下のいずれかの方法を使用します。
-
MySQL 5.6:一時表領域はシステム表領域 ibdata1 内に存在します。インスタンスを再起動しても一時ファイルは解放されません。プライマリノードとセカンダリノードの ibdata1 サイズを比較し、セカンダリノードの ibdata1 が小さい場合は、高可用性 (HA) スイッチオーバーを実行した後、元のセカンダリノードを再構築してスペースを解放します。両方のノードの ibdata1 が大きい場合は、新しいインスタンスを作成し、DTS を使用してデータを移行します。
-
MySQL 5.7:一時表領域は独立したファイル ibtmp1 内に存在します。インスタンスを再起動すると一時ファイルが解放されます。高可用性インスタンスの場合は、プライマリノードとセカンダリノードの ibtmp1 サイズを比較し、セカンダリノードの ibtmp1 が小さい場合は、HA スイッチオーバーを実行した後、元のセカンダリノードを再起動してスペースを解放します。また、
innodb_temp_data_file_pathパラメーターをibtmp1:12M:autoextend:max:10Gに設定することで、ibtmp1 のサイズを 10 GB に制限できます。この変更を有効にするには、インスタンスの再起動が必要です。 -
MySQL 8.0 および 8.4:インスタンスがロックされると、すべてのユーザーセッションが終了されます。終了されたセッションは自動的にロールバックを開始します。ロールバックの持続時間は、実行されていたクエリに依存します。トランザクションのロールバックが完了すると、インスタンスストレージが解放されます。
innodb_temp_data_file_path パラメーターは、一時表領域ファイルのサイズと拡張動作を制御します。このパラメーターは MySQL 5.7 および 8.0 でサポートされており、デフォルト値は ibtmp1:12M:autoextend です。MySQL 5.6 はこのパラメーターをサポートしていません。
大規模テーブルに対する DDL 操作(インデックスの追加など)は、ソート用の一時ファイルを生成します。デフォルトでは、これらのファイルにサイズ制限がなく、無制限に増加する可能性があります。このような操作を実行する前に、インスタンスに十分なストレージがあることを確認してください。
インスタンスの再起動 ボタンが 基本情報 ページで選択不可になっている場合は、以下の回避策を使用します。
-
インスタンス ページに移動します。上部のナビゲーションバーでインスタンスが配置されているリージョンを選択し、インスタンス ID をクリックします。
-
左側のナビゲーションウィンドウで パラメーター をクリックします。
-
編集可能なパラメーター タブで、強制再起動 列に Yes と表示されている任意のパラメーターを見つけ、その値を変更します。
オプション 3:問題を引き起こしているセッションの特定と終了
再起動後もインスタンスがロックされたままの場合は、一時ファイルを生成しているセッションを特定して終了します。
-
Data Management (DMS) を使用してインスタンスに接続します。
-
次のステートメントを実行して、アクティブセッションの一覧を表示します。
show processlist -
結果を State 列で並べ替えます。State に Copy to tmp table または Sending data と表示されているセッションは、大量の一時ファイルを使用していることを示します。問題のあるセッションの ID を記録します。
-
セッションを終了します。
kill [$ID];[$ID]は、前のステップで取得したセッション ID に置き換えてください。重要セッションを終了する前に、実行中のサービスに影響を与えないことを確認してください。
再発防止策
インスタンスのロックが解除された後は、再発を防ぐために以下の手順を実施してください。
ストレージの自動拡張の有効化
使用量がしきい値に近づいた際にシステムが自動的にストレージを拡張するよう、ストレージの自動拡張を構成します。詳細については、「ApsaraDB RDS for MySQL インスタンスのストレージ自動拡張の設定」をご参照ください。
一時ファイルを生成する SQL ステートメントの最適化
特定の SQL ステートメントが一時テーブルを使用しているかどうかを確認するには、EXPLAIN を実行して Extra 列を確認します。Using temporary が表示される場合、そのステートメントは一時テーブルを生成しています。
explain select * from alarm group by created_on order by default;
一時ファイルの使用量を削減するには、以下の対策を実施します。
-
大規模な結果セットに対する ORDER BY や GROUP BY を頻繁に実行しないようにクエリを書き換えます。
-
フルテーブルソートを回避するために、適切なインデックスを追加します。
-
ビジネス要件に基づいて
tmp_table_sizeおよびmax_heap_table_sizeの値を増やすことも可能です。ただし、ディスクリソースよりもメモリリソースの方が重要であるため、この方法は推奨されません。
大規模トランザクションによる一時ストレージの削減
大規模トランザクションは進行中に binlog キャッシュファイルをディスクに書き込みます。これを削減するには、以下の対策を実施します。
-
大規模なバッチ操作をより小さなトランザクションに分割します。
-
多数の接続で複数の大規模トランザクションを並列実行しないようにします。
-
一時ファイルが占有するストレージを削減するために、大規模トランザクションには短時間接続を使用します。
-
ビジネス要件に基づいて
binlog_cache_sizeの値を増やすことも可能です。ただし、この方法は使用しないことを推奨します。
ディスク使用率のモニタリング
ディスク使用率を 80 % 未満に保ちます。ストレージが枯渇する前に不要なデータを削除したり、大規模なデータセットを分割したりできるよう、モニタリングアラートを設定します。
次のステップ
一時ファイルを削除してインスタンスのロックを解除できない場合は、他の種類のファイルを削除してディスク使用量を削減します。以下のトピックをご参照ください。