diff --git a/contrib/test_decoding/expected/snapshot_build.out b/contrib/test_decoding/expected/snapshot_build.out index 0fcf20cce86..32e5cd1dd1d 100644 --- a/contrib/test_decoding/expected/snapshot_build.out +++ b/contrib/test_decoding/expected/snapshot_build.out @@ -31,3 +31,100 @@ COMMIT stop (1 row) + +starting permutation: s1_begin s1_insert s2_init s3_begin s3_insert s4_create_subxact s1_commit s4_begin s4_insert s3_commit s4_commit s2_get_changes +step s1_begin: BEGIN; +step s1_insert: INSERT INTO tbl1 VALUES (1); +step s2_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); +step s3_begin: BEGIN; +step s3_insert: INSERT INTO tbl1 VALUES (1); +step s4_create_subxact: BEGIN; SAVEPOINT a; CREATE TABLE tbl2 (val1 integer); RELEASE a; COMMIT; +step s1_commit: COMMIT; +step s4_begin: BEGIN; +step s4_insert: INSERT INTO tbl2 VALUES (1); +step s3_commit: COMMIT; +step s2_init: <... completed> +?column? +-------- +init +(1 row) + +step s4_commit: COMMIT; +step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0'); +data +------------------------------------------ +BEGIN +table public.tbl2: INSERT: val1[integer]:1 +COMMIT +(3 rows) + +?column? +-------- +stop +(1 row) + + +starting permutation: s1_begin s1_insert s2_init s3_begin s3_insert s4_prepare s4_commit_prepared s1_commit s4_begin s4_insert s3_commit s4_commit s2_get_changes +step s1_begin: BEGIN; +step s1_insert: INSERT INTO tbl1 VALUES (1); +step s2_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); +step s3_begin: BEGIN; +step s3_insert: INSERT INTO tbl1 VALUES (1); +step s4_prepare: BEGIN; CREATE TABLE tbl2 (val1 integer); PREPARE TRANSACTION 'snapshot_build'; +step s4_commit_prepared: COMMIT PREPARED 'snapshot_build'; +step s1_commit: COMMIT; +step s4_begin: BEGIN; +step s4_insert: INSERT INTO tbl2 VALUES (1); +step s3_commit: COMMIT; +step s2_init: <... completed> +?column? +-------- +init +(1 row) + +step s4_commit: COMMIT; +step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0'); +data +------------------------------------------ +BEGIN +table public.tbl2: INSERT: val1[integer]:1 +COMMIT +(3 rows) + +?column? +-------- +stop +(1 row) + + +starting permutation: s1_begin s1_insert s2_init s3_begin s3_insert s4_alter s1_commit s4_begin s4_insert3 s3_commit s4_commit s2_get_changes +step s1_begin: BEGIN; +step s1_insert: INSERT INTO tbl1 VALUES (1); +step s2_init: SELECT 'init' FROM pg_create_logical_replication_slot('isolation_slot', 'test_decoding'); +step s3_begin: BEGIN; +step s3_insert: INSERT INTO tbl1 VALUES (1); +step s4_alter: ALTER TABLE tbl3 ADD COLUMN val2 text, ADD COLUMN val3 bigint; +step s1_commit: COMMIT; +step s4_begin: BEGIN; +step s4_insert3: INSERT INTO tbl3 VALUES (1, 'two', 3); +step s3_commit: COMMIT; +step s2_init: <... completed> +?column? +-------- +init +(1 row) + +step s4_commit: COMMIT; +step s2_get_changes: SELECT data FROM pg_logical_slot_get_changes('isolation_slot', NULL, NULL, 'skip-empty-xacts', '1', 'include-xids', '0'); +data +-------------------------------------------------------------------------- +BEGIN +table public.tbl3: INSERT: val1[integer]:1 val2[text]:'two' val3[bigint]:3 +COMMIT +(3 rows) + +?column? +-------- +stop +(1 row) + diff --git a/contrib/test_decoding/specs/snapshot_build.spec b/contrib/test_decoding/specs/snapshot_build.spec index 334531dd219..65625e548ed 100644 --- a/contrib/test_decoding/specs/snapshot_build.spec +++ b/contrib/test_decoding/specs/snapshot_build.spec @@ -4,13 +4,16 @@ setup { DROP TABLE IF EXISTS tbl1; DROP TABLE IF EXISTS tbl2; + DROP TABLE IF EXISTS tbl3; CREATE TABLE tbl1 (val1 integer); + CREATE TABLE tbl3 (val1 integer); } teardown { DROP TABLE tbl1; - DROP TABLE tbl2; + DROP TABLE IF EXISTS tbl2; + DROP TABLE tbl3; SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot'); } @@ -34,8 +37,13 @@ step "s3_commit" { COMMIT; } session "s4" setup { SET synchronous_commit=on; } step "s4_create" { CREATE TABLE tbl2 (val1 integer); } +step "s4_create_subxact" { BEGIN; SAVEPOINT a; CREATE TABLE tbl2 (val1 integer); RELEASE a; COMMIT; } +step "s4_prepare" { BEGIN; CREATE TABLE tbl2 (val1 integer); PREPARE TRANSACTION 'snapshot_build'; } +step "s4_commit_prepared" { COMMIT PREPARED 'snapshot_build'; } +step "s4_alter" { ALTER TABLE tbl3 ADD COLUMN val2 text, ADD COLUMN val3 bigint; } step "s4_begin" { BEGIN; } step "s4_insert" { INSERT INTO tbl2 VALUES (1); } +step "s4_insert3" { INSERT INTO tbl3 VALUES (1, 'two', 3); } step "s4_commit" { COMMIT; } # T1: s1_begin -> s1_insert -> BUILDING_SNAPSHOT -> s1_commit -> FULL_SNAPSHOT @@ -44,3 +52,13 @@ step "s4_commit" { COMMIT; } # T4: FULL_SNAPSHOT -> s4_begin -> s4_insert -> CONSISTENT -> s4_commit # The snapshot must track T3 or the replay of T4 will fail because its snapshot cannot see tbl2 permutation "s1_begin" "s1_insert" "s2_init" "s3_begin" "s3_insert" "s4_create" "s1_commit" "s4_begin" "s4_insert" "s3_commit" "s4_commit" "s2_get_changes" + +# The same, with the catalog change made in a subtransaction. +permutation "s1_begin" "s1_insert" "s2_init" "s3_begin" "s3_insert" "s4_create_subxact" "s1_commit" "s4_begin" "s4_insert" "s3_commit" "s4_commit" "s2_get_changes" + +# The same, with the catalog change committed by COMMIT PREPARED. +permutation "s1_begin" "s1_insert" "s2_init" "s3_begin" "s3_insert" "s4_prepare" "s4_commit_prepared" "s1_commit" "s4_begin" "s4_insert" "s3_commit" "s4_commit" "s2_get_changes" + +# An ALTER TABLE instead: without tracking T3, the insert is decoded with the +# old tuple descriptor and the new columns are silently dropped. +permutation "s1_begin" "s1_insert" "s2_init" "s3_begin" "s3_insert" "s4_alter" "s1_commit" "s4_begin" "s4_insert3" "s3_commit" "s4_commit" "s2_get_changes"