MySQL 8.0 リファレンスマニュアル


15.6.3.4 undo テーブルスペース

undo テーブルスペースには undo ログが含まれます。undo ログレコードには、クラスタ化されたインデックスレコードに対するトランザクションによる最新の変更を取り消す方法に関する情報が含まれます。 undo ログは、ロールバックセグメント内に含まれる undo ログセグメント内に存在します。 innodb_rollback_segments 変数は、各 undo テーブルスペースに割り当てられるロールバックセグメントの数を定義します。

MySQL インスタンスが初期化されると、2 つのデフォルト undo テーブルスペースが作成されます。 SQL ステートメントを受け入れる前に存在する必要があるロールバックセグメントの場所を提供するために、初期化時にデフォルトの undo テーブルスペースが作成されます。 undo テーブルスペースの自動切捨てをサポートするには、2 つ以上の undo テーブルスペースが必要です。 undo テーブルスペースの切捨てを参照してください。

デフォルトの undo テーブルスペースは、innodb_undo_directory 変数で定義された場所に作成されます。 innodb_undo_directory 変数が定義されていない場合、デフォルトの undo テーブルスペースがデータディレクトリに作成されます。 デフォルトの undo テーブルスペースデータファイルには、undo_001 および undo_002 という名前が付けられます。 データディクショナリに定義されている対応する undo テーブルスペース名は、innodb_undo_001 および innodb_undo_002 です。

MySQL 8.0.14 では、SQL を使用して実行時に追加の undo テーブルスペースを作成できます。 undo テーブルスペースの追加を参照してください。

MySQL 8.0.23 より前のリリースでは、UNDO テーブルスペースの初期サイズは innodb_page_size の値によって異なります。 デフォルトの 16KB ページサイズの場合、undo テーブルスペースの初期ファイルサイズは 10MiB です。 4KB、8KB、32KB および 64KB のページサイズの場合、初期 undo テーブルスペースファイルサイズはそれぞれ 7MiB、8MiB、20MiB および 40MiB です。 MySQL 8.0.23 では、初期 UNDO テーブルスペースサイズは通常 16MiB です。 切捨て操作によって新しい UNDO テーブルスペースが作成される場合、初期サイズが異なることがあります。 この場合、ファイル拡張子のサイズが 16MB を超え、前のファイル拡張子が最後の秒以内に発生した場合、新しい UNDO テーブルスペースは innodb_max_undo_log_size 変数で定義されたサイズの四半期に作成されます。

MySQL 8.0.23 より前は、UNDO テーブルスペースは一度に 4 エクステント拡張されます。 MySQL 8.0.23 からは、UNDO テーブルスペースは 16MB 以上拡張されます。 積極的な増加に対処するために、以前のファイル拡張子が 0.1 秒未満になった場合、ファイル拡張子のサイズは倍増します。 拡張サイズの倍増は、最大 256MB まで複数回発生する可能性があります。 以前のファイル拡張子が 0.1 秒より前に発生した場合、拡張子のサイズは半分に縮小されます。これも、複数回出現する可能性があります (16MB 以上)。 UNDO テーブルスペースに AUTOEXTEND_SIZE オプションが定義されている場合、前述のロジックで決定された AUTOEXTEND_SIZE 設定および拡張サイズの大きい方によって拡張されます。 AUTOEXTEND_SIZE オプションの詳細は、セクション15.6.3.9「テーブルスペースの AUTOEXTEND_SIZE 構成」 を参照してください。

undo テーブルスペースの追加

長時間実行トランザクション中に undo ログが大きくなる可能性があるため、追加の undo テーブルスペースを作成すると、個々の undo テーブルスペースが大きくなりすぎるのを防ぐことができます。 MySQL 8.0.14 では、CREATE UNDO TABLESPACE 構文を使用して、実行時に追加の undo テーブルスペースを作成できます。

CREATE UNDO TABLESPACE tablespace_name ADD DATAFILE 'file_name.ibu';

undo テーブルスペースのファイル名には、.ibu 拡張子が必要です。 undo テーブルスペースファイル名の定義時に相対パスを指定することはできません。 完全修飾パスは許可されますが、パスは InnoDB で認識されている必要があります。 既知のパスは、innodb_directories 変数で定義されたパスです。 データの移動またはクローニング時に潜在的なファイル名の競合を回避するために、一意の undo テーブルスペースファイル名をお薦めします。

注記

レプリケーション環境では、ソースと各レプリカに独自の undo テーブルスペースファイルディレクトリが必要です。 undo テーブルスペースファイルの作成を共通ディレクトリにレプリケートすると、ファイル名の競合が発生します。

起動時に、innodb_directories 変数で定義されたディレクトリで undo テーブルスペースファイルがスキャンされます。 (スキャンはサブディレクトリも走査します。) innodb_data_home_dirinnodb_undo_directory および datadir 変数で定義されたディレクトリは、innodb_directories 変数が明示的に定義されているかどうかに関係なく、innodb_directories 値に自動的に追加されます。 したがって、undo テーブルスペースは、これらの変数のいずれかで定義されたパスに存在できます。

undo テーブルスペースのファイル名にパスが含まれていない場合、undo テーブルスペースは innodb_undo_directory 変数で定義されたディレクトリに作成されます。 この変数が定義されていない場合、undo テーブルスペースはデータディレクトリに作成されます。

注記

InnoDB リカバリプロセスでは、undo テーブルスペースファイルが既知のディレクトリに存在する必要があります。 コミットされていないトランザクションおよびデータディクショナリの変更をロールバックできるようにするには、undo テーブルスペースファイルを検出してオープンしてから redo リカバリを実行し、他のデータファイルをオープンする必要があります。 リカバリを使用する前に undo テーブルスペースが見つからないため、データベースの不整合が発生する可能性があります。 データディクショナリで認識されている undo テーブルスペースが見つからない場合は、起動時にエラーメッセージがレポートされます。 既知のディレクトリ要件では、undo テーブルスペースの移植性もサポートされます。 undo テーブルスペースの移動を参照してください。

データディレクトリからの相対パスに undo テーブルスペースを作成するには、innodb_undo_directory 変数を相対パスに設定し、undo テーブルスペースの作成時にのみファイル名を指定します。

undo テーブルスペースの名前とパスを表示するには、INFORMATION_SCHEMA.FILES をクエリーします:

SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES
  WHERE FILE_TYPE LIKE 'UNDO LOG';

MySQL インスタンスでは、MySQL インスタンスの初期化時に作成される 2 つのデフォルト undo テーブルスペースを含む、最大 127 個の undo テーブルスペースがサポートされます。

注記

MySQL 8.0.14 より前は、innodb_undo_tablespaces 起動変数を構成することで、追加の undo テーブルスペースが作成されます。 この変数は非推奨であり、MySQL 8.0.14 では構成できなくなりました。

MySQL 8.0.14 より前は、innodb_undo_tablespaces 設定を増やすと、指定した数の undo テーブルスペースが作成され、アクティブな undo テーブルスペースのリストに追加されます。 innodb_undo_tablespaces 設定を小さくすると、アクティブな undo テーブルスペースのリストから undo テーブルスペースが削除されます。 アクティブリストから削除された undo テーブルスペースは、既存のトランザクションで使用されなくなるまでアクティブなままです。 innodb_undo_tablespaces 変数は、SET ステートメントを使用して実行時に構成するか、構成ファイルで定義できます。

MySQL 8.0.14 より前は、非アクティブ化された undo テーブルスペースは削除できません。 undo テーブルスペースファイルは、低速な停止後に手動で削除できますが、非アクティブ化された undo テーブルスペースには、サーバーの停止時にオープントランザクションが存在していた場合、サーバーの再起動後のしばらくの間アクティブ undo ログが含まれる可能性があるため、お薦めしません。 MySQL 8.0.14 では、DROP UNDO TABALESPACE 構文を使用して undo テーブルスペースを削除できます。 undo テーブルスペースの削除を参照してください。

undo テーブルスペースの削除

MySQL 8.0.14 では、CREATE UNDO TABLESPACE 構文を使用して作成された undo テーブルスペースは、DROP UNDO TABALESPACE 構文を使用して実行時に削除できます。

undo テーブルスペースは、削除する前に空にする必要があります。 undo テーブルスペースを空にするには、ロールバックセグメントを新しいトランザクションに割り当てるためにテーブルスペースが使用されなくなるように、まず ALTER UNDO TABLESPACE 構文を使用して undo テーブルスペースを非アクティブとしてマークする必要があります。

ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;

undo テーブルスペースが非アクティブとしてマークされると、undo テーブルスペースのロールバックセグメントを現在使用しているトランザクションは、それらのトランザクションが完了する前に開始されたトランザクションと同様に終了できます。 トランザクションが完了すると、パージシステムによって undo テーブルスペースのロールバックセグメントが解放され、undo テーブルスペースは初期サイズに切り捨てられます。 (undo テーブルスペースを切り捨てる場合も同じプロセスが使用されます。 undo テーブルスペースの切捨てを参照してください。) undo テーブルスペースが空の場合は、削除できます。

DROP UNDO TABLESPACE tablespace_name;
注記

または、undo テーブルスペースを空の状態のままにし、必要に応じて ALTER UNDO TABLESPACE tablespace_name SET ACTIVE ステートメントを発行して後で再アクティブ化することもできます。

undo テーブルスペースの状態は、INFORMATION_SCHEMA.INNODB_TABLESPACES テーブルをクエリーすることで監視できます。

SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
  WHERE NAME LIKE 'tablespace_name';

inactive の状態は、undo テーブルスペースのロールバックセグメントが新しいトランザクションで使用されなくなったことを示します。 empty の状態は、undo テーブルスペースが空であり、削除の準備ができているか、ALTER UNDO TABLESPACE tablespace_name SET ACTIVE ステートメントを使用して再度アクティブになったことを示します。 空でない undo テーブルスペースを削除しようとすると、エラーが返されます。

MySQL インスタンスの初期化時に作成されたデフォルトの undo テーブルスペース (innodb_undo_001 および innodb_undo_002) は削除できません。 ただし、ALTER UNDO TABLESPACE tablespace_name SET INACTIVE ステートメントを使用して非アクティブにすることはできます。 デフォルトの undo テーブルスペースを非アクティブにするには、その前に undo テーブルスペースが必要です。 undo テーブルスペースの自動切捨てをサポートするには、常に 2 つ以上のアクティブ undo テーブルスペースが必要です。

undo テーブルスペースの移動

CREATE UNDO TABLESPACE 構文で作成された undo テーブルスペースは、サーバーがオフラインのときに既知のディレクトリに移動できます。 既知のディレクトリは、innodb_directories 変数で定義されたディレクトリです。 innodb_data_home_dirinnodb_undo_directory および datadir によって定義されたディレクトリは、innodb_directories 変数が明示的に定義されているかどうかに関係なく、innodb_directories 値に自動的に追加されます。 これらのディレクトリとそのサブディレクトリでは、undo テーブルスペースファイルが起動時にスキャンされます。 これらのディレクトリに移動された undo テーブルスペースファイルは、起動時に検出され、移動された undo テーブルスペースとみなされます。

MySQL インスタンスの初期化時に作成されるデフォルトの undo テーブルスペース (innodb_undo_001 および innodb_undo_002) は、innodb_undo_directory 変数で定義されたディレクトリに常に存在する必要があります。 innodb_undo_directory 変数が定義されていない場合、デフォルトの undo テーブルスペースはデータディレクトリに存在します。 サーバーがオフラインのときにデフォルトの undo テーブルスペースを移動する場合は、新しいディレクトリに構成された innodb_undo_directory 変数を使用してサーバーを起動する必要があります。

undo ログの I/O パターンにより、undo テーブルスペースは SSD 記憶域の適切な候補になります。

ロールバックセグメント数の構成

innodb_rollback_segments 変数は、各 undo テーブルスペースおよびグローバル一時テーブルスペースに割り当てられる rollback segments の数を定義します。 innodb_rollback_segments 変数は、起動時またはサーバーの実行中に構成できます。

innodb_rollback_segments のデフォルト設定は 128 で、これは最大値でもあります。 ロールバックセグメントがサポートするトランザクションの数の詳細は、セクション15.6.6「undo ログ」 を参照してください。

undo テーブルスペースの切捨て

undo テーブルスペースを切り捨てる方法は 2 つあり、undo テーブルスペースのサイズを個別に、または組み合せて管理できます。 1 つの方法は自動化され、構成変数を使用して有効化されます。 その他の方法は手動で、SQL ステートメントを使用して実行されます。

自動化された方法では undo テーブルスペースサイズを監視する必要はなく、一度有効にすると、手動操作なしで undo テーブルスペースの非アクティブ化、切捨ておよび再アクティブ化が実行されます。 切捨てのために undo テーブルスペースをオフラインにするタイミングを制御する場合は、手動切捨て方法をお薦めします。 たとえば、ワークロードのピーク時に undo テーブルスペースを切り捨てないようにすることが必要な場合があります。

自動切捨て

undo テーブルスペースの自動切捨てには、少なくとも 2 つのアクティブな undo テーブルスペースが必要です。これにより、一方の undo テーブルスペースはアクティブなままになり、もう一方の undo テーブルスペースは切り捨てられます。 デフォルトでは、MySQL インスタンスの初期化時に 2 つの undo テーブルスペースが作成されます。

undo テーブルスペースを自動的に切り捨てるには、innodb_undo_log_truncate 変数を有効にします。 例:

mysql> SET GLOBAL innodb_undo_log_truncate=ON;

innodb_undo_log_truncate 変数が有効な場合、innodb_max_undo_log_size 変数で定義されたサイズ制限を超える undo テーブルスペースは切り捨てられる可能性があります。 innodb_max_undo_log_size 変数は動的で、デフォルト値は 1073741824 バイト (1024 MiB) です。

mysql> SELECT @@innodb_max_undo_log_size;
+----------------------------+
| @@innodb_max_undo_log_size |
+----------------------------+
|                 1073741824 |
+----------------------------+

innodb_undo_log_truncate 変数を有効にすると、次のようになります:

  1. innodb_max_undo_log_size 設定を超えるデフォルトおよびユーザー定義の undo テーブルスペースは、切捨て対象としてマークされます。 切捨て用の undo テーブルスペースの選択は循環方式で実行され、毎回同じ undo テーブルスペースが切り捨てられないようにします。

  2. 選択した undo テーブルスペースに存在するロールバックセグメントは、新しいトランザクションに割り当てられないように非アクティブになります。 ロールバックセグメントを現在使用している既存のトランザクションは終了できます。

  3. purge システムは、使用されなくなった undo ログを解放することで、ロールバックセグメントを空にします。

  4. undo テーブルスペースのすべてのロールバックセグメントが解放されると、切捨て操作が実行され、undo テーブルスペースが初期サイズに切り捨てられます。

    切捨て操作後の undo テーブルスペースのサイズは、操作が完了した直後に使用されるため、初期サイズより大きくなる場合があります。

    innodb_undo_directory 変数は、デフォルトの undo テーブルスペースファイルの場所を定義します。 innodb_undo_directory 変数が定義されていない場合、デフォルトの undo テーブルスペースはデータディレクトリに存在します。 CREATE UNDO TABLESPACE 構文を使用して作成されたユーザー定義の undo テーブルスペースを含むすべての undo テーブルスペースファイルの場所は、INFORMATION_SCHEMA.FILES テーブルをクエリーすることで確認できます:

    SELECT TABLESPACE_NAME, FILE_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE LIKE 'UNDO LOG';
  5. ロールバックセグメントは、新しいトランザクションに割り当てることができるように再アクティブ化されます。

手動切捨て

undo テーブルスペースを手動で切り捨てるには、少なくとも 3 つのアクティブな undo テーブルスペースが必要です。 自動切捨てを有効にするには、常に 2 つのアクティブ undo テーブルスペースが必要です。 undo テーブルスペースを手動でオフラインにすることを許可しながら、少なくとも 3 つの undo テーブルスペースがこの要件を満たしています。

undo テーブルスペースの切捨てを手動で開始するには、次のステートメントを発行して undo テーブルスペースを非アクティブ化します:

ALTER UNDO TABLESPACE tablespace_name SET INACTIVE;

undo テーブルスペースが非アクティブとしてマークされると、undo テーブルスペースのロールバックセグメントを現在使用しているトランザクションは、それらのトランザクションが完了する前に開始されたトランザクションと同様に終了できます。 トランザクションが完了すると、パージシステムによって undo テーブルスペースのロールバックセグメントが解放され、undo テーブルスペースが初期サイズに切り捨てられ、undo テーブルスペースの状態が inactive から empty に変更されます。

注記

ALTER UNDO TABLESPACE tablespace_name SET INACTIVE ステートメントによって undo テーブルスペースが非アクティブ化されると、パージスレッドは次の機会でその undo テーブルスペースを検索します。 undo テーブルスペースが検出され、切捨てのマークが付けられると、パージスレッドは頻度を上げて戻され、undo テーブルスペースがすぐに空になり、切り捨てられます。

undo テーブルスペースの状態を確認するには、INFORMATION_SCHEMA.INNODB_TABLESPACES テーブルをクエリーします。

SELECT NAME, STATE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
  WHERE NAME LIKE 'tablespace_name';

undo テーブルスペースが empty 状態になると、次のステートメントを発行して undo テーブルスペースを再アクティブ化できます:

ALTER UNDO TABLESPACE tablespace_name SET ACTIVE;

empty 状態の undo テーブルスペースも削除できます。 undo テーブルスペースの削除を参照してください。

undo テーブルスペースの自動切捨ての回避

パージスレッドは、undo テーブルスペースを空にしたり切り捨てたりします。 デフォルトでは、パージスレッドは undo テーブルスペースを検索し、パージが起動されるたびに 128 回切り捨てます。 パージスレッドが切り捨てる undo テーブルスペースを検索する頻度は、innodb_purge_rseg_truncate_frequency 変数 (デフォルト設定は 128) によって制御されます。

mysql> SELECT @@innodb_purge_rseg_truncate_frequency;
+----------------------------------------+
| @@innodb_purge_rseg_truncate_frequency |
+----------------------------------------+
|                                    128 |
+----------------------------------------+

この頻度を上げるには、innodb_purge_rseg_truncate_frequency 設定を減らします。 たとえば、パージスレッドで undo テーブルスペースを 32 回起動するたびに検索するには、innodb_purge_rseg_truncate_frequency を 32 に設定します。

mysql> SET GLOBAL innodb_purge_rseg_truncate_frequency=32;
undo テーブルスペースファイルの切捨てによるパフォーマンスへの影響

undo テーブルスペースが切り捨てられると、undo テーブルスペースのロールバックセグメントは非アクティブ化されます。 他の undo テーブルスペースのアクティブロールバックセグメントは、システム全体の負荷を前提としているため、パフォーマンスがわずかに低下する可能性があります。 パフォーマンスの低下の量は、いくつかの要因によって異なります:

  • undo テーブルスペースの数

  • undo ログの数

  • undo テーブルスペースサイズ

  • I/O 疑わしいシステムの速度

  • 既存の長時間実行トランザクション

  • システムロード

この潜在的なパフォーマンスの問題を回避する最も簡単な方法は、undo テーブルスペースの数を増やすことです。

また、MySQL 8.0.21 より前は、undo テーブルスペースの切捨て操作中に 2 つのフラッシュ操作が実行されます。 最初のフラッシュ操作では、バッファプールから古い undo テーブルスペースページが削除されます。 2 回目のフラッシュ操作では、新しい undo テーブルスペースの初期ページがディスクに書き込まれます。 ビジー状態のシステムでは、削除するページが多数ある場合、特に最初のフラッシュ操作がシステムのパフォーマンスに一時的に影響を与える可能性があります。 MySQL 8.0.21 の時点では、両方のフラッシュ操作が削除されます。 古い undo テーブルスペースページは、最近最も使用されていない状態になるか、次のフルチェックポイントで解放されるため、パッシブに解放されます。 新しい undo テーブルスペースページの初期ページは、切捨て操作中にディスクにフラッシュされるのではなく、redo ログに記録されます。

undo テーブルスペースの切捨ての監視

MySQL 8.0.16 では、undo ログの切捨てに関連付けられたバックグラウンドアクティビティを監視するために、undo および purge の疑わしいシステムカウンタが提供されています。 カウンタ名と説明については、INFORMATION_SCHEMA.INNODB_METRICS テーブルをクエリーします。

SELECT NAME, SUBSYSTEM, COMMENT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME LIKE '%truncate%';

カウンタの有効化およびカウンタデータのクエリーの詳細は、セクション15.15.6「InnoDB INFORMATION_SCHEMA メトリックテーブル」 を参照してください。

undo テーブルスペースの切捨て制限

MySQL 8.0.21 の時点では、チェックポイント間の同じ undo テーブルスペースに対する切捨て操作の数は 64 に制限されています。 この制限により、ビジー状態のシステムで innodb_max_undo_log_size の設定が低すぎる場合などに発生する可能性のある undo テーブルスペースの切捨て操作の数が多すぎることが原因で発生する潜在的な問題が回避されます。 この制限を超えると、undo テーブルスペースは非アクティブにできますが、次のチェックポイントまで切り捨てられません。 MySQL 8.0.22 では、制限は 64 から 50,000 に引き上げられました。

undo テーブルスペースの切捨てリカバリ

undo テーブルスペースの切捨て操作では、一時 undo_space_number_trunc.log ファイルがサーバーログディレクトリに作成されます。 そのログディレクトリは、innodb_log_group_home_dir によって定義されます。 切捨て操作中にシステム障害が発生した場合、一時ログファイルを使用すると、起動プロセスで切り捨てられていた undo テーブルスペースを識別し、操作を続行できます。

undo テーブルスペースのステータス変数

次のステータス変数を使用すると、undo テーブルスペースの合計数、暗黙的 (InnoDB 作成) undo テーブルスペース、明示的 (ユーザー作成) undo テーブルスペースおよびアクティブ undo テーブルスペースの数を追跡できます:

mysql> SHOW STATUS LIKE 'Innodb_undo_tablespaces%';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| Innodb_undo_tablespaces_total    | 2     |
| Innodb_undo_tablespaces_implicit | 2     |
| Innodb_undo_tablespaces_explicit | 0     |
| Innodb_undo_tablespaces_active   | 2     |
+----------------------------------+-------+

ステータス変数の説明については、セクション5.1.10「サーバーステータス変数」を参照してください。


関連キーワード:  テーブル, スペース, InnoDB, 変数, 切捨て, 作成, 構成, トランザクション, 定義, 操作