From 2e2a200f2a02b0b10f931c5c9829a5518ea00bfb Mon Sep 17 00:00:00 2001 From: Zhijie Hou Date: Mon, 19 Oct 2026 17:10:24 +0800 Subject: [PATCH 2/2] Top-up test cases for snapshot_build isolation test. Author: Zhijie Hou --- .../test_decoding/expected/snapshot_build.out | 73 ++++++++++++++++++- .../test_decoding/specs/snapshot_build.spec | 48 ++++++++---- 2 files changed, 104 insertions(+), 17 deletions(-) diff --git a/contrib/test_decoding/expected/snapshot_build.out b/contrib/test_decoding/expected/snapshot_build.out index 0fcf20cce86..e002373f191 100644 --- a/contrib/test_decoding/expected/snapshot_build.out +++ b/contrib/test_decoding/expected/snapshot_build.out @@ -1,6 +1,6 @@ Parsed test spec with 4 sessions -starting 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 +starting permutation: s1_begin s1_insert s2_init s3_begin s3_insert s4_create s1_commit s1_begin s1_insert2 s3_commit s1_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'); @@ -8,8 +8,8 @@ step s3_begin: BEGIN; step s3_insert: INSERT INTO tbl1 VALUES (1); step s4_create: CREATE TABLE tbl2 (val1 integer); step s1_commit: COMMIT; -step s4_begin: BEGIN; -step s4_insert: INSERT INTO tbl2 VALUES (1); +step s1_begin: BEGIN; +step s1_insert2: INSERT INTO tbl2 VALUES (1); step s3_commit: COMMIT; step s2_init: <... completed> ?column? @@ -17,7 +17,7 @@ step s2_init: <... completed> init (1 row) -step s4_commit: COMMIT; +step s1_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 ------------------------------------------ @@ -31,3 +31,68 @@ COMMIT stop (1 row) + +starting permutation: s1_begin s1_insert s2_init s3_begin s3_insert s1_subxact_create s1_commit s1_begin s1_insert2 s3_commit s1_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 s1_subxact_create: SAVEPOINT sp1; CREATE TABLE tbl2 (val1 integer); +step s1_commit: COMMIT; +step s1_begin: BEGIN; +step s1_insert2: INSERT INTO tbl2 VALUES (1); +step s3_commit: COMMIT; +step s2_init: <... completed> +?column? +-------- +init +(1 row) + +step s1_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_alter_type s1_commit s1_begin s1_copy_comp s3_commit s1_insert_comp s1_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_alter_type: ALTER TYPE comp_type DROP ATTRIBUTE b; +step s1_commit: COMMIT; +step s1_begin: BEGIN; +step s1_copy_comp: INSERT INTO tbl_comp SELECT * FROM tbl_comp; +step s3_commit: COMMIT; +step s2_init: <... completed> +?column? +-------- +init +(1 row) + +step s1_insert_comp: INSERT INTO tbl_comp VALUES (ROW(10)); +step s1_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.tbl_comp: INSERT: val[comp_type]:'(1,2)' +table public.tbl_comp: INSERT: val[comp_type]:'(10)' +COMMIT +(4 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..4751391de43 100644 --- a/contrib/test_decoding/specs/snapshot_build.spec +++ b/contrib/test_decoding/specs/snapshot_build.spec @@ -1,16 +1,27 @@ -# Test snapshot build correctly, it must track committed transactions during BUILDING_SNAPSHOT +# Test tracking of catalog-modifying transactions in BUILDING_SNAPSHOT state. +# +# In each permutation, s1 and s3 hold transactions open so that "s2_init" +# transitions from BUILDING_SNAPSHOT (until "s1_commit") to FULL_SNAPSHOT +# (until "s3_commit") with xmin held back at s3's XID. setup { DROP TABLE IF EXISTS tbl1; DROP TABLE IF EXISTS tbl2; + DROP TABLE IF EXISTS tbl_comp; + DROP TYPE IF EXISTS comp_type; CREATE TABLE tbl1 (val1 integer); + CREATE TYPE comp_type AS (a integer, b integer); + CREATE TABLE tbl_comp (val comp_type); + INSERT INTO tbl_comp VALUES (ROW(1, 2)); } teardown { - DROP TABLE tbl1; - DROP TABLE tbl2; + DROP TABLE IF EXISTS tbl1; + DROP TABLE IF EXISTS tbl2; + DROP TABLE IF EXISTS tbl_comp; + DROP TYPE IF EXISTS comp_type; SELECT 'stop' FROM pg_drop_replication_slot('isolation_slot'); } @@ -18,6 +29,10 @@ session "s1" setup { SET synchronous_commit=on; } step "s1_begin" { BEGIN; } step "s1_insert" { INSERT INTO tbl1 VALUES (1); } +step "s1_insert2" { INSERT INTO tbl2 VALUES (1); } +step "s1_subxact_create" { SAVEPOINT sp1; CREATE TABLE tbl2 (val1 integer); } +step "s1_copy_comp" { INSERT INTO tbl_comp SELECT * FROM tbl_comp; } +step "s1_insert_comp" { INSERT INTO tbl_comp VALUES (ROW(10)); } step "s1_commit" { COMMIT; } session "s2" @@ -29,18 +44,25 @@ session "s3" setup { SET synchronous_commit=on; } step "s3_begin" { BEGIN; } step "s3_insert" { INSERT INTO tbl1 VALUES (1); } +step "s3_alter_type" { ALTER TYPE comp_type DROP ATTRIBUTE b; } step "s3_commit" { COMMIT; } session "s4" setup { SET synchronous_commit=on; } step "s4_create" { CREATE TABLE tbl2 (val1 integer); } -step "s4_begin" { BEGIN; } -step "s4_insert" { INSERT INTO tbl2 VALUES (1); } -step "s4_commit" { COMMIT; } - -# T1: s1_begin -> s1_insert -> BUILDING_SNAPSHOT -> s1_commit -> FULL_SNAPSHOT -# T2: BUILDING_SNAPSHOT -> s3_begin -> s3_insert -> FULL_SNAPSHOT -> s3_commit -> CONSISTENT -# T3: BUILDING_SNAPSHOT -> s4_create -> FULL_SNAPSHOT -# 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" + +# Verify that a catalog-modifying transaction ("s4_create") committed in +# BUILDING_SNAPSHOT is visible to a transaction ("s1_insert2") started in +# FULL_SNAPSHOT. +permutation "s1_begin" "s1_insert" "s2_init" "s3_begin" "s3_insert" "s4_create" "s1_commit" "s1_begin" "s1_insert2" "s3_commit" "s1_commit" "s2_get_changes" + +# Same as above, except the catalog change ("s1_subxact_create") is made in +# BUILDING_SNAPSHOT by a subtransaction whose top-level transaction started +# before "s2_init". +permutation "s1_begin" "s1_insert" "s2_init" "s3_begin" "s3_insert" "s1_subxact_create" "s1_commit" "s1_begin" "s1_insert2" "s3_commit" "s1_commit" "s2_get_changes" + +# Verify that invalidations from DDL ("s3_alter_type") executed in +# BUILDING_SNAPSHOT are accumulated and distributed when the transaction +# commits in FULL_SNAPSHOT ("s3_commit"), so that concurrent transactions see +# the updated type definition. +permutation "s1_begin" "s1_insert" "s2_init" "s3_begin" "s3_alter_type" "s1_commit" "s1_begin" "s1_copy_comp" "s3_commit" "s1_insert_comp" "s1_commit" "s2_get_changes" -- 2.50.1 (Apple Git-155)