aboutsummaryrefslogtreecommitdiff
path: root/src/include/storage
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2021-01-30 00:00:27 -0800
committerNoah Misch <noah@leadboat.com>2021-01-30 00:00:27 -0800
commit8a54e12a38d1545d249f1402f66c8cde2837d97c (patch)
treed6b155a68f9e3dc21f1061106320c620eeaeb6ed /src/include/storage
parentf77717b2985aa529a185e6988de26b885ca10ddb (diff)
downloadpostgresql-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.h17
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)