From ef1fdbef72f8ac090f01b6d8432d6fb4f8971bee Mon Sep 17 00:00:00 2001 From: ChangAo Chen Date: Tue, 23 Jun 2026 13:04:11 +0800 Subject: [PATCH v3 2/2] Add test case for vacuum with a concurrent drop. --- src/backend/commands/vacuum.c | 2 + src/test/modules/injection_points/Makefile | 1 + .../expected/vacuum_concurrent_drop.out | 65 +++++++++++++++++++ src/test/modules/injection_points/meson.build | 1 + .../specs/vacuum_concurrent_drop.spec | 64 ++++++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 src/test/modules/injection_points/expected/vacuum_concurrent_drop.out create mode 100644 src/test/modules/injection_points/specs/vacuum_concurrent_drop.spec diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 2217188d86e..d895b31be6b 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -1069,6 +1069,8 @@ get_all_vacuum_rels(MemoryContext vac_context, int options) scan = table_beginscan_catalog(pgclass, 0, NULL); + INJECTION_POINT("vacuum-constructing-vacuumable-rels", NULL); + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) { Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple); diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile index c01d2fb095c..2fae0e01f15 100644 --- a/src/test/modules/injection_points/Makefile +++ b/src/test/modules/injection_points/Makefile @@ -18,6 +18,7 @@ ISOLATION = basic \ repack_temporal \ repack_temporal_multirange \ repack_toast \ + vacuum_concurrent_drop \ syscache-update-pruned \ heap_lock_update diff --git a/src/test/modules/injection_points/expected/vacuum_concurrent_drop.out b/src/test/modules/injection_points/expected/vacuum_concurrent_drop.out new file mode 100644 index 00000000000..c46b267a27f --- /dev/null +++ b/src/test/modules/injection_points/expected/vacuum_concurrent_drop.out @@ -0,0 +1,65 @@ +Parsed test spec with 2 sessions + +starting permutation: create1 setrole1 vacuum1 drop2 wakeup2 resetrole1 +step create1: + CREATE TABLE foo (id int); + +step setrole1: + SET ROLE regress_vacuum; + +step vacuum1: + VACUUM; + +step drop2: + DROP TABLE foo; + +step wakeup2: + SELECT injection_points_wakeup('vacuum-constructing-vacuumable-rels'); + +injection_points_wakeup +----------------------- + +(1 row) + +s1: WARNING: skipping vacuum of "foo" --- relation no longer exists +step vacuum1: <... completed> +step resetrole1: + RESET ROLE; + +injection_points_detach +----------------------- + +(1 row) + + +starting permutation: create1 setrole1 analyze1 drop2 wakeup2 resetrole1 +step create1: + CREATE TABLE foo (id int); + +step setrole1: + SET ROLE regress_vacuum; + +step analyze1: + ANALYZE; + +step drop2: + DROP TABLE foo; + +step wakeup2: + SELECT injection_points_wakeup('vacuum-constructing-vacuumable-rels'); + +injection_points_wakeup +----------------------- + +(1 row) + +s1: WARNING: skipping analyze of "foo" --- relation no longer exists +step analyze1: <... completed> +step resetrole1: + RESET ROLE; + +injection_points_detach +----------------------- + +(1 row) + diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build index 59dba1cb023..dbb1edf0bfe 100644 --- a/src/test/modules/injection_points/meson.build +++ b/src/test/modules/injection_points/meson.build @@ -49,6 +49,7 @@ tests += { 'repack_temporal', 'repack_temporal_multirange', 'repack_toast', + 'vacuum_concurrent_drop', 'syscache-update-pruned', 'heap_lock_update', ], diff --git a/src/test/modules/injection_points/specs/vacuum_concurrent_drop.spec b/src/test/modules/injection_points/specs/vacuum_concurrent_drop.spec new file mode 100644 index 00000000000..793a12762ae --- /dev/null +++ b/src/test/modules/injection_points/specs/vacuum_concurrent_drop.spec @@ -0,0 +1,64 @@ +# Test vacuum/analyze with a concurrent drop when constructing the list +# of vacuumable relations. The vacuum/analyze should not error out when +# a concurrent drop happens. + +setup +{ + CREATE EXTENSION injection_points; + CREATE ROLE regress_vacuum IN ROLE pg_maintain; +} +teardown +{ + DROP ROLE regress_vacuum; + DROP EXTENSION injection_points; +} + +session s1 +setup +{ + SELECT injection_points_set_local(); + SELECT injection_points_attach('vacuum-constructing-vacuumable-rels', 'wait'); + SET client_min_messages = WARNING; +} +step create1 +{ + CREATE TABLE foo (id int); +} +# Make sure that current user is not the owner of current database. +step setrole1 +{ + SET ROLE regress_vacuum; +} +step vacuum1 +{ + VACUUM; +} +step analyze1 +{ + ANALYZE; +} +step resetrole1 +{ + RESET ROLE; +} +teardown +{ + RESET client_min_messages; + SELECT injection_points_detach('vacuum-constructing-vacuumable-rels'); +} + +session s2 +step drop2 +{ + DROP TABLE foo; +} +step wakeup2 +{ + SELECT injection_points_wakeup('vacuum-constructing-vacuumable-rels'); +} + +# Test vacuum +permutation create1 setrole1 vacuum1 drop2 wakeup2 resetrole1 + +# Test analyze +permutation create1 setrole1 analyze1 drop2 wakeup2 resetrole1 -- 2.34.1