Hologres V3.1 は論理パーティションテーブルをサポートしています。論理パーティションテーブルは、物理パーティションテーブルでよく見られる、過剰なテーブル数やメタデータの肥大化によって引き起こされる問題を解決することで、安定性を向上させます。このトピックでは、物理パーティションテーブルを論理パーティションテーブルに移行する方法について説明します。
シナリオ
以下のシナリオでは、物理パーティションテーブルから論理パーティションテーブルに移行します。
物理パーティションテーブルのテーブルグループに、10,000 を超えるような多数の子テーブルが含まれており、メタデータが過剰になっている場合。
毎日多くの新しいパーティションが追加され、頻繁なデータ定義言語 (DDL) 操作が必要な場合。
移行ソリューション
ソリューション 1: ビジネスを移行する前にデュアルライティングで検証する
このソリューションは、ビジネスへの影響を最小限に抑え、移行中の安定性を確保します。プロセスは次のとおりです。
元の物理パーティションテーブルのデータインポートタスクを停止し、新しい論理パーティションテーブルを作成して、既存データを移行します。詳細については、「既存データの移行」をご参照ください。
テーブルスキーマを変更する必要がなく、データ量が中程度の場合は、CLONE 構文を使用します。
テーブルスキーマを変更する必要がある場合、またはデータ量が大きくデータ移行の負荷が高い場合は、手動移行メソッドを使用します。
新しい論理パーティションテーブル用のデータインポートタスクを作成し、古いパーティションテーブルと新しいパーティションテーブルの両方に対してデータインポートタスクを開始して、デュアルライティングを実行します。
新しい論理パーティションテーブルを検証します。
次の 2 つの方法のいずれかでビジネスを移行します。
(推奨) クエリを新しい論理パーティションテーブルに直接移行します。これを行うには、クエリタスクのターゲットテーブル名を新しい論理パーティションテーブルの名前に変更し、必要に応じてパーティションフィルター条件を追加します。
新しい論理パーティションテーブルの名前を元の物理パーティションテーブルの名前に変更します。次に、元のテーブルの子テーブルに対する書き込みタスクとクエリタスクを変更して、親テーブルへの書き込みとクエリを行い、パーティションフィルター条件を追加します。コマンドは次のとおりです。
BEGIN; ALTER TABLE <source_table_name> RENAME TO <source_table_name_archive>; ALTER TABLE <target_table_name> RENAME TO <source_table_name>; COMMIT;
運用保守 (O&M) タスクを適応させます。
ソリューション 2: クイック移行 (非推奨)
より長い変更タイムウィンドウと、一部の読み取りおよび書き込みタスクの潜在的な失敗を受け入れることができる場合は、REBUILD 構文を使用して移行できます。プロセスは次のとおりです。
元の物理パーティションテーブルのデータインポートタスクを停止します。
REBUILD 構文を使用して既存データを移行します。詳細については、「REBUILD 構文」をご参照ください。
インポートタスクを変更して開始します。
クエリタスクを適応させます。
O&M タスクを適応させます。
パーティションテーブルの移行
テーブル構造の変換
論理パーティションテーブルを作成するためのステートメントは、物理パーティションテーブルを作成するためのステートメントと次の点で異なります。
DDL ステートメントに LOGICAL キーワードを追加し、パーティションキーに NOT NULL 制約を追加します。
(オプション) 物理パーティションテーブルは 1 つのパーティションキーのみをサポートしますが、論理パーティションテーブルは最大 2 つをサポートします。必要に応じて 2 番目のパーティションキーを追加できます。
次の例を考えてみましょう。
物理パーティションテーブルを作成する:
BEGIN; CREATE TABLE user_profile ( a TEXT, b TEXT, ds TEXT ) PARTITION BY LIST (ds); CREATE TABLE user_profile_202503 PARTITION OF user_profile FOR VALUES IN ('202503'); CREATE TABLE user_profile_202504 PARTITION OF user_profile FOR VALUES IN ('202504'); COMMIT;論理パーティションテーブルを作成する:
パーティションキーを 1 つ保持する。
CREATE TABLE user_profile_lp_1 ( a TEXT, b TEXT, ds TEXT NOT NULL) LOGICAL PARTITION BY LIST (ds);2 つのパーティションキー (年と月) に変更します。
CREATE TABLE user_profile_lp_2 ( a TEXT, b TEXT, yy TEXT NOT NULL, mm TEXT NOT NULL) LOGICAL PARTITION BY LIST (yy, mm);
テーブルマッピング
次の表は、物理パーティションテーブルと論理パーティションテーブル間のテーブルプロパティとパーティションプロパティのマッピングを示しています。
元の物理パーティションテーブルがパーティションキーに TEXT などの非時間データ型を使用し、動的パーティション管理が有効になっている場合、テーブルを論理パーティションテーブルに変換した後、自動パーティションクリーンアップ (partition_expiration_time パラメーター) とコールドストレージへの自動変換 (partition_keep_hot_window パラメーター) はサポートされません。
モジュール | 機能 | 物理パーティションテーブル | 論理パーティションテーブル |
親テーブルの動的パーティション管理 | 動的パーティション管理の有効化 | auto_partitioning_enable | 該当なし。 |
時間単位 | auto_partitioning_time_unit | 個別の構成は不要です。時間ベースのパーティションのみがサポートされます。 | |
タイムゾーン | auto_partitioning_time_zone | 該当なし。 | |
事前に作成されるパーティションの数 | auto_partitioning_num_precreate | 該当なし。 | |
保持する履歴パーティションの数 | auto_partitioning_num_retention | 期限切れパーティションの自動クリーンアップは、partition_expiration_time パラメーターによって実装されます。 | |
保持するホットパーティションの数 | auto_partitioning_num_hot | 期限切れパーティションのコールドストレージへの自動変換は、partition_keep_hot_window パラメーターによって実装されます。 | |
動的パーティション管理のスケジューリング時間 | auto_partitioning_schd_start_time | 該当なし。 | |
子テーブルの日時フォーマット | auto_partitioning_time_format | 該当なし。 | |
子テーブル/サブパーティション管理 | パーティションを保持するかどうか | keep_alive | keep_alive |
パーティションをコールド/ホットストレージに保持するかどうか | storage_mode | storage_mode | |
バイナリロギング | 親テーブルのバイナリロギングを有効にする | binlog_level | binlog_level |
親テーブルのバイナリロギングライフサイクル | binlog_ttl | binlog_ttl | |
パーティションごとにバイナリロギングを動的に管理する | サポートされていません。 | partition_generate_binlog_window | |
サブパーティションのバイナリロギングを有効にする | 親テーブルから継承されます。変更できません。 | generate_binlog | |
サブパーティションのバイナリロギングライフサイクル | 子テーブルに対して変更できます。 | 親テーブルから継承されます。変更できません。 | |
インデックスおよびその他のテーブルプロパティ | サブパーティションの bitmap_columns | 子テーブルに対して変更できます。 | 親テーブルから継承されます。変更できません。 |
サブパーティションの dictionary_encoding_columns | 子テーブルに対して変更できます。 | 親テーブルから継承されます。変更できません。 | |
orientation や table_group などのその他のテーブルプロパティ | 親テーブルから継承されます。変更できません。 | 親テーブルから継承されます。変更できません。 | |
プライマリキー、distribution_key、clustering_key などのその他のインデックス | 親テーブルから継承されます。変更できません。 | 親テーブルから継承されます。変更できません。 |
既存データの移行
CLONE
テーブルスキーマを変更する必要がなく、データ量が中程度の場合は、CLONE 構文を使用できます。
このコマンドは、新しい論理パーティションテーブルを自動的に作成し、元のテーブルから新しいテーブルにデータをコピーします。テーブルスキーマは同一のままです。元の物理パーティションテーブルは削除されません。
元のテーブルにリアルタイム書き込みタスクがある場合:
CLONE コマンドを実行する前に、リアルタイム書き込みタスクを手動で停止する必要があります。
CLONE 操作が完了したら、新しいリアルタイム書き込みタスクを作成して、データソースから古いテーブルと新しいテーブルの両方にデータを書き込みます。これにより、両方のテーブルのデータの一貫性と完全性が確保されます。
移行が完了したら、古いパーティションテーブルと新しいパーティションテーブルの両方のデータと特徴を徹底的に検証します。インポート、クエリ、および O&M タスクを適応させた後、元の物理パーティションテーブルを削除できます。
例:
CALL hg_clone_to_logical_partition('user_profile', 'user_profile_logical');大量のデータを移行しており、操作に時間がかかると予想される場合は、ASYNC コマンドを使用してタスクをバックグラウンドで実行できます。コマンドが送信されると、CALL ステートメントの query_id が返されます。この query_id を使用して、クエリインサイトで非同期タスクの実行ステータスを確認できます。
SET statement_timeout = 0;
ASYNC CALL hg_clone_to_logical_partition('user_profile', 'user_profile_logical');手動移行
テーブルスキーマを変更する必要がある場合、またはデータ量が大きくデータ移行の負荷が高い場合は、手動移行メソッドを使用します。このメソッドは、移行ペースを制御するためのより高い柔軟性を提供します。
このメソッドでは、新しい論理パーティションテーブルを手動で作成し、元のテーブルから新しいテーブルにデータをコピーします。テーブルを手動で作成するため、テーブルプロパティを最適化し、移行ペースを制御する柔軟性があります。
元のテーブルにリアルタイム書き込みタスクがある場合:
データをインポートする前に、リアルタイム書き込みタスクを手動で停止する必要があります。
データインポートが完了したら、新しいリアルタイム書き込みタスクを作成して、データソースから古いテーブルと新しいテーブルの両方にデータを書き込みます。これにより、両方のテーブルのデータの一貫性と完全性が確保されます。
移行が完了したら、古いパーティションテーブルと新しいパーティションテーブルの両方のデータと特徴を徹底的に検証します。インポート、クエリ、および O&M タスクを適応させた後、元の物理パーティションテーブルを削除できます。
移行手順:
テーブルを作成します。
詳細については、このトピックの「論理パーティションテーブルを作成する」をご参照ください。
hg_insert_overwrite ストアドプロシージャを使用して既存データをインポートします。
CALL hg_insert_overwrite('logical_partition_table', '{20250601, 20250602}'::text[], 'SELECT * FROM tb');
REBUILD 構文(非推奨)
より長い変更タイムウィンドウと、一部の読み取りおよび書き込みタスクの潜在的な失敗を受け入れることができる場合は、REBUILD 構文を使用して移行できます。詳細については、「REBUILD (ベータ)」をご参照ください。
次の点に注意してください。
REBUILD 機能を使用してパーティションテーブルを移行すると、新しい論理パーティションテーブルの名前は元のテーブル名と同じになります。元の物理パーティションテーブルは
tmp_rebuild_old_<query_id>_<unique_id>_<table_name>に名前が変更されます。移行が完了したら、インポート、クエリ、および O&M タスクを適応させる必要があります。
適応が完了する前に、互換性の問題により関連タスクが失敗する可能性があります。このため、このメソッドはパーティションテーブルの移行には推奨されません。
例:
-- パーティションフィールドに NOT NULL 制約を追加します。
ASYNC REBUILD TABLE user_profile ALTER ds SET NOT NULL;
-- 物理パーティションテーブルを論理パーティションテーブルに変換し、元の物理パーティションテーブルを保持します。
ASYNC REBUILD TABLE user_profile WITH (keep_source) TO logical partition;インポートタスクの適応
元の物理パーティションテーブルのデータインポートタスクが Fixed Plan を使用して親テーブルにデータをインポートする場合、タスクを変更する必要はありません。
元の物理パーティションテーブルのデータインポートタスクが子テーブルにデータをインポートする場合、次の適応を行います。
新しい子テーブルを作成するステートメントを削除します。論理パーティションテーブルには物理的な子テーブルがなく、手動で作成する必要はありません。
インポートタスクで、子テーブル名を論理パーティションテーブルの親テーブルの名前に変更します。
シナリオ 1: 子テーブルまたはサブパーティションを追加してデータをインポートする
-- 元の物理パーティションテーブルのインポートタスク
CREATE TABLE user_profile_202505 PARTITION OF user_profile FOR VALUES IN ('202505');
INSERT INTO user_profile_202505 SELECT a, b, ds FROM <source_table> WHERE ds = '202505';
-- 新しい論理パーティションテーブルのインポートタスク
INSERT INTO user_profile_lp_1 SELECT a, b, ds FROM <source_table> WHERE ds = '202505';シナリオ 2: 子テーブルまたはサブパーティションのデータをリフレッシュする
元の物理パーティションテーブルが hg_insert_overwrite ストアドプロシージャを使用して一度に複数の子テーブルのデータをリフレッシュする場合、移行後にタスクを適応させる必要があります。タスクをパーティションごとに分割し、新しいタスクを直列に実行し、ネイティブの INSERT OVERWRITE 構文を使用します。詳細については、「INSERT OVERWRITE」をご参照ください。
-- 元の物理パーティションテーブルのリフレッシュタスク (一時テーブルを作成して INSERT OVERWRITE を実装)
-- 一時テーブルを作成してデータをインポートします。
CREATE TABLE tmp_user_profile_202505(a text, b text, ds text);
INSERT INTO tmp_user_profile_202505 SELECT a, b, ds FROM <source_table> WHERE ds = '202505';
-- 一時テーブルの名前を変更し、親テーブルにアタッチします。
BEGIN;
DROP TABLE IF EXISTS user_profile_202505;
ALTER TABLE tmp_user_profile_202505 RENAME TO user_profile_202505;
ALTER TABLE user_profile ATTACH PARTITION user_profile_202505 FOR VALUES IN ('202505');
COMMIT;
-- 元の物理パーティションテーブルのリフレッシュタスク (hg_insert_overwrite コマンドを使用)
CALL hg_insert_overwrite('user_profile' , '202505', $$SELECT a, b, mm FROM <source_table> WHERE ds='202505'$$);
-- 新しい論理パーティションテーブルのリフレッシュタスク (ネイティブの INSERT OVERWRITE 構文を使用)
INSERT OVERWRITE user_profile_lp_1 PARTITION (ds = '202505') SELECT a, b, ds FROM <source_table> WHERE ds='202505';クエリタスクの適応
元の物理パーティションテーブルのデータクエリタスクが親テーブルをクエリする場合、タスクを変更する必要はありません。
元の物理パーティションテーブルのデータクエリタスクが子テーブルをクエリする場合、タスクを親テーブルをクエリするように変更し、パーティションフィルター条件を追加します。例:
-- 元の物理パーティションテーブルの子テーブルのクエリタスク SELECT * FROM user_profile_202504; -- 論理パーティションテーブルのクエリタスク SELECT * FROM user_profile_lp_1 WHERE ds = '202504';
O&M タスクの適応
日常の O&M タスクも、物理パーティションテーブルと論理パーティションテーブルで異なる場合があります。次の表は、いくつかの一般的な O&M シナリオを比較したものです。
クエリタイプ | 物理パーティションテーブル | 論理パーティションテーブル | 説明 |
親テーブル DDL のクエリ |
| 違いはありません。 | |
親テーブルプロパティのクエリ |
| 違いはありません。 | |
パーティションリストのクエリ |
| 異なります。 | |
パーティションのプロパティのクエリ |
|
| 異なります。 |
親テーブル ストレージのクエリ |
|
| 異なります。 |