From 0d56ffa57803b5059bd40589f659840f80d29adc Mon Sep 17 00:00:00 2001
From: Sami Imseih <simseih@amazon.com>
Date: Fri, 27 Feb 2026 10:35:41 -0600
Subject: [PATCH v1 1/1] repro

---
 .../isolation/expected/multixact-aux-proc.out | 24 +++++++++++++++
 .../isolation/expected/multixact-prep-tx.out  | 30 +++++++++++++++++++
 src/test/isolation/isolation_schedule         |  1 +
 .../isolation/specs/multixact-aux-proc.spec   | 29 ++++++++++++++++++
 .../isolation/specs/multixact-prep-tx.spec    | 29 ++++++++++++++++++
 5 files changed, 113 insertions(+)
 create mode 100644 src/test/isolation/expected/multixact-aux-proc.out
 create mode 100644 src/test/isolation/expected/multixact-prep-tx.out
 create mode 100644 src/test/isolation/specs/multixact-aux-proc.spec
 create mode 100644 src/test/isolation/specs/multixact-prep-tx.spec

diff --git a/src/test/isolation/expected/multixact-aux-proc.out b/src/test/isolation/expected/multixact-aux-proc.out
new file mode 100644
index 00000000000..08bba739bc9
--- /dev/null
+++ b/src/test/isolation/expected/multixact-aux-proc.out
@@ -0,0 +1,24 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin_p1 s1_share_p1 s1_prep_p1 s1_begin_p2 s1_share_p2 s1_prep_p2 s2_lock_timeout s2_delete s2_rollback_prepared_p1 s2_rollback_prepared_p2
+step s1_begin_p1: BEGIN;
+step s1_share_p1: SELECT * FROM dont_delete WHERE id = 1 FOR SHARE;
+id|data     
+--+---------
+ 1|test data
+(1 row)
+
+step s1_prep_p1: PREPARE TRANSACTION 'p1';
+step s1_begin_p2: BEGIN;
+step s1_share_p2: SELECT * FROM dont_delete WHERE id = 1 FOR SHARE;
+id|data     
+--+---------
+ 1|test data
+(1 row)
+
+step s1_prep_p2: PREPARE TRANSACTION 'p2';
+step s2_lock_timeout: SET lock_timeout TO '2s';
+step s2_delete: DELETE FROM dont_delete WHERE id = 1;
+ERROR:  canceling statement due to lock timeout
+step s2_rollback_prepared_p1: ROLLBACK PREPARED 'p1';
+step s2_rollback_prepared_p2: ROLLBACK PREPARED 'p2';
diff --git a/src/test/isolation/expected/multixact-prep-tx.out b/src/test/isolation/expected/multixact-prep-tx.out
new file mode 100644
index 00000000000..68470cf33d9
--- /dev/null
+++ b/src/test/isolation/expected/multixact-prep-tx.out
@@ -0,0 +1,30 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s1_begin_p1 s1_share_p1 s1_prep_p1 s1_begin_p2 s1_share_p2 s1_prep_p2 s2_lock_timeout s2_delete s2_select s2_rollback_prepared_p1 s2_rollback_prepared_p2
+step s1_begin_p1: BEGIN;
+step s1_share_p1: SELECT * FROM block_delete WHERE id = 1 FOR SHARE;
+id|data     
+--+---------
+ 1|test data
+(1 row)
+
+step s1_prep_p1: PREPARE TRANSACTION 'p1';
+step s1_begin_p2: BEGIN;
+step s1_share_p2: SELECT * FROM block_delete WHERE id = 1 FOR SHARE;
+id|data     
+--+---------
+ 1|test data
+(1 row)
+
+step s1_prep_p2: PREPARE TRANSACTION 'p2';
+step s2_lock_timeout: SET lock_timeout TO '2s';
+step s2_delete: DELETE FROM block_delete WHERE id = 1;
+ERROR:  canceling statement due to lock timeout
+step s2_select: SELECT * FROM block_delete WHERE id = 1;
+id|data     
+--+---------
+ 1|test data
+(1 row)
+
+step s2_rollback_prepared_p1: ROLLBACK PREPARED 'p1';
+step s2_rollback_prepared_p2: ROLLBACK PREPARED 'p2';
diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule
index 4e466580cd4..ff7f93ea6ef 100644
--- a/src/test/isolation/isolation_schedule
+++ b/src/test/isolation/isolation_schedule
@@ -66,6 +66,7 @@ test: aborted-keyrevoke
 test: multixact-no-deadlock
 test: multixact-no-forget
 test: multixact-stats
+test: multixact-prep-tx
 test: lock-committed-update
 test: lock-committed-keyupdate
 test: update-locked-tuple
diff --git a/src/test/isolation/specs/multixact-aux-proc.spec b/src/test/isolation/specs/multixact-aux-proc.spec
new file mode 100644
index 00000000000..2cddf53d1d1
--- /dev/null
+++ b/src/test/isolation/specs/multixact-aux-proc.spec
@@ -0,0 +1,29 @@
+# Test that dummy processes for prepared transactions are properly accounted for in multixact tracking
+
+setup
+{
+    CREATE TABLE block_delete (id int PRIMARY KEY, data text);
+    INSERT INTO block_delete VALUES (1, 'test data');
+}
+
+teardown
+{
+    DROP TABLE block_delete;
+}
+
+session s1
+step s1_begin_p1 { BEGIN; }
+step s1_share_p1 { SELECT * FROM block_delete WHERE id = 1 FOR SHARE; }
+step s1_prep_p1 { PREPARE TRANSACTION 'p1'; }
+step s1_begin_p2 { BEGIN; }
+step s1_share_p2 { SELECT * FROM block_delete WHERE id = 1 FOR SHARE; }
+step s1_prep_p2 { PREPARE TRANSACTION 'p2'; }
+
+session s2
+step s2_lock_timeout { SET lock_timeout TO '2s'; }
+step s2_delete { DELETE FROM block_delete WHERE id = 1; }
+step s2_select { SELECT * FROM block_delete WHERE id = 1; }
+step s2_rollback_prepared_p1 { ROLLBACK PREPARED 'p1'; }
+step s2_rollback_prepared_p2 { ROLLBACK PREPARED 'p2'; }
+
+permutation s1_begin_p1 s1_share_p1 s1_prep_p1 s1_begin_p2 s1_share_p2 s1_prep_p2 s2_lock_timeout s2_delete s2_select s2_rollback_prepared_p1 s2_rollback_prepared_p2
diff --git a/src/test/isolation/specs/multixact-prep-tx.spec b/src/test/isolation/specs/multixact-prep-tx.spec
new file mode 100644
index 00000000000..2cddf53d1d1
--- /dev/null
+++ b/src/test/isolation/specs/multixact-prep-tx.spec
@@ -0,0 +1,29 @@
+# Test that dummy processes for prepared transactions are properly accounted for in multixact tracking
+
+setup
+{
+    CREATE TABLE block_delete (id int PRIMARY KEY, data text);
+    INSERT INTO block_delete VALUES (1, 'test data');
+}
+
+teardown
+{
+    DROP TABLE block_delete;
+}
+
+session s1
+step s1_begin_p1 { BEGIN; }
+step s1_share_p1 { SELECT * FROM block_delete WHERE id = 1 FOR SHARE; }
+step s1_prep_p1 { PREPARE TRANSACTION 'p1'; }
+step s1_begin_p2 { BEGIN; }
+step s1_share_p2 { SELECT * FROM block_delete WHERE id = 1 FOR SHARE; }
+step s1_prep_p2 { PREPARE TRANSACTION 'p2'; }
+
+session s2
+step s2_lock_timeout { SET lock_timeout TO '2s'; }
+step s2_delete { DELETE FROM block_delete WHERE id = 1; }
+step s2_select { SELECT * FROM block_delete WHERE id = 1; }
+step s2_rollback_prepared_p1 { ROLLBACK PREPARED 'p1'; }
+step s2_rollback_prepared_p2 { ROLLBACK PREPARED 'p2'; }
+
+permutation s1_begin_p1 s1_share_p1 s1_prep_p1 s1_begin_p2 s1_share_p2 s1_prep_p2 s2_lock_timeout s2_delete s2_select s2_rollback_prepared_p1 s2_rollback_prepared_p2
-- 
2.50.1 (Apple Git-155)

