Skip to content

Commit d0651e7

Browse files
author
Andrey M. Borodin
committed
Add TAP test for REINDEX CONCURRENTLY with HOT updates
Existing amcheck TAP tests failed to find problem in HOT chains in bug 17485.
1 parent 916e829 commit d0651e7

1 file changed

Lines changed: 88 additions & 0 deletions

File tree

contrib/amcheck/t/004_rc.pl

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
# Copyright (c) 2022, PostgreSQL Global Development Group
3+
4+
# Test REINDEX CONCURRENTLY with concurrent modifications and HOT updates
5+
use strict;
6+
use warnings;
7+
8+
use Config;
9+
10+
use PostgreSQL::Test::Cluster;
11+
use PostgreSQL::Test::Utils;
12+
13+
use Test::More tests => 3;
14+
15+
my ($node, $result);
16+
17+
#
18+
# Test set-up
19+
#
20+
$node = PostgreSQL::Test::Cluster->new('RC_test');
21+
$node->init;
22+
$node->append_conf('postgresql.conf',
23+
'lock_timeout = ' . (1000 * $PostgreSQL::Test::Utils::timeout_default));
24+
$node->append_conf('postgresql.conf', 'fsync = off');
25+
$node->start;
26+
$node->safe_psql('postgres', q(CREATE EXTENSION amcheck));
27+
$node->safe_psql('postgres', q(CREATE TABLE tbl(i int primary key,
28+
c1 money default 0,c2 money default 0,
29+
c3 money default 0, updated_at timestamp)));
30+
$node->safe_psql('postgres', q(CREATE INDEX idx ON tbl(i)));
31+
32+
#
33+
# Stress RC with pgbench.
34+
#
35+
# pgbench might try to launch more than one instance of the RC
36+
# transaction concurrently. That would deadlock, so use an advisory
37+
# lock to ensure only one RC runs at a time.
38+
#
39+
$node->pgbench(
40+
'--no-vacuum --client=5 --transactions=1500',
41+
0,
42+
[qr{actually processed}],
43+
[qr{^$}],
44+
'concurrent INSERTs, UPDATES and RC',
45+
{
46+
'002_pgbench_concurrent_transaction_inserts' => q(
47+
BEGIN;
48+
INSERT INTO tbl VALUES(random()*10000,0,0,0,now())
49+
on conflict(i) do update set updated_at = now();
50+
INSERT INTO tbl VALUES(random()*10000,0,0,0,now())
51+
on conflict(i) do update set updated_at = now();
52+
INSERT INTO tbl VALUES(random()*10000,0,0,0,now())
53+
on conflict(i) do update set updated_at = now();
54+
INSERT INTO tbl VALUES(random()*10000,0,0,0,now())
55+
on conflict(i) do update set updated_at = now();
56+
SELECT pg_sleep(case when random()<0.05 then 0.01 else 0 end);
57+
INSERT INTO tbl VALUES(random()*10000,0,0,0,now())
58+
on conflict(i) do update set updated_at = now();
59+
COMMIT;
60+
),
61+
# Ensure some HOT updates happen
62+
'002_pgbench_concurrent_transaction_updates' => q(
63+
BEGIN;
64+
INSERT INTO tbl VALUES(random()*1000,0,0,0,now())
65+
on conflict(i) do update set updated_at = now();
66+
INSERT INTO tbl VALUES(random()*1000,0,0,0,now())
67+
on conflict(i) do update set updated_at = now();
68+
INSERT INTO tbl VALUES(random()*1000,0,0,0,now())
69+
on conflict(i) do update set updated_at = now();
70+
INSERT INTO tbl VALUES(random()*1000,0,0,0,now())
71+
on conflict(i) do update set updated_at = now();
72+
SELECT pg_sleep(case when random()<0.05 then 0.01 else 0 end);
73+
INSERT INTO tbl VALUES(random()*1000,0,0,0,now())
74+
on conflict(i) do update set updated_at = now();
75+
COMMIT;
76+
),
77+
'002_pgbench_concurrent_cic' => q(
78+
SELECT pg_try_advisory_lock(42)::integer AS gotlock \gset
79+
\if :gotlock
80+
REINDEX INDEX CONCURRENTLY idx;
81+
SELECT bt_index_check('idx',true);
82+
SELECT pg_advisory_unlock(42);
83+
\endif
84+
)
85+
});
86+
87+
$node->stop;
88+
done_testing();

0 commit comments

Comments
 (0)