From db0835a7e080b8552a08f583402f2d1c5472bc28 Mon Sep 17 00:00:00 2001 From: Shihao Zhong Date: Sat, 12 Sep 2026 08:46:49 -0400 Subject: [PATCH v3 2/2] Add isolation test for timeouts in the REPACK decoding worker The test checks both directions: a lock_timeout set on the table owner role does not reach the worker, and one set in the REPACK session does. --- src/test/modules/injection_points/Makefile | 1 + .../expected/repack_timeout.out | 18 ++++++++ src/test/modules/injection_points/meson.build | 1 + .../specs/repack_timeout.spec | 42 +++++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 src/test/modules/injection_points/expected/repack_timeout.out create mode 100644 src/test/modules/injection_points/specs/repack_timeout.spec diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile index 408a35c3c21..e9745d3f275 100644 --- a/src/test/modules/injection_points/Makefile +++ b/src/test/modules/injection_points/Makefile @@ -21,6 +21,7 @@ ISOLATION = basic \ repack_decode \ repack_temporal \ repack_temporal_multirange \ + repack_timeout \ repack_toast \ ri_fastpath_reindex \ ri_fastpath_snapshot \ diff --git a/src/test/modules/injection_points/expected/repack_timeout.out b/src/test/modules/injection_points/expected/repack_timeout.out new file mode 100644 index 00000000000..6a4d3d0a915 --- /dev/null +++ b/src/test/modules/injection_points/expected/repack_timeout.out @@ -0,0 +1,18 @@ +Parsed test spec with 2 sessions + +starting permutation: s1_begin s2_repack s1_sleep s1_commit s1_begin s2_lto s2_repack +step s1_begin: BEGIN; INSERT INTO repack_timeout_other VALUES (1); +step s2_repack: REPACK (CONCURRENTLY) repack_timeout_tab; +step s1_sleep: SELECT pg_sleep(0.5); +pg_sleep +-------- + +(1 row) + +step s1_commit: COMMIT; +step s2_repack: <... completed> +step s1_begin: BEGIN; INSERT INTO repack_timeout_other VALUES (1); +step s2_lto: SET lock_timeout = '100ms'; +step s2_repack: REPACK (CONCURRENTLY) repack_timeout_tab; +step s2_repack: <... completed> +ERROR: canceling statement due to lock timeout diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build index a7b40e084f6..1b530a9cfc6 100644 --- a/src/test/modules/injection_points/meson.build +++ b/src/test/modules/injection_points/meson.build @@ -50,6 +50,7 @@ tests += { 'repack_decode', 'repack_temporal', 'repack_temporal_multirange', + 'repack_timeout', 'repack_toast', 'ri_fastpath_reindex', 'ri_fastpath_snapshot', diff --git a/src/test/modules/injection_points/specs/repack_timeout.spec b/src/test/modules/injection_points/specs/repack_timeout.spec new file mode 100644 index 00000000000..2842be0ad0a --- /dev/null +++ b/src/test/modules/injection_points/specs/repack_timeout.spec @@ -0,0 +1,42 @@ +# Timeouts in the REPACK (CONCURRENTLY) decoding worker. +# +# The worker connects as the table owner in a new session, so the timeouts +# set for that role (or for the database) would apply to it while it waits +# for older transactions to finish. Instead, the worker adopts the values in +# effect in the session running REPACK, so that the user can control them +# with SET. + +setup +{ + CREATE ROLE regress_repack_timeout; + ALTER ROLE regress_repack_timeout SET lock_timeout = '100ms'; + + CREATE TABLE repack_timeout_tab (a int PRIMARY KEY); + INSERT INTO repack_timeout_tab VALUES (1), (2); + ALTER TABLE repack_timeout_tab OWNER TO regress_repack_timeout; + + CREATE TABLE repack_timeout_other (a int); +} + +teardown +{ + DROP TABLE repack_timeout_tab, repack_timeout_other; + DROP ROLE regress_repack_timeout; +} + +# Hold an XID that the decoding worker has to wait for. +session s1 +step s1_begin { BEGIN; INSERT INTO repack_timeout_other VALUES (1); } +# Keep the worker waiting for longer than the role's lock_timeout. +step s1_sleep { SELECT pg_sleep(0.5); } +step s1_commit { COMMIT; } +teardown { ABORT; } + +session s2 +step s2_lto { SET lock_timeout = '100ms'; } +step s2_repack { REPACK (CONCURRENTLY) repack_timeout_tab; } + +# The role-level lock_timeout does not reach the worker: REPACK waits until +# s1 finishes. With lock_timeout set in the REPACK session, the worker's +# wait is cancelled by that value. +permutation s1_begin s2_repack s1_sleep s1_commit s1_begin s2_lto s2_repack(*) -- 2.37.1 (Apple Git-137.1)