8000 Only allow autovacuum to be auto-canceled by a directly blocked process. · sureandrew/postgres@588586b · GitHub
[go: up one dir, main page]

Skip to content

Commit 588586b

Browse files
committed
Only allow autovacuum to be auto-canceled by a directly blocked process.
In the original coding of the autovacuum cancel feature, commit acac68b, an autovacuum process was considered a target for cancellation if it was found to hard-block any process examined in the deadlock search. This patch tightens the test so that the autovacuum must directly hard-block the current process. This should make the behavior more predictable in general, and in particular it ensures that an autovacuum will not be canceled with less than deadlock_timeout grace period. In the old coding, it was possible for an autovacuum to be canceled almost instantly, given unfortunate timing of two or more other processes' lock attempts. This also justifies the logging methodology in the recent commit d7318d4; without this restriction, that patch isn't providing enough information to see the connection of the canceling process to the autovacuum. Like that one, patch all the way back.
1 parent d2b93bf commit 588586b

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

src/backend/storage/lmgr/deadlock.c

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -521,25 +521,6 @@ FindLockCycleRecurse(PGPROC *checkProc,
521521
if ((proclock->holdMask & LOCKBIT_ON(lm)) &&
522522
(conflictMask & LOCKBIT_ON(lm)))
523523
{
524-
/*
525-
* Look for a blocking autovacuum. There can be more than
526-
* one in the deadlock cycle, in which case we just pick a
527-
* random one. We stash the autovacuum worker's PGPROC so
528-
* that the caller can send a cancel signal to it, if
529-
* appropriate.
530-
*
531-
* Note we read vacuumFlags without any locking. This is
532-
* OK only for checking the PROC_IS_AUTOVACUUM flag,
533-
* because that flag is set at process start and never
534-
* reset; there is logic elsewhere to avoid cancelling an
535-
* autovacuum that is working for preventing Xid
536-
* wraparound problems (which needs to read a different
537-
* vacuumFlag bit), but we don't do that here to avoid
538-
* grabbing ProcArrayLock.
539-
*/
540-
if (proc->vacuumFlags & PROC_IS_AUTOVACUUM)
541-
blocking_autovacuum_proc = proc;
542-
543524
/* This proc hard-blocks checkProc */
544525
if (FindLockCycleRecurse(proc, depth + 1,
545526
softEdges, nSoftEdges))
@@ -553,7 +534,34 @@ FindLockCycleRecurse(PGPROC *checkProc,
553534

554535
return true;
555536
}
556-
/* If no deadlock, we're done looking at this proclock */
537+
538+
/*
539+
* No deadlock here, but see if this proc is an autovacuum
540+
* that is directly hard-blocking our own proc. If so,
541+
* report it so that the caller can send a cancel signal
542+
* to it, if appropriate. If there's more than one such
543+
* proc, it's indeterminate which one will be reported.
544+
*
545+
* We don't touch autovacuums that are indirectly blocking
546+
* us; it's up to the direct blockee to take action. This
547+
* rule simplifies understanding the behavior and ensures
548+
* that an autovacuum won't be canceled with less than
549+
* deadlock_timeout grace period.
550+
*
551+
* Note we read vacuumFlags without any locking. This is
552+
* OK only for checking the PROC_IS_AUTOVACUUM flag,
553+
* because that flag is set at process start and never
554+
* reset. There is logic elsewhere to avoid canceling an
555+
* autovacuum that is working to prevent XID wraparound
556+
* problems (which needs to read a different vacuumFlag
557+
* bit), but we don't do that here to avoid grabbing
558+
* ProcArrayLock.
559+
*/
560+
if (checkProc == MyProc &&
561+
proc->vacuumFlags & PROC_IS_AUTOVACUUM)
562+
blocking_autovacuum_proc = proc;
563+
564+
/* We're done looking at this proclock */
557565
break;
558566
}
559567
}

0 commit comments

Comments
 (0)
0