はじめに
にゃーん。
今回は小ネタ。
前回の記事(PostgreSQL 17がやってくる(5) パーティションの分割&マージ )でPostgreSQL 17で入るパーティションの分割とマージについて書いたけど、少し気になることがあったので追加で確認してみた。
ネストしたパーティション
PostgrSQLのパーティションはねストすることができる。
例えば、
test
+-- test_2023
+-- test_2024
| +--- 2024_1q
| +--- 2024_2q
| +--- 2024_3q
| +--- 2024_4q
+-- test_2025
のように、日付をレンジキーにして、test_2023
,test_2024
,test_2025
のように分割し、更にtest_2024
も日付をレンジキーにして、test_2024_1q
,test_2024_2q
,test_2024_3q
,test_2024_4q
のようにネストしたパーティションを構成することができる。
psqlの\d+
メタコマンドで見るとこんな感じ。
postgres@test=# \d+ test
Partitioned table "public.test"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
----------+---------+-----------+----------+---------+----------+-------------+--------------+-------------
id | integer | | | | plain | | |
part_key | date | | | | plain | | |
data | text | | | | extended | | |
Partition key: RANGE (part_key)
Partitions: test_2023 FOR VALUES FROM ('2023-01-01') TO ('2024-01-01'),
test_2024 FOR VALUES FROM ('2024-01-01') TO ('2025-01-01'), PARTITIONED,
test_2025 FOR VALUES FROM ('2025-01-01') TO ('2026-01-01'),
test_default DEFAULT
postgres@test=# \d+ test_2024
Partitioned table "public.test_2024"
Column | Type | Collation | Nullable | Default | Storage | Compression | Stats target | Description
----------+---------+-----------+----------+---------+----------+-------------+--------------+-------------
id | integer | | | | plain | | |
part_key | date | | | | plain | | |
data | text | | | | extended | | |
Partition of: test FOR VALUES FROM ('2024-01-01') TO ('2025-01-01')
Partition constraint: ((part_key IS NOT NULL) AND (part_key >= '2024-01-01'::date) AND (part_key < '2025-01-01'::date))
Partition key: RANGE (part_key)
Partitions: test_2024_1q FOR VALUES FROM ('2024-01-01') TO ('2024-04-01'),
test_2024_2q FOR VALUES FROM ('2024-04-01') TO ('2024-07-01'),
test_2024_3q FOR VALUES FROM ('2024-07-01') TO ('2024-10-01'),
test_2024_4q FOR VALUES FROM ('2024-10-01') TO ('2025-01-01')
postgres@test=#
ネストしたパーティションの分割
検証時のバージョン
2024-05-10(commit 31e8f4e619d9b5856fa2bd5713cb1e2e170a9c7d)を使って検証した。
検証内容
最初に示した中間階層test_2024
のパーティションを指定して、月単位に一気に分割できるか確認してみる。
$ psql test -ef split_year2month.sql
Null display is "(null)".
ALTER TABLE test_2024 SPLIT PARTITION test_2024 INTO
(
PARTITION test_01m FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'),
PARTITION test_02m FOR VALUES FROM ('2024-02-01') TO ('2024-03-01'),
PARTITION test_03m FOR VALUES FROM ('2024-03-01') TO ('2024-04-01'),
PARTITION test_01m FOR VALUES FROM ('2024-04-01') TO ('2024-05-01'),
PARTITION test_02m FOR VALUES FROM ('2024-05-01') TO ('2024-06-01'),
PARTITION test_03m FOR VALUES FROM ('2024-06-01') TO ('2024-07-01'),
PARTITION test_01m FOR VALUES FROM ('2024-07-01') TO ('2024-08-01'),
PARTITION test_02m FOR VALUES FROM ('2024-08-01') TO ('2024-09-01'),
PARTITION test_03m FOR VALUES FROM ('2024-09-01') TO ('2024-10-01'),
PARTITION test_01m FOR VALUES FROM ('2024-10-01') TO ('2024-11-01'),
PARTITION test_02m FOR VALUES FROM ('2024-11-01') TO ('2024-12-01'),
PARTITION test_03m FOR VALUES FROM ('2024-12-01') TO ('2025-01-01')
);
psql:split_year2month.sql:15: ERROR: "test_2024" is not a table
$
ダメでした。
分割対象のtest_2024
を指定したけど、not a table
と怒られてしまう。
いや、test_2024
もPARTITIONEDではあるけどtableじゃないの?と一瞬思ったけど、たぶん実際にデータが格納されている末端のテーブルじゃないからダメなのかも。
(PARTITIONEDの種別がついているとダメっぽい)
なので、パーティションを分割する場合には、SPLIT
の対象には、実際にデータが格納されている末端の階層のパーティションを指定しないとダメっぽい。
今回の場合だと、test_2024
を分割した末端の階層(test_2024_1q
,test_2024_2q
,test_2024_3q
,test_2024_4q
)ごとにALTER TABLE ... SPLIT
コマンドを発行する必要がある。
$ psql test -ef split_quarter2month.sql
Null display is "(null)".
ALTER TABLE test_2024 SPLIT PARTITION test_2024_1q INTO
(
PARTITION test_2024_01m FOR VALUES FROM ('2024-01-01') TO ('2024-02-01'),
PARTITION test_2024_02m FOR VALUES FROM ('2024-02-01') TO ('2024-03-01'),
PARTITION test_2024_03m FOR VALUES FROM ('2024-03-01') TO ('2024-04-01')
);
ALTER TABLE
ALTER TABLE test_2024 SPLIT PARTITION test_2024_2q INTO
(
PARTITION test_2024_04m FOR VALUES FROM ('2024-04-01') TO ('2024-05-01'),
PARTITION test_2024_05m FOR VALUES FROM ('2024-05-01') TO ('2024-06-01'),
PARTITION test_2024_06m FOR VALUES FROM ('2024-06-01') TO ('2024-07-01')
);
ALTER TABLE
ALTER TABLE test_2024 SPLIT PARTITION test_2024_3q INTO
(
PARTITION test_2024_07m FOR VALUES FROM ('2024-07-01') TO ('2024-08-01'),
PARTITION test_2024_08m FOR VALUES FROM ('2024-08-01') TO ('2024-09-01'),
PARTITION test_2024_09m FOR VALUES FROM ('2024-09-01') TO ('2024-10-01')
);
ALTER TABLE
ALTER TABLE test_2024 SPLIT PARTITION test_2024_4q INTO
(
PARTITION test_2024_10m FOR VALUES FROM ('2024-10-01') TO ('2024-11-01'),
PARTITION test_2024_11m FOR VALUES FROM ('2024-11-01') TO ('2024-12-01'),
PARTITION test_2024_12m FOR VALUES FROM ('2024-12-01') TO ('2025-01-01')
);
ALTER TABLE
$
おわりに
ALTER TABLE ... SPLIT
コマンドでは、中間の階層のパーティションを指定して、一気に分割はできないことがわかった。
複数段のパーティションテーブルを設計する場合の注意点が分かったのでヨシ!