Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 87c21bb

Browse files
committed
Implement ALTER TABLE ... SPLIT PARTITION ... command
This new DDL command splits a single partition into several parititions. Just like ALTER TABLE ... MERGE PARTITIONS ... command, new patitions are created using createPartitionTable() function with parent partition as the template. This commit comprises quite naive implementation which works in single process and holds the ACCESS EXCLUSIVE LOCK on the parent table during all the operations including the tuple routing. This is why this new DDL command can't be recommended for large partitioned tables under a high load. However, this implementation come in handy in certain cases even as is. Also, it could be used as a foundation for future implementations with lesser locking and possibly parallel. Discussion: https://postgr.es/m/c73a1746-0cd0-6bdd-6b23-3ae0b7c0c582%40postgrespro.ru Author: Dmitry Koval Reviewed-by: Matthias van de Meent, Laurenz Albe, Zhihong Yu, Justin Pryzby Reviewed-by: Alvaro Herrera, Robert Haas, Stephane Tachoires
1 parent 1adf16b commit 87c21bb

File tree

19 files changed

+3766
-14
lines changed

19 files changed

+3766
-14
lines changed

doc/src/sgml/ddl.sgml

+19
Original file line numberDiff line numberDiff line change
@@ -4400,6 +4400,25 @@ ALTER TABLE measurement
44004400
measurement_y2006m03) INTO measurement_y2006q1;
44014401
</programlisting>
44024402
</para>
4403+
4404+
<para>
4405+
Similarly to merging multiple table partitions, there is an option for
4406+
splitting a single partition into multiple using the
4407+
<link linkend="sql-altertable-split-partition"><command>ALTER TABLE ... SPLIT PARTITION</command></link>.
4408+
This feature could come in handy when one partition grows too big
4409+
and needs to be split into multiple. It's important to note that
4410+
this operation is not supported for hash-partitioned tables and acquires
4411+
an <literal>ACCESS EXCLUSIVE</literal> lock, which could impact high-load
4412+
systems due to the lock's restrictive nature. For example, we can split
4413+
the quarter partition back to monthly partitions:
4414+
<programlisting>
4415+
ALTER TABLE measurement SPLIT PARTITION measurement_y2006q1 INTO
4416+
(PARTITION measurement_y2006m01 FOR VALUES FROM ('2006-01-01') TO ('2006-02-01'),
4417+
PARTITION measurement_y2006m02 FOR VALUES FROM ('2006-02-01') TO ('2006-03-01'),
4418+
PARTITION measurement_y2006m03 FOR VALUES FROM ('2006-03-01') TO ('2006-04-01'));
4419+
</programlisting>
4420+
</para>
4421+
44034422
</sect3>
44044423

44054424
<sect3 id="ddl-partitioning-declarative-limitations">

doc/src/sgml/ref/alter_table.sgml

+63-2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
3737
ATTACH PARTITION <replaceable class="parameter">partition_name</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }
3838
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
3939
DETACH PARTITION <replaceable class="parameter">partition_name</replaceable> [ CONCURRENTLY | FINALIZE ]
40+
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
41+
SPLIT PARTITION <replaceable class="parameter">partition_name</replaceable> INTO
42+
(PARTITION <replaceable class="parameter">partition_name1</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT },
43+
PARTITION <replaceable class="parameter">partition_name2</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } [, ...])
4044
ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
4145
MERGE PARTITIONS (<replaceable class="parameter">partition_name1</replaceable>, <replaceable class="parameter">partition_name2</replaceable> [, ...])
4246
INTO <replaceable class="parameter">partition_name</replaceable>
@@ -1121,6 +1125,44 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
11211125
</listitem>
11221126
</varlistentry>
11231127

1128+
<varlistentry id="sql-altertable-split-partition">
1129+
<term><literal>SPLIT PARTITION <replaceable class="parameter">partition_name</replaceable> INTO (PARTITION <replaceable class="parameter">partition_name1</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }, PARTITION <replaceable class="parameter">partition_name2</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } [, ...])</literal></term>
1130+
1131+
<listitem>
1132+
<para>
1133+
This form splits a single partition of the target table. Hash-partitioning
1134+
is not supported. Bounds of new partitions should not overlap with new and
1135+
existing partitions (except <replaceable class="parameter">partition_name</replaceable>).
1136+
If the split partition is a DEFAULT partition, one of the new partitions must be DEFAULT.
1137+
In case one of the new partitions or one of existing partitions is DEFAULT,
1138+
new partitions <replaceable class="parameter">partition_name1</replaceable>,
1139+
<replaceable class="parameter">partition_name2</replaceable>, ... can have spaces
1140+
between partitions bounds. If the partitioned table does not have a DEFAULT
1141+
partition, the DEFAULT partition can be defined as one of the new partitions.
1142+
</para>
1143+
<para>
1144+
In case new partitions do not contain a DEFAULT partition and the partitioned table
1145+
does not have a DEFAULT partition, the following must be true: sum bounds of
1146+
new partitions <replaceable class="parameter">partition_name1</replaceable>,
1147+
<replaceable class="parameter">partition_name2</replaceable>, ... should be
1148+
equal to bound of split partition <replaceable class="parameter">partition_name</replaceable>.
1149+
One of the new partitions <replaceable class="parameter">partition_name1</replaceable>,
1150+
<replaceable class="parameter">partition_name2</replaceable>, ... can have
1151+
the same name as split partition <replaceable class="parameter">partition_name</replaceable>
1152+
(this is suitable in case of splitting a DEFAULT partition: we split it, but after
1153+
splitting we have a partition with the same name).
1154+
Only simple, non-partitioned partition can be split.
1155+
</para>
1156+
<note>
1157+
<para>
1158+
This command acquires an <literal>ACCESS EXCLUSIVE</literal> lock.
1159+
This is a significant limitation, which limits the usage of this
1160+
command with large partitioned tables under a high load.
1161+
</para>
1162+
</note>
1163+
</listitem>
1164+
</varlistentry>
1165+
11241166
<varlistentry id="sql-altertable-merge-partitions">
11251167
<term><literal>MERGE PARTITIONS (<replaceable class="parameter">partition_name1</replaceable>, <replaceable class="parameter">partition_name2</replaceable> [, ...]) INTO <replaceable class="parameter">partition_name</replaceable></literal></term>
11261168

@@ -1188,7 +1230,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
11881230
All the forms of ALTER TABLE that act on a single table, except
11891231
<literal>RENAME</literal>, <literal>SET SCHEMA</literal>,
11901232
<literal>ATTACH PARTITION</literal>, <literal>DETACH PARTITION</literal>,
1191-
and <literal>MERGE PARTITIONS</literal> can be combined into
1233+
<literal>SPLIT PARTITION</literal>, and <literal>MERGE PARTITIONS</literal>
1234+
can be combined into
11921235
a list of multiple alterations to be applied together. For example, it
11931236
is possible to add several columns and/or alter the type of several
11941237
columns in a single command. This is particularly useful with large
@@ -1432,7 +1475,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
14321475
<listitem>
14331476
<para>
14341477
The name of the table to attach as a new partition or to detach from this table,
1435-
or the name of the new merged partition.
1478+
or the name of split partition, or the name of the new merged partition.
14361479
</para>
14371480
</listitem>
14381481
</varlistentry>
@@ -1848,6 +1891,24 @@ ALTER TABLE measurement
18481891
DETACH PARTITION measurement_y2015m12;
18491892
</programlisting></para>
18501893

1894+
<para>
1895+
To split a single partition of the range-partitioned table:
1896+
<programlisting>
1897+
ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2023 INTO
1898+
(PARTITION sales_feb2023 FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'),
1899+
PARTITION sales_mar2023 FOR VALUES FROM ('2023-03-01') TO ('2023-04-01'),
1900+
PARTITION sales_apr2023 FOR VALUES FROM ('2023-04-01') TO ('2023-05-01'));
1901+
</programlisting></para>
1902+
1903+
<para>
1904+
To split a single partition of the list-partitioned table:
1905+
<programlisting>
1906+
ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
1907+
(PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
1908+
PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
1909+
PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
1910+
</programlisting></para>
1911+
18511912
<para>
18521913
To merge several partitions into one partition of the target table:
18531914
<programlisting>

0 commit comments

Comments
 (0)