ApsaraDB RDS for MySQL インスタンスのストレージが不足すると、データ損失を防ぐために自動的に読み取り専用にロックされます。どのファイルタイプが容量を消費しているかを特定し、それぞれの原因を解決してください。
緊急対応
インスタンスがすでにロックされている (読み取り専用) 場合は、直ちにディスクを拡張して書き込みを復元してください。サービスの復旧後に、すべてのクリーンアップと根本原因の修正を実行してください。
-
RDS コンソールで、インスタンス ID をクリックします。
-
手動でディスクのサイズ変更を行い、インスタンスのロックを解除します。
サイズ変更が完了してから約 5 分以内にインスタンスのロックが解除されます。進捗状況は タスクセンターで確認できます。
ディスクのサイズ変更は短期的な回避策です。後述する根本原因にも対処しない限り、ストレージは再び満杯になります。
ストレージ使用量の表示
ApsaraDB RDS for MySQL インスタンスのストレージ容量には、ユーザーデータ、システムデータ、ログ、一時ファイルが含まれます。
-
RDS コンソールで、インスタンス ID をクリックします。
-
左側メニューで、[モニタリングとアラート] > [標準モニタリング] を選択します。
-
[MySQL ストレージ容量の使用状況] ビューを探します。ビューのタイトルの横にあるアイコンをクリックすると、各パラメーターの説明が表示されます。
詳細な監視手順については、「監視情報の表示」をご参照ください。
原因の特定
[MySQL ストレージ容量の使用状況] ビューを確認し、使用率の高いパラメーターを以下のファイルタイプと解決策に照らし合わせてください。
| ファイルタイプ | 標準モニタリングのパラメーター | スペース分析のパラメーター | 解決策 |
|---|---|---|---|
| 一時ファイル | temp_file_size |
Temporary file data size |
一時ファイルの蓄積 |
| バイナリログファイル | binlog_size |
Binlog usage |
バイナリログファイルの蓄積 |
| undo ログファイル | undolog_size |
undo log usage |
システムファイルの蓄積 |
| 一般ログファイル | general_log_size |
General log usage |
一般ログファイルの蓄積 |
| ユーザーデータファイル | user_data_size |
User database usage |
ユーザーデータファイルの蓄積 |
また、フラグメンテーションやインデックスの肥大化も確認してください。これらは個別のパラメーターとしては表示されませんが、かなりの容量を消費する可能性があります。
-
フラグメンテーション:「フラグメンテーションの蓄積」をご参照ください。
-
インデックスの肥大化:「インデックスファイルの蓄積」をご参照ください。
一時ファイルの蓄積
一時ファイルは、MySQL が大規模なデータセットのソート、グループ化、または結合を行う SQL ステートメントを実行するときに作成されます。大規模なトランザクションのバイナリログも、トランザクションがコミットされるまで一時的にキャッシュされます。これらのファイルが蓄積されると、インスタンスはロックされます。
直ちにロックを解決:
-
MySQL 5.7 以前: インスタンスを再起動します。再起動時にシステムが一時ファイルを自動的に削除します。
-
MySQL 8.0: インスタンスはすべてのユーザーセッションを終了し、自動ロールバックを開始します。ロールバックが完了すると、一時ファイルが解放されます。
インスタンスが自動的にロック解除されない場合は、show processlist を実行して、ステータスが Copy to tmp table または Sending data のセッションを特定し、kill コマンドでそれらを終了させます。
詳細については、「RDS for MySQL の一時ファイル蓄積の解決策」をご参照ください。
バイナリログファイルの蓄積
大規模なトランザクションは、短時間で多くのバイナリログファイルを生成します。ログがクリーンアップされるよりも速く蓄積されると、ストレージが枯渇し、インスタンスはロックされます。
既存のログをアップロードして解決:
[ワンクリックバイナリログアップロード] 機能を使用して、RDS インスタンスから OSS にバイナリログファイルをアップロードします。RDS はアップロードされたファイルを自動的に削除します。詳細については、「バイナリログファイルの表示と削除」をご参照ください。
保持ポリシーを調整して再発を防止:
-
RDS コンソールで、[バックアップと復元] ページに移動します。
-
[バックアップ戦略] タブをクリックします。
-
[ローカルログ保持ポリシー] の横にある [編集] をクリックします。
-
保持期間、最大ストレージ使用量、および利用可能なストレージ容量を調整します。ローカルログストレージがしきい値に達すると、システムは最も古いログを自動的に削除します。
詳細については、「MySQL のバイナリログファイルの蓄積に関する解決策」をご参照ください。
フラグメンテーションの蓄積
InnoDB はページ単位でテーブルスペースを管理します。delete または update を使用して行を削除または更新すると、MySQL は領域を再利用可能としてマークしますが、ディスクファイルは縮小しません。解放されたページを再利用できない場合、フラグメンテーションが蓄積され、ストレージを消費します。
以下のいずれかの方法でフラグメンテーションを解決:
-
コマンドライン: テーブルを再構築し、断片化した領域を再利用するには、
optimize table <table_name>を実行します。 -
DMS コンソール: DMS で RDS インスタンスにログインします。テーブル名を右クリックし、[テーブルの一括操作] を選択します。デフラグするテーブルを選択し、[テーブルメンテナンス] > [テーブルの最適化] を選択します。
-
[自動回収:] RDS コンソールで、[自律サービス] > [診断] > [自律センター] に移動します。[自律サービス設定] をクリックし、[最適化とスロットリング] タブで [自動フラグメント回収] を有効にします。詳細については、「自動フラグメント回収機能の使用」をご参照ください。
詳細については、「MySQL の領域フラグメンテーションの解決策」をご参照ください。
システムファイルの蓄積
大規模なシステムファイルは、ほとんどの場合 undo ログの増加が原因です。実行時間の長い InnoDB クエリが大規模なデータ更新と同時に実行されると、MySQL は過剰な undo データを生成し、それがシステムテーブルスペースを埋め尽くし、ストレージを枯渇させる可能性があります。
解決策は、MySQL のバージョンと undo テーブルスペースの設定によって異なります。
MySQL 8.0
システムが自動的に undo ファイルをクリーンアップします。手動での操作は不要です。
MySQL 5.7 (innodb_undo_tablespaces = 2 の場合)
インスタンスは個別の undo テーブルスペースを使用します。undo ファイルサイズが innodb_max_undo_log_size を超え、かつアクティブなトランザクションがそのデータを必要としない場合、システムは領域を解放するために truncate 操作を実行します。
MySQL 5.7 (innodb_undo_tablespaces = 0 の場合)
Undo データは、システムテーブルスペース ibdata1 に格納され、解放できません。この問題を解決するには、次のいずれかの方法を使用します。
-
方法 1: 新しいインスタンスを作成し、DTS を使用してデータを移行します。詳細については、「RDS for MySQL コンソールを介したデータ移行」をご参照ください。
-
方法 2: MySQL 8.0 にアップグレードします。詳細については、「データベースバージョンのアップグレード」をご参照ください。
MySQL 5.5 および 5.6
undo ファイルのクリーンアップには対応していません。MySQL 5.7 High-availability Edition または MySQL 8.0 にアップグレードしてください。MySQL 5.7 にアップグレードした後、個別の undo テーブルスペースを有効にすると自動クリーンアップが可能になります。MySQL 8.0 は自動的に undo ファイルをクリーンアップします。
innodb_undo_tablespaces = 0 が設定されている MySQL 5.7 以前のインスタンスでは、メジャーバージョンアップグレード後も、元の ibdata1 ファイルが使用する領域は解放できません。アップグレード後は、新しく生成された undo ログのみが個別のテーブルスペースに書き込まれ、自動クリーンアップがサポートされます。
詳細については、「MySQL のシステムファイル蓄積の解決策」をご参照ください。
一般ログファイルの蓄積
一般クエリログが有効になっている場合、RDS は実行されたすべての SQL ステートメント (SELECT、INSERT、UPDATE、DELETE を含む) を記録します。高トラフィック下では、ログファイルは急速に増大します。定期的にクリーンアップされないと、ストレージを使い果たす可能性があります。
直ちに解決:
次のコマンドを実行して、既存のすべての一般ログレコードを削除します。
TRUNCATE TABLE mysql.general_log;
新しいログの増加を停止:
ランタイムパラメーター general_log を OFF に設定することで、一般ログの収集を無効にできます。 詳細については、「インスタンスパラメーターを設定する」をご参照ください。
ベストプラクティス: 本番環境では一般ログを無効にしておいてください。デバッグ目的でのみ一時的に有効にし、その後は直ちに無効にしてクリーンアップしてください。
詳細については、「MySQL の一般ログファイル蓄積の解決策」をご参照ください。
ユーザーデータファイルの蓄積
ユーザーデータファイルは時間とともに増加するため、管理しないとストレージがいっぱいになる可能性があります。blob、text、または長い varchar 型の列は、データファイルが大きくなる一般的な原因です。ストレージがいっぱいになると、RDS はデータ損失を防ぐためにインスタンスをロックします。
未使用のデータをクリーンアップして解決:
-
不要になったテーブルやデータを削除するには、
dropまたはtruncateを使用します。 -
ラージオブジェクトデータの場合は、保存する前にデータを圧縮して容量の使用量を削減します。
詳細については、「RDS for MySQL のデータファイル蓄積の解決策」をご参照ください。
インデックスファイルの蓄積
インデックスはディスクファイルとして保存されます。非効率的なインデックス戦略や過剰なセカンダリインデックスは、インデックスファイルの増大を招き、ストレージを枯渇させる原因となります。
インデックス戦略の最適化:
-
適切なフィールドにインデックスを作成: 頻繁にクエリ、ソート、またはテーブル結合で使用されるフィールドにインデックスを作成します。可能な場合は、単一列のインデックスの代わりに複合インデックスを使用して、合計インデックスファイルサイズを削減します。
-
未使用のインデックスを削除: 冗長なインデックスや、どのクエリからも参照されなくなったインデックスを削除します。
インデックスを削除すると、テーブルレベルのブロッキングが発生する可能性があります。この操作はオフピーク時に実行するか、DMS のロックフリーなスキーマ変更機能を使用して影響を軽減してください。