単一テーブルの大規模なデータ量によってクエリが遅くなったり、不適切な初期パーティショニングポリシーがデータホットスポットを引き起こしたりすると、元のテーブルスキーマがパフォーマンスボトルネックになる可能性があります。これらの問題を解決するために、PolarDB for Xscale は、テーブルタイプとパーティショニングポリシーをオンラインで変更する機能を提供します。この機能は、テーブルをロックしたり、データ操作言語 (DML) 操作をブロックしたりしないため、ビジネスを中断することなくデータを再配布できます。テーブルを単一、ブロードキャスト、パーティションタイプ間で変換できます。また、既存のパーティションテーブルのパーティションキーやアルゴリズムを調整することもできます。これにより、データレイアウトが最適化され、データベース全体のパフォーマンスとスケーラビリティが向上します。
この操作は、負荷の高いデータ定義言語 (DDL) タスクです。完全なデータ移行と再配布をオンラインで実行します。
実行中、タスクは大量の CPU、I/O、およびネットワークリソースを消費し、インスタンスのパフォーマンスに影響を与える可能性があります。所要時間はデータ量に比例します。
この操作はオフピーク時間帯に実行し、タスク管理コマンドを使用してその進捗を監視してください。
適用性
この変更を実行する前に、お使いの環境が次の条件を満たしていることを確認してください。
データベースモード: この機能は、AUTO モードのデータベースにのみ適用されます。
インスタンスバージョン:
5.4.13以降のマイナーエンジンバージョンを持つ PolarDB-X 2.0 インスタンスのみがサポートされています。グローバルセカンダリインデックス (GSI): GSI を持つパーティションテーブルのパーティションを変更するには、
5.4.14以降のマイナーエンジンバージョンを持つ PolarDB-X 2.0 インスタンスが必要です。変更中、GSI データも再配布されます。
インスタンスバージョンの命名規則については、「リリースノート」をご参照ください。
インスタンスのバージョンの表示方法については、「インスタンスのバージョンの表示と更新」をご参照ください。
仕組み
オンライン DDL: すべての変更操作はオンラインで実行されます。元のテーブルはロックされません。DML および SELECT 操作は通常どおり続行でき、業務継続性が確保されます。
データ再配布: テーブルタイプまたはパーティショニングポリシーを変更する中核は、物理的なデータ移行です。例:
単一テーブルをパーティションテーブルに変換すると、データは単一のデータノード (DN) から複数の DN に分散されます。
パーティションキーを変更すると、データは新しいパーティショニングポリシーに基づいて DN 間でリバランスされます。このプロセスがリソース消費の主な原因です。
原子性とロールバック: DDL タスク全体はアトミックです。一意キーの競合、ディスク領域の不足、またはその他の理由でタスクが失敗した場合、システムは元のテーブルデータがそのまま維持されることを保証します。ビジネスに影響はありません。CANCEL DDL コマンドを使用して、失敗したタスクをロールバックできます。
テーブルタイプの変更
PolarDB for Xscale は、単一テーブル、ブロードキャストテーブル、パーティションテーブルの 3 つのテーブルタイプをサポートしています。ビジネスシナリオの変化に応じて、これらのタイプ間でテーブルをオンラインで変換できます。詳細については、「CREATE TABLE (AUTO モード)」をご参照ください。
テーブルタイプを変更する際、元のテーブルがキーパーティションテーブル (パーティションキーがプライマリキーと同じ) であり、それを標準テーブルに変換すると、プライマリキーパーティショニング機能が失われます。これらの機能には、自動パーティショニングポリシーやインデックス変換ルールが含まれます。詳細については、「AUTO モードでの自動シャーディング」をご参照ください。
単一テーブルまたはブロードキャストテーブルをパーティションテーブルに変換する
このシナリオは、単一テーブルのデータ量が増加している場合に適しています。テーブルがパフォーマンスボトルネックになっているか、なりそうな場合、水平分割してスケーラビリティとクエリパフォーマンスを向上させることができます。
構文
ALTER TABLE 文を使用し、新しいパーティショニングポリシーを指定します。partition_options 構文の詳細については、「パーティションテーブル」をご参照ください。
ALTER TABLE table_name PARTITION BY partition_options;例
t_orderという名前のサンプルテーブルを作成します。CREATE TABLE t_order ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, `seller_id` varchar(20) DEFAULT NULL, `order_snapshot` longtext DEFAULT NULL, `order_detail` longtext DEFAULT NULL, PRIMARY KEY (`id`), KEY `l_i_order` (`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;ビジネスの成長により、単一テーブル
t_orderのデータ量が増加しました。order_idをパーティションキーとしてパーティションテーブルに変換します。-- 単一テーブル t_order を、order_id をパーティションキーとする KEY パーティションテーブルに変換します。 ALTER TABLE t_order PARTITION BY KEY(`order_id`); -- 変換中にパーティション数を指定することもできます。 ALTER TABLE t_order PARTITION BY KEY(`order_id`) PARTITIONS 8;
パーティションテーブルまたは単一テーブルをブロードキャストテーブルに変換する
このシナリオは、データ量が少なく比較的に静的で、大規模テーブルと頻繁に結合されるテーブル (構成テーブルや辞書テーブルなど) に適しています。テーブルデータを各データノード (DN) に複製することで、データベース間の結合によるネットワークオーバーヘッドをなくし、結合クエリのパフォーマンスを向上させることができます。
構文
ALTER TABLE 文を使用し、BROADCAST 句を指定します。
ALTER TABLE table_name BROADCAST;ブロードキャストテーブルは、各 DN にデータのレプリカを保存するため、より多くのストレージ領域を消費します。
例
t_order_1という名前のサンプルテーブルを作成します。CREATE TABLE t_order_1 ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, `seller_id` varchar(20) DEFAULT NULL, `order_snapshot` longtext DEFAULT NULL, `order_detail` longtext DEFAULT NULL, PRIMARY KEY (`id`), KEY `l_i_order` (`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;t_order_1テーブルをブロードキャストテーブルに変換します。ALTER TABLE t_order_1 BROADCAST;
パーティションテーブルまたはブロードキャストテーブルを単一テーブルに変換する
このシナリオは、データ量が少なく、水平スケーリングを必要としないテーブルに適しています。テーブルのデータを単一のデータノード (DN) に統合して、テーブルスキーマを簡素化できます。
構文
ALTER TABLE 文を使用し、SINGLE 句を指定します。
ALTER TABLE table_name SINGLE;パーティションテーブルを単一テーブルに変換すると、すべてのシャードのデータが単一の DN に統合されます。ターゲットノードに十分なディスク領域があることを確認し、領域不足による操作の失敗を防いでください。
例
t_order_2という名前のサンプルテーブルを作成します。CREATE TABLE t_order_2 ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, `seller_id` varchar(20) DEFAULT NULL, `order_snapshot` longtext DEFAULT NULL, `order_detail` longtext DEFAULT NULL, PRIMARY KEY (`id`), KEY `l_i_order` (`order_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY KEY(`order_id`) PARTITIONS 8;t_order_2テーブルを単一テーブルに変換します。ALTER TABLE t_order_2 SINGLE;
パーティションテーブルのパーティショニングポリシーの変更
既存のパーティショニングポリシーがビジネスニーズを満たさなくなった場合、オンラインで調整できます。これは、不適切なパーティションキーの選択によるデータスキューやクエリパターンの変更などの問題に役立ちます。パーティションキー、パーティション関数、またはパーティション数を変更して、物理的なデータ分布を再最適化できます。これにより、データホットスポットを解決し、新しいビジネスモデルに適応できます。
構文
ALTER TABLE 文を使用し、新しいパーティショニングポリシーを指定します。
ALTER TABLE tbl_name PARTITION BY new_partition_options;元のテーブルがキーパーティションテーブルであり、パーティショニングポリシーを変更して新しいパーティションキーがプライマリキーでなくなった場合、テーブルは自動パーティション作成などのプライマリキーパーティショニング機能を失います。詳細については、「AUTO モードでの自動シャーディング」をご参照ください。
パーティショニングポリシーを変更した後、プライマリキーにすべてのパーティションキー列が含まれていない場合、プライマリキーはローカルプライマリキーになります。パーティション内でのみ一意性を保証し、グローバルでは保証しません。詳細については、「プライマリキーと一意キー (AUTO モード)」をご参照ください。
例
パーティションキーの変更
t_order_3 という名前のテーブルは現在 order_id でパーティション化されています。しかし、ほとんどのクエリは buyer_id に基づいており、多くのクロスシャードクエリが発生しています。パーティションキーを buyer_id に変更し、パーティション数を 16 に設定できます。
元のテーブルスキーマを表示します。
CREATE TABLE t_order_3 ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY KEY(`order_id`) PARTITIONS 8;変更を実行します。
ALTER TABLE t_order_3 PARTITION BY KEY(buyer_id) PARTITIONS 16;変更後のテーブルスキーマを表示します。システムは自動的に
auto_shard_key_buyer_idという名前の新しいパーティションキーインデックスを作成します。SHOW FULL CREATE TABLE t_order_3;+-----------+-----------------------------------------------------------------------+ | Table | Create Table | +-----------+-----------------------------------------------------------------------+ | t_order_3 | CREATE TABLE `t_order_3` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`), LOCAL KEY `auto_shard_key_buyer_id` USING BTREE (`buyer_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_0900_ai_ci PARTITION BY KEY(`buyer_id`) PARTITIONS 16 /* tablegroup = `tg12` */ | +-----------+---------------------------------------------------------------------+
パーティショニング戦略の変更
t_order_4 という名前のテーブルは現在、id 列で RANGE パーティション化されています。しかし、ほとんどのクエリは order_id と buyer_id に基づいています。パーティショニングを、order_id と buyer_id をパーティションキーとする KEY パーティショニングに変更し、パーティション数を 16 に設定できます。
元のテーブルスキーマを表示します。
CREATE TABLE t_order_4 ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY RANGE(`id`) ( PARTITION p1 VALUES LESS THAN (100), PARTITION p2 VALUES LESS THAN (1000), PARTITION P3 VALUES LESS THAN MAXVALUE );変更を実行します。
ALTER TABLE t_order_4 PARTITION BY KEY(order_id, buyer_id) PARTITIONS 16;変更後のテーブルスキーマを表示します。システムは自動的に
auto_shard_key_order_id_buyer_idという名前の新しいパーティションキーインデックスを作成します。SHOW FULL CREATE TABLE t_order_4;+-----------+--------------------------------------------------------------------------------+ | Table | Create Table | +-----------+--------------------------------------------------------------------------------+ | t_order_4 | CREATE TABLE `t_order_4` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`), LOCAL KEY `auto_shard_key_order_id_buyer_id` USING BTREE (`order_id`, `buyer_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb3 PARTITION BY KEY(`order_id`,`buyer_id`) PARTITIONS 16 /* tablegroup = `tg15` */ | +-----------+------------------------------------------------------------------------------+
パーティション数の増加
データ量が増加するにつれて、パーティション数を増やしてデータをより広く分散させることができます。
元のテーブルスキーマを表示します。
CREATE TABLE t_order_5 ( `id` bigint(11) NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY KEY(`order_id`) PARTITIONS 8;変更を実行します。
ALTER TABLE t_order_5 PARTITION BY KEY(order_id) PARTITIONS 128;変更後、パーティション数は 8 から 128 に増加します。
SHOW FULL CREATE TABLE t_order_5;+-----------+----------------------------------------------------------+ | Table | Create Table | +-----------+----------------------------------------------------------+ | t_order_4 | CREATE TABLE `t_order_5` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_id` varchar(20) DEFAULT NULL, `buyer_id` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`), LOCAL KEY `auto_shard_key_order_id` USING BTREE (`order_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8mb3 PARTITION BY KEY(`order_id`) PARTITIONS 128 /* tablegroup = `tg13` */ | +-----------+---------------------------------------------------------+
タスク管理と緊急対応
時間のかかるデータ再配布 DDL タスクについては、次のコマンドを使用して完全なライフサイクル管理を行うことができます。
タスクの進捗を監視: SHOW DDL コマンドを使用して、現在および過去の DDL タスクのリストとそのステータスを表示できます。
タスクの一時停止と再開: DDL タスクがピーク時のビジネスに大きな影響を与える場合は、タスクを一時停止し、オフピーク時に再開できます。
-- タスクを一時停止します。SHOW DDL の結果から JobId を取得します。 PAUSE DDL <JobId>; -- タスクを再開します。 CONTINUE DDL <JobId>;タスクの終了とロールバック: DDL タスクが失敗した場合、または実行中のタスクをキャンセルしたい場合は、CANCEL DDL コマンドを使用できます。この操作はすべての変更をロールバックし、テーブルスキーマとデータをタスク開始前の状態に復元します。
-- タスクをロールバックします。SHOW DDL の結果から JobId を取得します。 CANCEL DDL <JobId>;
本番稼働
実行時間: オンラインビジネスへの潜在的なパフォーマンスへの影響を最小限に抑えるために、これらの操作はオフピーク時間帯に実行してください。
キャパシティプランニング: 変更を実行する前に、ターゲットのデータノード (DN) に十分なディスク領域、CPU、および 1 秒あたりの入出力操作 (IOPS) リソースがあるかどうかを評価してください。これは、パーティションテーブルを単一テーブルに変換するシナリオや、リソース不足によるタスクの失敗を防ぐための大幅なデータ再配布の場合に特に重要です。
操作前のバックアップ: 失敗した DDL タスクはロールバックできますが、本番環境で大きな変更を行う前に、完全なデータバックアップを作成することをお勧めします。
検証: タスクが完了したら、
SHOW CREATE TABLE <tablename>を使用して新しいテーブル定義を表示したり、SHOW TOPOLOGY を使用して新しいデータシャーディングトポロジーを表示したりできます。