test.diff
application/octet-stream
Filename: test.diff
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| contrib/amcheck/t/004_rc.pl | 67 | 0 |
diff --git a/contrib/amcheck/t/004_rc.pl b/contrib/amcheck/t/004_rc.pl
new file mode 100644
index 0000000000..9f5509c813
--- /dev/null
+++ b/contrib/amcheck/t/004_rc.pl
@@ -0,0 +1,67 @@
+
+# Copyright (c) 2021, PostgreSQL Global Development Group
+
+# Test REINDEX CONCURRENTLY with concurrent modifications
+use strict;
+use warnings;
+
+use Config;
+use PostgresNode;
+use TestLib;
+
+use Test::More tests => 3;
+
+my ($node, $result);
+
+#
+# Test set-up
+#
+$node = get_new_node('RC_test');
+$node->init;
+$node->append_conf('postgresql.conf',
+ 'lock_timeout = ' . (1000 * $TestLib::timeout_default));
+$node->start;
+$node->safe_psql('postgres', q(CREATE EXTENSION amcheck));
+$node->safe_psql('postgres', q(CREATE TABLE tbl(i int primary key,
+ c1 money default 0,c2 money default 0,
+ c3 money default 0, updated_at timestamp)));
+$node->safe_psql('postgres', q(CREATE INDEX idx ON tbl(i)));
+
+#
+# Stress RC with pgbench.
+#
+# pgbench might try to launch more than one instance of the RC
+# transaction concurrently. That would deadlock, so use an advisory
+# lock to ensure only one RC runs at a time.
+#
+$node->pgbench(
+ '--no-vacuum --client=5 --time=20',
+ 0,
+ [qr{actually processed}],
+ [qr{^$}],
+ 'concurrent INSERTs, UPDATES and RC',
+ {
+ '002_pgbench_concurrent_transaction_inserts' => q(
+ BEGIN;
+ INSERT INTO tbl VALUES(random()*10000,0,0,0,now())
+ on conflict(i) do update set updated_at = now();
+ COMMIT;
+ ),
+ '002_pgbench_concurrent_transaction_updates' => q(
+ BEGIN;
+ INSERT INTO tbl VALUES(random()*1000,0,0,0,now())
+ on conflict(i) do update set updated_at = now();
+ COMMIT;
+ ),
+ '002_pgbench_concurrent_cic' => q(
+ SELECT pg_try_advisory_lock(42)::integer AS gotlock \gset
+ \if :gotlock
+ REINDEX INDEX CONCURRENTLY idx;
+ SELECT bt_index_check('idx',true);
+ SELECT pg_advisory_unlock(42);
+ \endif
+ )
+ });
+
+$node->stop;
+done_testing();