diff options
author | Noah Misch <noah@leadboat.com> | 2021-01-30 00:00:27 -0800 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2021-01-30 00:00:27 -0800 |
commit | 8a54e12a38d1545d249f1402f66c8cde2837d97c (patch) | |
tree | d6b155a68f9e3dc21f1061106320c620eeaeb6ed /src/include/storage | |
parent | f77717b2985aa529a185e6988de26b885ca10ddb (diff) | |
download | postgresql-8a54e12a38d1545d249f1402f66c8cde2837d97c.tar.gz postgresql-8a54e12a38d1545d249f1402f66c8cde2837d97c.zip |
Fix CREATE INDEX CONCURRENTLY for simultaneous prepared transactions.
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.ru
Diffstat (limited to 'src/include/storage')
-rw-r--r-- | src/include/storage/lock.h | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 2e6ef174e9a..68a3487d49f 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -46,10 +46,10 @@ extern bool Debug_deadlocks; /* * Top-level transactions are identified by VirtualTransactionIDs comprising - * the BackendId of the backend running the xact, plus a locally-assigned - * LocalTransactionId. These are guaranteed unique over the short term, - * but will be reused after a database restart; hence they should never - * be stored on disk. + * PGPROC fields backendId and lxid. For prepared transactions, the + * LocalTransactionId is an ordinary XID. These are guaranteed unique over + * the short term, but will be reused after a database restart or XID + * wraparound; hence they should never be stored on disk. * * Note that struct VirtualTransactionId can not be assumed to be atomically * assignable as a whole. However, type LocalTransactionId is assumed to @@ -61,15 +61,16 @@ extern bool Debug_deadlocks; */ typedef struct { - BackendId backendId; /* determined at backend startup */ - LocalTransactionId localTransactionId; /* backend-local transaction id */ + BackendId backendId; /* backendId from PGPROC */ + LocalTransactionId localTransactionId; /* lxid from PGPROC */ } VirtualTransactionId; #define InvalidLocalTransactionId 0 #define LocalTransactionIdIsValid(lxid) ((lxid) != InvalidLocalTransactionId) #define VirtualTransactionIdIsValid(vxid) \ - (((vxid).backendId != InvalidBackendId) && \ - LocalTransactionIdIsValid((vxid).localTransactionId)) + (LocalTransactionIdIsValid((vxid).localTransactionId)) +#define VirtualTransactionIdIsPreparedXact(vxid) \ + ((vxid).backendId == InvalidBackendId) #define VirtualTransactionIdEquals(vxid1, vxid2) \ ((vxid1).backendId == (vxid2).backendId && \ (vxid1).localTransactionId == (vxid2).localTransactionId) |