Skip to content

Commit b4f4c02

Browse files
author
Devansh Saxena
committed
[#23431] YSQL: Disable default partition creation
Summary: This diff disables the defualt partition creation in pg_partman as after creating default partition the further maintenance work of moving rows out of default partition into newly created partitions will cause this error ``` updated partition constraint for default partition would be violated by some row ``` When `partition_data_proc` or `run_maintenance` functions tries to move rows from default partition to a newly created child partition, it does that process in following steps 1.) Create a temporary table to hold the data that needs to be moved. This is done because child tables cannot be created in native partitioning if data that belongs to it exists in the default. ``` CREATE TEMP TABLE IF NOT EXISTS partman_temp_data_storage (LIKE %I.%I INCLUDING INDEXES) ON COMMIT DROP ``` 2.) Move rows from default table to the temp table. ``` EXECUTE format('WITH partition_data AS ( DELETE FROM %1$I.%2$I WHERE %3$I >= %4$s AND %3$I < %5$s RETURNING *) INSERT INTO partman_temp_data_storage (%6$s) SELECT %6$s FROM partition_data' ``` 3.) Create the child partition via create_partition_id function ``` PERFORM @[email protected]_partition_id(p_parent_table, v_partition_id, p_analyze); ``` 4.) After creation of the child partition, move the data from temp table to the new child partition. ``` EXECUTE format('WITH partition_data AS ( DELETE FROM ONLY %1$I.%2$I WHERE %3$I >= %4$s AND %3$I < %5$s RETURNING *) INSERT INTO %1$I.%6$I (%7$s) SELECT %7$s FROM partition_data ``` The issue is occurring at step 3 while creating the new child partition. Since currently YugabyteDB does not have transactional DDL support and the plsql functions are run inside a transactional context, `create_partition_id` and `partition_data_proc` are in different transactional context. When `create_partition_id` tries to attach the newly created child partition, that transaction still finds the default partition have violating rows present and the `ALTER TABLE ATTACH` query fails stating ``` updated partition constraint for default partition would be violated by some row . ``` Hence to not get fall in this scenario, default partition creation should be disabled in pg_partman. This diff also adds the check that if default partition is created deliberately then `partition_data_proc` and `run_maintenance` will early exit without performing any operation. Jira: DB-12352 Test Plan: Jenkins: test regex: PgPartmanTest* Reviewers: skumar, hsunder Reviewed By: hsunder Subscribers: yql Differential Revision: https://phorge.dev.yugabyte.com/D39010
1 parent b903e0b commit b4f4c02

15 files changed

+460
-17
lines changed

src/postgres/third-party-extensions/pg_partman/sql/functions/create_parent.sql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ v_top_parent_schema text := split_part(p_parent_table, '.', 1);
7575
v_top_parent_table text := split_part(p_parent_table, '.', 2);
7676
v_unlogged char;
7777
yb_v_parent_table_default regclass;
78+
yb_v_enable_default_partition boolean := false;
7879

7980
BEGIN
8081
/*
@@ -730,7 +731,10 @@ IF v_control_type = 'id' AND p_epoch = 'none' THEN
730731

731732
END IF; -- End IF id
732733

733-
IF p_type = 'native' AND current_setting('server_version_num')::int >= 110000 THEN
734+
/* YB: Disable default partition creation.
735+
* TODO(#3109): Re-enable it after transactional DDL support.
736+
*/
737+
IF yb_v_enable_default_partition AND p_type = 'native' AND current_setting('server_version_num')::int >= 110000 THEN
734738
-- Add default partition to native sets in PG11+
735739

736740
v_default_partition := @[email protected]_name_length(v_parent_tablename, '_default', FALSE);

src/postgres/third-party-extensions/pg_partman/sql/functions/partition_data_id.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ ELSIF v_partition_type = 'native' AND current_setting('server_version_num')::int
106106
v_source_tablename := v_default_tablename;
107107

108108
v_default_exists := true;
109+
-- YB: Moving data from default partition is not supported
110+
-- TODO(#3109): Re-enable it after transactional DDL support.
111+
RAISE NOTICE 'Moving data from default partition to newly created child tables is not supported';
112+
RETURN v_total_rows;
109113
EXECUTE format ('CREATE TEMP TABLE IF NOT EXISTS partman_temp_data_storage (LIKE %I.%I INCLUDING INDEXES) ON COMMIT DROP', v_source_schemaname, v_source_tablename);
110114
ELSE
111115
RAISE DEBUG 'No default table found when partition_data_id() was called';

src/postgres/third-party-extensions/pg_partman/sql/functions/partition_data_time.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ ELSIF v_partition_type = 'native' AND current_setting('server_version_num')::int
118118
v_source_tablename := v_default_tablename;
119119

120120
v_default_exists := true;
121+
-- YB: Moving data from default partition is not supported
122+
-- TODO(#3109): Re-enable it after transactional DDL support.
123+
RAISE NOTICE 'Moving data from default partition to newly created child tables is not supported';
124+
RETURN v_total_rows;
121125
EXECUTE format ('CREATE TEMP TABLE IF NOT EXISTS partman_temp_data_storage (LIKE %I.%I INCLUDING INDEXES) ON COMMIT DROP', v_source_schemaname, v_source_tablename);
122126
ELSE
123127
RAISE DEBUG 'No default table found when partition_data_id() was called';

src/postgres/third-party-extensions/pg_partman/sql/functions/run_maintenance.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,12 @@ LOOP
172172
WHERE n.nspname = v_parent_schema
173173
AND c.relname = v_default_tablename;
174174

175+
-- YB: TODO(#3109): Disable skip after transactional DDL support.
176+
IF v_is_default = 'DEFAULT' THEN
177+
RAISE NOTICE 'Skip run maintenace job for table % as it has default table attached', v_row.parent_table;
178+
CONTINUE;
179+
END IF;
180+
175181
IF v_is_default != 'DEFAULT' THEN
176182
v_default_tablename := v_parent_tablename;
177183
END IF;

src/postgres/third-party-extensions/pg_partman/test/test_native/test_nonsuperuser/yb_pg_test-time-hourly-nonsuperuser-part2.sql

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
-- BEGIN; YB: Transactional DDL not supported
1111
SELECT set_config('search_path','partman, public',false);
1212

13-
SELECT plan(30); -- YB: decreased number of tests
13+
SELECT plan(28); -- YB: decreased number of tests
1414

1515
CREATE TABLE partman_test.time_taptest_table (col1 serial, col2 text, col3 timestamp NOT NULL DEFAULT now()) PARTITION BY RANGE (col3);
1616
CREATE TABLE partman_test.time_taptest_undo (LIKE partman_test.time_taptest_table);
@@ -57,7 +57,9 @@ SELECT results_eq('SELECT count(*)::int FROM partman_test.time_taptest_table_p'|
5757
INSERT INTO partman_test.time_taptest_table (col1, col3) VALUES (generate_series(11,20), CURRENT_TIMESTAMP + '1 hour'::interval);
5858
INSERT INTO partman_test.time_taptest_table (col1, col3) VALUES (generate_series(21,25), CURRENT_TIMESTAMP + '2 hours'::interval);
5959

60-
SELECT is_empty('SELECT * FROM partman_test.time_taptest_table_default', 'Check that default table has had no data inserted to it');
60+
-- YB: default partition creation is disabled.
61+
-- TODO(#3109): Re-enable it after transactional DDL support.
62+
-- SELECT is_empty('SELECT * FROM partman_test.time_taptest_table_default', 'Check that default table has had no data inserted to it'); --YB: Disabled default partition
6163
SELECT results_eq('SELECT count(*)::int FROM partman_test.time_taptest_table', ARRAY[25], 'Check count from time_taptest_table');
6264
SELECT results_eq('SELECT count(*)::int FROM partman_test.time_taptest_table_p'||to_char(date_trunc('hour', CURRENT_TIMESTAMP)+'1 hour'::interval, 'YYYY_MM_DD_HH24MI'),
6365
ARRAY[10], 'Check count from time_taptest_table_p'||to_char(date_trunc('hour', CURRENT_TIMESTAMP)+'1 hour'::interval, 'YYYY_MM_DD_HH24MI'));
@@ -91,8 +93,10 @@ SELECT hasnt_table('partman_test', 'time_taptest_table_p'||to_char(date_trunc('h
9193
SELECT col_is_pk('partman_test', 'time_taptest_table_p'||to_char(date_trunc('hour', CURRENT_TIMESTAMP)+'8 hours'::interval, 'YYYY_MM_DD_HH24MI'), ARRAY['col1'],
9294
'Check for primary key in time_taptest_table_p'||to_char(date_trunc('hour', CURRENT_TIMESTAMP)+'8 hours'::interval, 'YYYY_MM_DD_HH24MI'));
9395

94-
INSERT INTO partman_test.time_taptest_table (col1, col3) VALUES (generate_series(200,210), CURRENT_TIMESTAMP + '20 hours'::interval);
95-
SELECT results_eq('SELECT count(*)::int FROM ONLY partman_test.time_taptest_table_default', ARRAY[11], 'Check that data outside trigger scope goes to default');
96+
-- YB: default partition creation is disabled
97+
-- TODO(#3109): Re-enable it after transactional DDL support.
98+
-- INSERT INTO partman_test.time_taptest_table (col1, col3) VALUES (generate_series(200,210), CURRENT_TIMESTAMP + '20 hours'::interval);
99+
-- SELECT results_eq('SELECT count(*)::int FROM ONLY partman_test.time_taptest_table_default', ARRAY[11], 'Check that data outside trigger scope goes to default');
96100

97101
/* YB: undo_partition not supported
98102
-- Keep tables after undoing

src/postgres/third-party-extensions/pg_partman/test/test_native/yb_pg_test-id-native.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
-- BEGIN; YB: Transactional DDL not supported
1111
SELECT set_config('search_path','partman, public',false);
1212

13-
SELECT plan(98); -- YB: decreased number of tests
13+
SELECT plan(99); -- YB: decreased number of tests
1414
CREATE SCHEMA partman_test;
1515
CREATE SCHEMA partman_retention_test;
1616
CREATE ROLE partman_basic;
@@ -62,7 +62,7 @@ SELECT has_table('partman_test', 'id_taptest_table_p3000000010', 'Check id_tapte
6262
SELECT has_table('partman_test', 'id_taptest_table_p3000000020', 'Check id_taptest_table_p3000000020 exists');
6363
SELECT has_table('partman_test', 'id_taptest_table_p3000000030', 'Check id_taptest_table_p3000000030 exists');
6464
SELECT has_table('partman_test', 'id_taptest_table_p3000000040', 'Check id_taptest_table_p3000000040 exists');
65-
--SELECT has_table('partman_test', 'id_taptest_table_default', 'Check id_taptest_table_default exists');
65+
SELECT hasnt_table('partman_test', 'id_taptest_table_default', 'Check id_taptest_table_default exists'); -- YB: disable default partition creation
6666
SELECT hasnt_table('partman_test', 'id_taptest_table_p3000000050', 'Check id_taptest_table_p3000000050 doesn''t exists yet');
6767
SELECT col_is_pk('partman_test', 'id_taptest_table_p3000000000', ARRAY['col1'], 'Check for primary key in id_taptest_table_p3000000000');
6868
SELECT col_is_pk('partman_test', 'id_taptest_table_p3000000010', ARRAY['col1'], 'Check for primary key in id_taptest_table_p3000000010');

src/postgres/third-party-extensions/pg_partman/test/test_native/yb_pg_test-time-daily-native.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ SELECT is_empty('SELECT * FROM ONLY partman_test.time_taptest_table', 'Check tha
168168
SELECT results_eq('SELECT count(*)::int FROM partman_test.time_taptest_table', ARRAY[10], 'Check count from parent table');
169169
SELECT results_eq('SELECT count(*)::int FROM partman_test.time_taptest_table_p'||to_char(CURRENT_TIMESTAMP, 'YYYY_MM_DD'),
170170
ARRAY[10], 'Check count from time_taptest_table_p'||to_char(CURRENT_TIMESTAMP, 'YYYY_MM_DD'));
171-
SELECT results_eq('SELECT count(*)::int FROM pg_catalog.pg_publication_tables WHERE pubname = ''partman_test_publication''', ARRAY[10], 'Check that all child tables were added to publication. This test will fail in PG10 since default tables are not supported.');
171+
SELECT results_eq('SELECT count(*)::int FROM pg_catalog.pg_publication_tables WHERE pubname = ''partman_test_publication''', ARRAY[9], 'Check that all child tables were added to publication. This test will fail in PG10 since default tables are not supported.');
172172

173173
REVOKE INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER ON partman_test.time_taptest_table FROM partman_revoke;
174174
INSERT INTO partman_test.time_taptest_table (col1, col3) VALUES (generate_series(11,20), CURRENT_TIMESTAMP + '1 day'::interval);
@@ -256,7 +256,7 @@ SELECT col_is_fk('partman_test', 'time_taptest_table_p'||to_char(CURRENT_TIMESTA
256256
SELECT is_empty('SELECT * FROM ONLY partman_test.time_taptest_table', 'Check that parent table has had no data inserted to it');
257257
SELECT results_eq('SELECT count(*)::int FROM partman_test.time_taptest_table_p'||to_char(CURRENT_TIMESTAMP+'5 days'::interval, 'YYYY_MM_DD'),
258258
ARRAY[22], 'Check count from time_taptest_table_p'||to_char(CURRENT_TIMESTAMP+'5 days'::interval, 'YYYY_MM_DD'));
259-
SELECT results_eq('SELECT count(*)::int FROM pg_catalog.pg_publication_tables WHERE pubname = ''partman_test_publication''', ARRAY[16], 'Check that all child tables were added to publication. This test will fail in PG10 since default tables are not supported.');
259+
SELECT results_eq('SELECT count(*)::int FROM pg_catalog.pg_publication_tables WHERE pubname = ''partman_test_publication''', ARRAY[15], 'Check that all child tables were added to publication. This test will fail in PG10 since default tables are not supported.');
260260

261261
SELECT table_privs_are('partman_test', 'time_taptest_table_p'||to_char(CURRENT_TIMESTAMP, 'YYYY_MM_DD'), 'partman_basic', ARRAY['SELECT','INSERT','UPDATE'],
262262
'Check partman_basic privileges of time_taptest_table_p'||to_char(CURRENT_TIMESTAMP, 'YYYY_MM_DD'));
@@ -303,7 +303,7 @@ SELECT is_empty('SELECT * FROM ONLY partman_test.time_taptest_table', 'Check tha
303303
SELECT results_eq('SELECT count(*)::int FROM partman_test.time_taptest_table', ARRAY[148], 'Check count from parent table');
304304
SELECT results_eq('SELECT count(*)::int FROM partman_test.time_taptest_table_p'||to_char(CURRENT_TIMESTAMP+'6 days'::interval, 'YYYY_MM_DD'),
305305
ARRAY[28], 'Check count from time_taptest_table_p'||to_char(CURRENT_TIMESTAMP+'6 days'::interval, 'YYYY_MM_DD'));
306-
SELECT results_eq('SELECT count(*)::int FROM pg_catalog.pg_publication_tables WHERE pubname = ''partman_test_publication''', ARRAY[18], 'Check that all child tables were added to publication. This test will fail in PG10 since default tables are not supported.');
306+
SELECT results_eq('SELECT count(*)::int FROM pg_catalog.pg_publication_tables WHERE pubname = ''partman_test_publication''', ARRAY[17], 'Check that all child tables were added to publication. This test will fail in PG10 since default tables are not supported.');
307307

308308
SELECT has_table('partman_test', 'time_taptest_table_p'||to_char(CURRENT_TIMESTAMP+'11 days'::interval, 'YYYY_MM_DD'),
309309
'Check time_taptest_table_p'||to_char(CURRENT_TIMESTAMP+'11 days'::interval, 'YYYY_MM_DD')||' exists');

src/postgres/third-party-extensions/pg_partman/test/test_procedure/yb_pg_test-id-procedure-source-table-part1.sql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ CREATE TABLE partman_test.template_id_taptest_table (LIKE partman_test.id_taptes
3333

3434
SELECT create_parent('partman_test.id_taptest_table', 'col1', 'native', '10000', p_jobmon := false, p_template_table := 'partman_test.template_id_taptest_table');
3535

36-
SELECT has_table('partman_test', 'id_taptest_table_default', 'Check id_taptest_table_default exists');
36+
-- YB: default partition creation is disabled
37+
-- TODO(#3109): Re-enable it after transactional DDL support.
38+
SELECT hasnt_table('partman_test', 'id_taptest_table_default', 'Check id_taptest_table_default doesn''t exists');
3739
SELECT has_table('partman_test', 'id_taptest_table_p0', 'Check id_taptest_table_p0 exists');
3840
SELECT has_table('partman_test', 'id_taptest_table_p10000', 'Check id_taptest_table_p10000 exists');
3941
SELECT has_table('partman_test', 'id_taptest_table_p20000', 'Check id_taptest_table_p20000 exists');

src/postgres/third-party-extensions/pg_partman/test/test_procedure/yb_pg_test-id-procedure-source-table-part3.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
SELECT set_config('search_path','partman, public',false);
44

5-
SELECT plan(7);
5+
SELECT plan(5);
66

77
-- YB: reduced number of rows by factor of 10 to prevent test timeout
88
SELECT has_table('partman_test', 'id_taptest_table_p110000', 'Check id_taptest_table_p110000 exists');
@@ -11,11 +11,14 @@ SELECT has_table('partman_test', 'id_taptest_table_p130000', 'Check id_taptest_t
1111
SELECT has_table('partman_test', 'id_taptest_table_p140000', 'Check id_taptest_table_p140000 exists');
1212
SELECT hasnt_table('partman_test', 'id_taptest_table_p150000', 'Check id_taptest_table_p150000 doesn''t exists yet');
1313

14+
/* YB: default partition creation is disabled.
15+
* TODO(#3109): Re-enable it after transactional DDL support.
1416
-- Test default partition
1517
INSERT INTO partman_test.id_taptest_table (col1) VALUES (generate_series(200000, 200009));
1618
1719
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table WHERE col1 > 100000', ARRAY[10], 'Check count from id_taptest_table for out of band data');
1820
SELECT results_eq('SELECT count(*)::int FROM partman_test.id_taptest_table_default', ARRAY[10], 'Check count from id_taptest_table_default');
21+
*/ -- YB
1922

2023
SELECT diag('!!! In separate psql terminal, please run the following (adjusting schema if needed): "CALL partman.undo_partition_proc(''partman_test.id_taptest_table'', p_target_table := ''partman_test.id_taptest_table_target'', p_keep_table := false);".');
2124
SELECT diag('!!! After that, run part4 of this script to check result and cleanup tests !!!');

0 commit comments

Comments
 (0)