aboutsummaryrefslogtreecommitdiff
path: root/src/include/storage/lock.h
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:02:11 -0800
commit179775135b41a0640ec8b378b2699dca00d3a49a (patch)
tree85d97e687d3dcbc4c3a5880e8b6298165ab751a4 /src/include/storage/lock.h
parentc4484232ed3f17c270621eb8ffb974d85023b9ea (diff)
downloadpostgresql-179775135b41a0640ec8b378b2699dca00d3a49a.tar.gz
postgresql-179775135b41a0640ec8b378b2699dca00d3a49a.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/lock.h')
-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 5d1d2763bc8..54674155d77 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -47,10 +47,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
@@ -62,15 +62,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)