物理パーティションテーブルは、スケール時に次の 2 つの安定性の問題が発生する可能性があります。1 つは、テーブルグループに 10,000 個を超える子テーブル(パーティション)が存在するとメタデータが肥大化すること、もう 1 つは、毎日新しいパーティションを追加することで高頻度の DDL 操作が発生し、パフォーマンスが低下することです。Hologres V3.1 では、これらの問題に対処するために論理パーティションテーブルが導入されました。本トピックでは、既存の物理パーティションテーブルを論理パーティションテーブルに移行する方法について説明します。
移行のタイミング
ご利用の物理パーティションテーブルが次のいずれかの条件を満たす場合は、論理パーティションテーブルへの移行を検討してください。
-
テーブルグループに 10,000 個を超える子テーブルが含まれており、メタデータが大規模になっている。
-
新しいパーティションが毎日追加され、DDL 操作が頻繁に発生している。
移行アプローチの選択
|
アプローチ |
使用タイミング |
ダウンタイム |
リスク |
|
デュアルライト検証(推奨) |
業務継続性が重要なすべての移行 |
最小限 — 古いテーブルと新しいテーブルを並行して実行 |
低 |
|
REBUILD(非推奨) |
変更ウィンドウを長く設定でき、一部の読み取り/書き込みタスクの失敗が許容できる場合 |
長い — 移行中に書き込みタスクが停止 |
高 — 適応完了前にタスクが失敗する可能性あり |
デュアルライト検証による移行(推奨)
このアプローチでは、移行中に古いテーブルと新しいテーブルを並行して実行し、業務への影響を最小限に抑えます。
概要
-
物理パーティションテーブルへの書き込みタスクを停止し、新しい論理パーティションテーブルを作成して、既存データをコピーします。
-
新しいテーブル向けの書き込みタスクを作成し、両方のテーブルに同時に書き込むデュアルライトを有効にします。
-
新しい論理パーティションテーブルを検証します。
-
業務クエリおよび書き込みタスクを新しいテーブルに切り替えます。
-
O&M タスクを新しいテーブルに適応させます。
ステップ 1:論理パーティションテーブルの作成と既存データのロード
状況に応じて、以下のいずれかの方法を選択してください。
方法 1:CLONE(スキーマ変更がなく、データ量が中程度の場合に推奨)
hg_clone_to_logical_partition は、新しい論理パーティションテーブルを自動的に作成し、元のテーブルからすべてのデータをコピーします。元の物理パーティションテーブルは削除されません。
CLONE 実行前にリアルタイムの書き込みタスクを停止してください。CLONE 完了後は、古いテーブルと新しいテーブルの両方に同時に書き込む新しい書き込みタスクを作成し、データを同期させてください。移行完了後は、両テーブルを十分に検証し、インポートタスク、クエリタスク、O&M タスクの適応を完了したうえで、元の物理パーティションテーブルをクリーンアップしてください。
CALL hg_clone_to_logical_partition('user_profile', 'user_profile_logical');
データ量が多い場合は、タイムアウトを回避するために CLONE を非同期で実行してください。送信後は、返された query_id を使用して、クエリインサイトの取得で進行状況を確認できます。
SET statement_timeout = 0;
ASYNC CALL hg_clone_to_logical_partition('user_profile', 'user_profile_logical');
方法 2:手動移行(スキーマ変更が必要な場合やデータ量が多い場合)
手動移行により、テーブルスキーマを最適化し、移行のペースを制御できます。
データインポート前にリアルタイムの書き込みタスクを停止してください。インポート完了後は、両方のテーブルに同時に書き込む新しい書き込みタスクを作成してください。移行完了後は、両テーブルを十分に検証し、インポートタスク、クエリタスク、O&M タスクの適応を完了したうえで、元の物理パーティションテーブルをクリーンアップしてください。
-
論理パーティションテーブルを作成します。必要な DDL 変更については、「テーブルスキーマの変換」をご参照ください。
-
hg_insert_overwriteを使用して、既存データをインポートします。CALL hg_insert_overwrite('logical_partition_table', '{20250601, 20250602}'::text[], 'SELECT * FROM tb');
ステップ 2:デュアルライトの有効化
論理パーティションテーブル向けの新しい書き込みタスクを作成し、物理パーティションテーブル向けの既存の書き込みタスクと並行して実行します。これにより、検証期間中に両方のテーブルのデータが同期された状態を維持できます。
ステップ 3:新しいテーブルの検証
論理パーティションテーブルに対して業務クエリを実行し、データおよび動作が物理パーティションテーブルと一致することを確認してください。
ステップ 4:業務を新しいテーブルに切り替え
以下のいずれかの方法を使用してください。
オプション A(推奨): クエリタスク内のテーブル名を新しい論理パーティションテーブルを指すように更新し、必要に応じてパーティションフィルター条件を追加します。
オプション B: RENAME を使用して、テーブル名をアトミックに交換します。
この操作により、既存のテーブル名が変更されます。実行前に、書き込みタスクおよびクエリタスクが親テーブルを対象とする準備ができていることを確認してください。
BEGIN;
ALTER TABLE <source_table_name> RENAME TO <source_table_name_archive>;
ALTER TABLE <target_table_name> RENAME TO <source_table_name>;
COMMIT;
切り替え後、子テーブルを対象としていた書き込みタスクおよびクエリタスクを更新し、親テーブルを使用するように変更するとともに、パーティションフィルター条件を追加してください。
ステップ 5:O&M タスクの適応
物理パーティションテーブルと論理パーティションテーブルで異なる O&M タスクを更新してください。詳細については、「O&M タスクの適応」をご参照ください。
REBUILD を使用した移行(非推奨)
REBUILD 移行中は、一部の読み取りおよび書き込みタスクが失敗する可能性があります。このアプローチは、変更ウィンドウを長く設定でき、一時的なタスクの失敗が許容できる場合にのみ使用してください。パーティションテーブルの移行にはこの方法を推奨しません。
REBUILD 完了後、物理パーティションテーブルは tmp_rebuild_old_<query_id>_<unique_id>_<table_name> という名前に変更されます。タスクの適応が完了するまで、関連タスクでエラーが発生する可能性があります。
-
物理パーティションテーブルへの書き込みタスクを停止します。
-
テーブルを変換するために REBUILD を実行します。
-- パーティションフィールドに NOT NULL 制約を追加します。 ASYNC REBUILD TABLE user_profile ALTER ds SET NOT NULL; -- 物理パーティションテーブルを論理パーティションテーブルに変換します(元のテーブルは保持されます)。 ASYNC REBUILD TABLE user_profile WITH (keep_source) TO logical partition;詳細については、「REBUILD」をご参照ください。
-
書き込みタスクを更新して再起動します。
-
クエリタスクを新しい論理パーティションテーブルに適応させます。
-
O&M タスクを新しい論理パーティションテーブルに適応させます。
テーブルスキーマの変換
既存の物理パーティションテーブルの DDL から論理パーティションテーブルを作成する際は、以下の変更を行ってください。
-
PARTITION BYの前にLOGICALキーワードを追加します。 -
パーティションキー列に
NOT NULLを追加します。 -
(オプション)2 番目のパーティションキーを追加します。物理パーティションテーブルは 1 つのパーティションキーのみをサポートしますが、論理パーティションテーブルは最大 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 つの場合(ds を年用の yy と月用の mm に分割):
CREATE TABLE user_profile_lp_2 (
a TEXT,
b TEXT,
yy TEXT NOT NULL,
mm TEXT NOT NULL)
LOGICAL PARTITION BY LIST (yy, mm);
インポートタスクの適応
インポートタスクが 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 構文を使用してください。
-- 元の形式:物理パーティションテーブル(一時テーブル方式)
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 操作では、論理パーティションテーブル向けに異なるシステムテーブルまたは関数を使用します。
|
操作 |
物理パーティションテーブル |
論理パーティションテーブル |
|
親テーブルの DDL のクエリ |
|
差異なし |
|
親テーブルのプロパティのクエリ |
|
差異なし |
|
パーティションリストのクエリ |
|
|
|
パーティションプロパティのクエリ |
|
|
|
親テーブルのストレージのクエリ |
|
|
プロパティおよびパラメーターのマッピング
以下の表は、物理パーティションテーブルと論理パーティションテーブル間での自動パーティション管理パラメーターおよびその他のテーブルプロパティの対応関係を示しています。
元の物理パーティションテーブルが時間以外のフィールド(TEXT など)をパーティションキーとして使用しており、自動パーティション管理を利用している場合、Hologres V4.2 以降では、論理パーティションテーブルで partition_expiration_time および partition_keep_hot_window がサポートされます。partition_time_format を設定して時間フォーマットを指定する必要があります。V4.2 より前のバージョンでは、この構成はサポートされていません。
|
モジュール |
機能 |
物理パーティションテーブル |
論理パーティションテーブル |
|
自動パーティション分割 |
有効化 |
|
同等のパラメーターなし |
|
時間単位 |
|
個別の構成なし。時間パーティションのみサポート |
|
|
タイムゾーン |
|
同等のパラメーターなし |
|
|
事前作成済みパーティション |
|
同等のパラメーターなし |
|
|
保持するパーティション数 |
|
|
|
|
保持するホットパーティション数 |
|
|
|
|
スケジュール設定時間 |
|
同等のパラメーターなし |
|
|
パーティション日付/時刻フォーマット |
|
同等のパラメーターなし |
|
|
パーティション管理 |
パーティション保持 |
|
|
|
ホット/コールドストレージ |
|
|
|
|
バイナリログ |
有効化(親テーブル) |
|
|
|
ライフサイクル(親テーブル) |
|
|
|
|
パーティションごとの動的バイナリログ |
サポートなし |
|
|
|
有効化(パーティション) |
親から継承。変更はサポートされない |
|
|
|
ライフサイクル(パーティション) |
パーティションでの変更をサポート |
親から継承。変更はサポートされない |
|
|
インデックスおよびテーブルプロパティ |
|
パーティションでの変更をサポート |
親から継承。変更はサポートされない |
|
|
パーティションでの変更をサポート |
親から継承。変更はサポートされない |
|
|
|
親から継承。変更はサポートされない |
親から継承。変更はサポートされない |
|
|
主キー、 |
親から継承。変更はサポートされない |
親から継承。変更はサポートされない |