Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2783898

Browse files
committed
Relax lock level for setting PGPROC->statusFlags
We don't actually need a lock to set PGPROC->statusFlags itself; what wedo need is a shared lock on either XidGenLock or ProcArrayLock in order toensure MyProc->pgxactoff keeps still while we modify the mirror array inProcGlobal->statusFlags. Some places were using an exclusive lock forthat, which is excessive. Relax those to use shared lock only.procarray.c has a couple of places with somewhat brittle assumptionsabout PGPROC changes: ProcArrayEndTransaction uses only shared lock, soit's permissible to change MyProc only. On the other hand,ProcArrayEndTransactionInternal also changes other procs, so it musthold exclusive lock. Add asserts to ensure those assumptions continueto hold.Author: Álvaro Herrera <alvherre@alvh.no-ip.org>Reviewed-by: Michael Paquier <michael@paquier.xyz>Discussion:https://postgr.es/m/20201117155501.GA13805@alvherre.pgsql
1 parent2cccb62 commit2783898

File tree

6 files changed

+16
-5
lines changed

6 files changed

+16
-5
lines changed

‎src/backend/commands/vacuum.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1741,7 +1741,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
17411741
* MyProc->xid/xmin, otherwise GetOldestNonRemovableTransactionId()
17421742
* might appear to go backwards, which is probably Not Good.
17431743
*/
1744-
LWLockAcquire(ProcArrayLock,LW_EXCLUSIVE);
1744+
LWLockAcquire(ProcArrayLock,LW_SHARED);
17451745
MyProc->statusFlags |=PROC_IN_VACUUM;
17461746
if (params->is_wraparound)
17471747
MyProc->statusFlags |=PROC_VACUUM_FOR_WRAPAROUND;

‎src/backend/replication/logical/logical.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ StartupDecodingContext(List *output_plugin_options,
181181
*/
182182
if (!IsTransactionOrTransactionBlock())
183183
{
184-
LWLockAcquire(ProcArrayLock,LW_EXCLUSIVE);
184+
LWLockAcquire(ProcArrayLock,LW_SHARED);
185185
MyProc->statusFlags |=PROC_IN_LOGICAL_DECODING;
186186
ProcGlobal->statusFlags[MyProc->pgxactoff]=MyProc->statusFlags;
187187
LWLockRelease(ProcArrayLock);

‎src/backend/replication/slot.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ ReplicationSlotRelease(void)
527527
MyReplicationSlot=NULL;
528528

529529
/* might not have been set when we've been a plain slot */
530-
LWLockAcquire(ProcArrayLock,LW_EXCLUSIVE);
530+
LWLockAcquire(ProcArrayLock,LW_SHARED);
531531
MyProc->statusFlags &= ~PROC_IN_LOGICAL_DECODING;
532532
ProcGlobal->statusFlags[MyProc->pgxactoff]=MyProc->statusFlags;
533533
LWLockRelease(ProcArrayLock);

‎src/backend/storage/ipc/procarray.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,8 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
662662
/* avoid unnecessarily dirtying shared cachelines */
663663
if (proc->statusFlags&PROC_VACUUM_STATE_MASK)
664664
{
665+
/* Only safe to change my own flags with just share lock */
666+
Assert(proc==MyProc);
665667
Assert(!LWLockHeldByMe(ProcArrayLock));
666668
LWLockAcquire(ProcArrayLock,LW_SHARED);
667669
Assert(proc->statusFlags==ProcGlobal->statusFlags[proc->pgxactoff]);
@@ -682,7 +684,11 @@ ProcArrayEndTransactionInternal(PGPROC *proc, TransactionId latestXid)
682684
{
683685
size_tpgxactoff=proc->pgxactoff;
684686

685-
Assert(LWLockHeldByMe(ProcArrayLock));
687+
/*
688+
* Note: we need exclusive lock here because we're going to
689+
* change other processes' PGPROC entries.
690+
*/
691+
Assert(LWLockHeldByMeInMode(ProcArrayLock,LW_EXCLUSIVE));
686692
Assert(TransactionIdIsValid(ProcGlobal->xids[pgxactoff]));
687693
Assert(ProcGlobal->xids[pgxactoff]==proc->xid);
688694

‎src/backend/storage/lmgr/deadlock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ FindLockCycleRecurseMember(PGPROC *checkProc,
623623
* because that flag is set at process start and never
624624
* reset. There is logic elsewhere to avoid canceling an
625625
* autovacuum that is working to prevent XID wraparound
626-
* problems (which needs to read a differentvacuumFlag
626+
* problems (which needs to read a differentstatusFlags
627627
* bit), but we don't do that here to avoid grabbing
628628
* ProcArrayLock.
629629
*/

‎src/include/storage/proc.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ typedef enum
9898
* The semaphore and lock-activity fields in a prepared-xact PGPROC are unused,
9999
* but its myProcLocks[] lists are valid.
100100
*
101+
* We allow many fields of this struct to be accessed without locks, such as
102+
* statusFlags or delayChkpt. However, keep in mind that writing mirrored ones
103+
* (see below) requires holding ProcArrayLock or XidGenLock in at least shared
104+
* mode, so that pgxactoff does not change concurrently.
105+
*
101106
* Mirrored fields:
102107
*
103108
* Some fields in PGPROC (see "mirrored in ..." comment) are mirrored into an

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp