mirror of https://github.com/postgres/postgres
In a cluster having used CREATE INDEX CONCURRENTLY while having enabled prepared transactions, queries that use the resulting index can silently fail to find rows. Fix this for future CREATE INDEX CONCURRENTLY by making it wait for prepared transactions like it waits for ordinary transactions. This expands the VirtualTransactionId structure domain to admit prepared transactions. It may be necessary to reindex to recover from past occurrences. Back-patch to 9.5 (all supported versions). Andrey Borodin, reviewed (in earlier versions) by Tom Lane and Michael Paquier. Discussion: https://postgr.es/m/2E712143-97F7-4890-B470-4A35142ABC82@yandex-team.rupull/61/head
parent
f77717b298
commit
8a54e12a38
@ -0,0 +1,18 @@ |
||||
Parsed test spec with 2 sessions |
||||
|
||||
starting permutation: w1 p1 cic2 c1 r2 |
||||
step w1: BEGIN; INSERT INTO cic_test VALUES (1); |
||||
step p1: PREPARE TRANSACTION 's1'; |
||||
step cic2: |
||||
CREATE INDEX CONCURRENTLY on cic_test(a); |
||||
|
||||
ERROR: canceling statement due to lock timeout |
||||
step c1: COMMIT PREPARED 's1'; |
||||
step r2: |
||||
SET enable_seqscan to off; |
||||
SET enable_bitmapscan to off; |
||||
SELECT * FROM cic_test WHERE a = 1; |
||||
|
||||
a |
||||
|
||||
1 |
@ -0,0 +1,37 @@ |
||||
# This test verifies that CREATE INDEX CONCURRENTLY interacts with prepared |
||||
# transactions correctly. |
||||
setup |
||||
{ |
||||
CREATE TABLE cic_test (a int); |
||||
} |
||||
|
||||
teardown |
||||
{ |
||||
DROP TABLE cic_test; |
||||
} |
||||
|
||||
|
||||
# Sessions for CREATE INDEX CONCURRENTLY test |
||||
session "s1" |
||||
step "w1" { BEGIN; INSERT INTO cic_test VALUES (1); } |
||||
step "p1" { PREPARE TRANSACTION 's1'; } |
||||
step "c1" { COMMIT PREPARED 's1'; } |
||||
|
||||
session "s2" |
||||
# The isolation tester never recognizes that a lock of s1 blocks s2, because a |
||||
# prepared transaction's locks have no pid associated. While there's a slight |
||||
# chance of timeout while waiting for an autovacuum-held lock, that wouldn't |
||||
# change the output. Hence, no timeout is too short. |
||||
setup { SET lock_timeout = 10; } |
||||
step "cic2" |
||||
{ |
||||
CREATE INDEX CONCURRENTLY on cic_test(a); |
||||
} |
||||
step "r2" |
||||
{ |
||||
SET enable_seqscan to off; |
||||
SET enable_bitmapscan to off; |
||||
SELECT * FROM cic_test WHERE a = 1; |
||||
} |
||||
|
||||
permutation "w1" "p1" "cic2" "c1" "r2" |
Loading…
Reference in new issue