高速 DDL を使用して Amazon Aurora のテーブルを変更する - Amazon Aurora

高速 DDL を使用して Amazon Aurora のテーブルを変更する

Amazon Aurora には、ほぼ瞬時に所定の位置で ALTER TABLE オペレーションを実行するための最適化が含まれています。このオペレーションを実行するために、テーブルをコピーする必要はありません。また、他の DML ステートメントに実質的な影響を及ぼすことなく実行できます。このオペレーションは、テーブルのコピーにテンポラリストレージを使用しないため、スモールインスタンスクラスの大きなテーブルに対しても、DDL ステートメントを使用できます。

Aurora MySQL バージョン 3 は、インスタント DDL と呼ばれる MySQL 8.0 の特徴と互換性があります。Aurora MySQL バージョン 2 では、高速 DDL と呼ばれる異なる実装が使用されています。

インスタント DDL (Aurora MySQL バージョン 3)

DDL オペレーションの効率性を向上するため Aurora MySQL バージョン 3 によって実行される最適化を、インスタント DDL と呼びます。

Aurora MySQL バージョン 3 はコミュニティ MySQL 8.0 のインスタント DDL と互換性があります。インスタント DDL オペレーションを実行するには、ALTER TABLE ステートメントで ALGORITHM=INSTANT 句を使用します。インスタント DDL の構文と使用方法の詳細については、MySQL ドキュメントの「ALTER TABLE」ならびに「Online DDL Operations」(オンライン DDL オペレーション) を参照してください。

以下の例は、インスタンス DDL の特徴を説明しています。ALTER TABLE ステートメントは、列の追加、および列でのデフォルト値の変更を行います。例には、スタンダードカラムと仮想カラムの両方、およびスタンダードテーブルとパーティションテーブルの両方が含まれます。各ステップで、SHOW CREATE TABLEDESCRIBE ステートメントを発行すると結果が確認できます。

mysql> CREATE TABLE t1 (a INT, b INT, KEY(b)) PARTITION BY KEY(b) PARTITIONS 6; Query OK, 0 rows affected (0.02 sec) mysql> ALTER TABLE t1 RENAME TO t2, ALGORITHM = INSTANT; Query OK, 0 rows affected (0.01 sec) mysql> ALTER TABLE t2 ALTER COLUMN b SET DEFAULT 100, ALGORITHM = INSTANT; Query OK, 0 rows affected (0.00 sec) mysql> ALTER TABLE t2 ALTER COLUMN b DROP DEFAULT, ALGORITHM = INSTANT; Query OK, 0 rows affected (0.01 sec) mysql> ALTER TABLE t2 ADD COLUMN c ENUM('a', 'b', 'c'), ALGORITHM = INSTANT; Query OK, 0 rows affected (0.01 sec) mysql> ALTER TABLE t2 MODIFY COLUMN c ENUM('a', 'b', 'c', 'd', 'e'), ALGORITHM = INSTANT; Query OK, 0 rows affected (0.01 sec) mysql> ALTER TABLE t2 ADD COLUMN (d INT GENERATED ALWAYS AS (a + 1) VIRTUAL), ALGORITHM = INSTANT; Query OK, 0 rows affected (0.02 sec) mysql> ALTER TABLE t2 ALTER COLUMN a SET DEFAULT 20, -> ALTER COLUMN b SET DEFAULT 200, ALGORITHM = INSTANT; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t3 (a INT, b INT) PARTITION BY LIST(a)( -> PARTITION mypart1 VALUES IN (1,3,5), -> PARTITION MyPart2 VALUES IN (2,4,6) -> ); Query OK, 0 rows affected (0.03 sec) mysql> ALTER TABLE t3 ALTER COLUMN a SET DEFAULT 20, ALTER COLUMN b SET DEFAULT 200, ALGORITHM = INSTANT; Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE t4 (a INT, b INT) PARTITION BY RANGE(a) -> (PARTITION p0 VALUES LESS THAN(100), PARTITION p1 VALUES LESS THAN(1000), -> PARTITION p2 VALUES LESS THAN MAXVALUE); Query OK, 0 rows affected (0.05 sec) mysql> ALTER TABLE t4 ALTER COLUMN a SET DEFAULT 20, -> ALTER COLUMN b SET DEFAULT 200, ALGORITHM = INSTANT; Query OK, 0 rows affected (0.01 sec) /* Sub-partitioning example */ mysql> CREATE TABLE ts (id INT, purchased DATE, a INT, b INT) -> PARTITION BY RANGE( YEAR(purchased) ) -> SUBPARTITION BY HASH( TO_DAYS(purchased) ) -> SUBPARTITIONS 2 ( -> PARTITION p0 VALUES LESS THAN (1990), -> PARTITION p1 VALUES LESS THAN (2000), -> PARTITION p2 VALUES LESS THAN MAXVALUE -> ); Query OK, 0 rows affected (0.10 sec) mysql> ALTER TABLE ts ALTER COLUMN a SET DEFAULT 20, -> ALTER COLUMN b SET DEFAULT 200, ALGORITHM = INSTANT; Query OK, 0 rows affected (0.01 sec)

高速 DDL (Aurora MySQL バージョン 2)

MySQL において、何度もデータ操作言語 (DDL) オペレーションを行うと、パフォーマンスに大きな影響が出ることがあります。

例えば、ALTER TABLE オペレーションを使用して列をテーブルに追加するとします。オペレーションに指定するアルゴリズムによっては、このオペレーションに以下の操作が伴う場合があります。

  • テーブル全体のコピーの作成

  • 同時データ操作言語 (DML) オペレーションを処理するためのテンポラリテーブルの作成

  • テーブルのすべてのインデックスの再構築

  • 同時 DML 変更の適用時におけるテーブルロックの適用

  • 同時 DML スループットの低下

DDL オペレーションの効率性向上のために Aurora MySQL バージョン 2 によって実行される最適化を、高速 DDL と呼びます。

Aurora MySQL バージョン 3 では、Aurora はインスタント DDL と呼ばれる MySQL 8.0 特徴を使用します。Aurora MySQL バージョン 2 では、高速 DDL と呼ばれる異なる実装が使用されています。

重要

現在、Aurora MySQL で高速 DDL を使用するには、Aurora ラボモードを有効にする必要があります。本番 DB クラスターに高速 DDL を使用することはお勧めしません。Aurora ラボモードを有効にする方法については、「Amazon Aurora MySQL ラボモード」を参照してください。

高速 DDL の制限事項

現在、高速 DDL には以下の制限があります。

  • 高速 DDL は、NULL を許容する列 (デフォルト値を持たない) を、既存テーブルの末尾に追加する場合にのみ使用できます。

  • 高速DDLは、パーティション化されたテーブルでは機能しません。

  • 高速 DDL は、REDUNDANT 行形式を使用する InnoDB テーブルをサポートしていません。

  • Fast DDL は、フルテキスト検索インデックスを持つテーブルでは機能しません。

  • DDL オペレーションの最大可能レコードサイズが大きすぎる場合、高速 DDL は使用されません。ページサイズの半分を超えるレコードサイズは大きすぎます。レコードの最大サイズは、すべての列の最大サイズを追加して計算されます。サイズを変更可能な列の場合は、InnoDB スタンダードに基づき、extern byte は計算に含まれません。

高速 DDL の構文

ALTER TABLE tbl_name ADD COLUMN col_name column_definition

このステートメントには、以下のオプションがあります。

  • tbl_name変更するテーブルの名前。

  • col_name追加する列の名前。

  • col_definition追加する列の定義。

    注記

    NULL を許容する列の定義は、デフォルト値を使用せずに指定する必要があります。そうでない場合、高速 DDL は使用されません。

高速 DDL の例

次の例は、高速 DDL オペレーションによる高速化を示しています。最初の SQL の例では、高速 DDL を使用せずに、大きなテーブルに対して ALTER TABLE ステートメントを実行しています。この操作にはかなりの時間がかかります。CLI の例は、クラスターで高速 DDL を有効化する方法を示しています。次に、別の SQL の例では、同じテーブルで同じ ALTER TABLE ステートメントを実行します。高速 DDL を有効にすると、オペレーションが非常に高速になります。

この例では、1 億 5000 万行を含む、TPC-H ベンチマークの ORDERS テーブルを使用しています。このクラスターでは、比較的小さなインスタンスクラスを意図的に使用して、高速 DDL を使用できない場合の ALTER TABLE ステートメントの所要時間を示しています。この例では、同じデータを含む元のテーブルのクローンを作成します。aurora_lab_mode 設定を確認すると、ラボモードが有効になっていないため、クラスターで高速 DDL を使用できないことが分かります。その場合、ALTER TABLE ADD COLUMN ステートメントでテーブルの最後に新しい列を追加するには、かなりの時間がかかります。

mysql> create table orders_regular_ddl like orders; Query OK, 0 rows affected (0.06 sec) mysql> insert into orders_regular_ddl select * from orders; Query OK, 150000000 rows affected (1 hour 1 min 25.46 sec) mysql> select @@aurora_lab_mode; +-------------------+ | @@aurora_lab_mode | +-------------------+ | 0 | +-------------------+ mysql> ALTER TABLE orders_regular_ddl ADD COLUMN o_refunded boolean; Query OK, 0 rows affected (40 min 31.41 sec) mysql> ALTER TABLE orders_regular_ddl ADD COLUMN o_coverletter varchar(512); Query OK, 0 rows affected (40 min 44.45 sec)

この例では、前の例と同様に大きなテーブルを準備します。ただし、Interactive SQL セッション内で単にラボモードを有効にすることはできません。この設定は、カスタムパラメータグループで有効にする必要があります。そのためには、mysql セッションを終了して AWS CLI コマンドをいくつか実行するか、AWS Management Console を使用する必要があります。

mysql> create table orders_fast_ddl like orders; Query OK, 0 rows affected (0.02 sec) mysql> insert into orders_fast_ddl select * from orders; Query OK, 150000000 rows affected (58 min 3.25 sec) mysql> set aurora_lab_mode=1; ERROR 1238 (HY000): Variable 'aurora_lab_mode' is a read only variable

クラスターのラボモードを有効にするには、パラメータグループをいくつか使用する必要があります。この AWS CLI の例では、クラスターのパラメータグループを使用して、クラスター内のすべての DB インスタンスのラボモード設定で同じ値を使用するようにします。

$ aws rds create-db-cluster-parameter-group \ --db-parameter-group-family aurora5.7 \ --db-cluster-parameter-group-name lab-mode-enabled-57 --description 'TBD' $ aws rds describe-db-cluster-parameters \ --db-cluster-parameter-group-name lab-mode-enabled-57 \ --query '*[*].[ParameterName,ParameterValue]' \ --output text | grep aurora_lab_mode aurora_lab_mode 0 $ aws rds modify-db-cluster-parameter-group \ --db-cluster-parameter-group-name lab-mode-enabled-57 \ --parameters ParameterName=aurora_lab_mode,ParameterValue=1,ApplyMethod=pending-reboot { "DBClusterParameterGroupName": "lab-mode-enabled-57" } # Assign the custom parameter group to the cluster that's going to use Fast DDL. $ aws rds modify-db-cluster --db-cluster-identifier tpch100g \ --db-cluster-parameter-group-name lab-mode-enabled-57 { "DBClusterIdentifier": "tpch100g", "DBClusterParameterGroup": "lab-mode-enabled-57", "Engine": "aurora-mysql", "EngineVersion": "5.7.mysql_aurora.2.10.2", "Status": "available" } # Reboot the primary instance for the cluster tpch100g: $ aws rds reboot-db-instance --db-instance-identifier instance-2020-12-22-5208 { "DBInstanceIdentifier": "instance-2020-12-22-5208", "DBInstanceStatus": "rebooting" } $ aws rds describe-db-clusters --db-cluster-identifier tpch100g \ --query '*[].[DBClusterParameterGroup]' --output text lab-mode-enabled-57 $ aws rds describe-db-cluster-parameters \ --db-cluster-parameter-group-name lab-mode-enabled-57 \ --query '*[*].{ParameterName:ParameterName,ParameterValue:ParameterValue}' \ --output text | grep aurora_lab_mode aurora_lab_mode 1

次の例では、パラメータグループの変更が有効になった後のステップを示します。クラスターで高速 DDL を使用できることを確認するため、aurora_lab_mode 設定をテストします。次に、ALTER TABLE ステートメントを実行して、別の大きなテーブルの末尾に列を追加します。ここでは、ステートメントは非常に高速で終了します。

mysql> select @@aurora_lab_mode; +-------------------+ | @@aurora_lab_mode | +-------------------+ | 1 | +-------------------+ mysql> ALTER TABLE orders_fast_ddl ADD COLUMN o_refunded boolean; Query OK, 0 rows affected (1.51 sec) mysql> ALTER TABLE orders_fast_ddl ADD COLUMN o_coverletter varchar(512); Query OK, 0 rows affected (0.40 sec)