aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/vacuum.c2
-rw-r--r--src/backend/replication/logical/logical.c2
-rw-r--r--src/backend/replication/slot.c2
-rw-r--r--src/backend/storage/ipc/procarray.c8
-rw-r--r--src/backend/storage/lmgr/deadlock.c2
-rw-r--r--src/include/storage/proc.h5
6 files changed, 16 insertions, 5 deletions
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index d89ba3031f9..395e75f768f 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -1741,7 +1741,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
* MyProc->xid/xmin, otherwise GetOldestNonRemovableTransactionId()
* might appear to go backwards, which is probably Not Good.
*/
- LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+ LWLockAcquire(ProcArrayLock, LW_SHARED);
MyProc->statusFlags |= PROC_IN_VACUUM;
if (params->is_wraparound)
MyProc->statusFlags |= PROC_VACUUM_FOR_WRAPAROUND;
diff --git a/src/backend/replication/logical/logical.c b/src/backend/replication/logical/logical.c
index f1f4df7d70f..4324e326565 100644
--- a/src/backend/replication/logical/logical.c
+++ b/src/backend/replication/logical/logical.c
@@ -181,7 +181,7 @@ StartupDecodingContext(List *output_plugin_options,
*/
if (!IsTransactionOrTransactionBlock())
{
- LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+ LWLockAcquire(ProcArrayLock, LW_SHARED);
MyProc->statusFlags |= PROC_IN_LOGICAL_DECODING;
ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
LWLockRelease(ProcArrayLock);
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 5ed955ba0bf..9c7cf13d4d9 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -527,7 +527,7 @@ ReplicationSlotRelease(void)
MyReplicationSlot = NULL;
/* might not have been set when we've been a plain slot */
- LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
+ LWLockAcquire(ProcArrayLock, LW_SHARED);
MyProc->statusFlags &= ~PROC_IN_LOGICAL_DECODING;
ProcGlobal->statusFlags[MyProc->pgxactoff] = MyProc->statusFlags;
LWLockRelease(ProcArrayLock);
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index e2cb6e990d1..94edb24b22d 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -662,6 +662,8 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
/* avoid unnecessarily dirtying shared cachelines */
if (proc->statusFlags & PROC_VACUUM_STATE_MASK)
{
+ /* Only safe to change my own flags with just share lock */
+ Assert(proc == MyProc);
Assert(!LWLockHeldByMe(ProcArrayLock));
LWLockAcquire(ProcArrayLock, LW_SHARED);
Assert(proc->statusFlags == ProcGlobal->statusFlags[proc->pgxactoff]);
@@ -682,7 +684,11 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
{
size_t pgxactoff = proc->pgxactoff;
- Assert(LWLockHeldByMe(ProcArrayLock));
+ /*
+ * Note: we need exclusive lock here because we're going to
+ * change other processes' PGPROC entries.
+ */
+ Assert(LWLockHeldByMeInMode(ProcArrayLock, LW_EXCLUSIVE));
Assert(TransactionIdIsValid(ProcGlobal->xids[pgxactoff]));
Assert(ProcGlobal->xids[pgxactoff] == proc->xid);
diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c
index cb7a8f0fd28..f7ed6968ca9 100644
--- a/src/backend/storage/lmgr/deadlock.c
+++ b/src/backend/storage/lmgr/deadlock.c
@@ -623,7 +623,7 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
* because that flag is set at process start and never
* reset. There is logic elsewhere to avoid canceling an
* autovacuum that is working to prevent XID wraparound
- * problems (which needs to read a different vacuumFlag
+ * problems (which needs to read a different statusFlags
* bit), but we don't do that here to avoid grabbing
* ProcArrayLock.
*/
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index 1067f58f51b..00bb244340a 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -98,6 +98,11 @@ typedef enum
* The semaphore and lock-activity fields in a prepared-xact PGPROC are unused,
* but its myProcLocks[] lists are valid.
*
+ * We allow many fields of this struct to be accessed without locks, such as
+ * statusFlags or delayChkpt. However, keep in mind that writing mirrored ones
+ * (see below) requires holding ProcArrayLock or XidGenLock in at least shared
+ * mode, so that pgxactoff does not change concurrently.
+ *
* Mirrored fields:
*
* Some fields in PGPROC (see "mirrored in ..." comment) are mirrored into an