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

Commit66d86d4

Browse files
committed
Document more assumptions of LWLock variable changes with WAL inserts
This commit adds a few comments about what LWLockWaitForVar() relies onwhen a backend waits for a variable update on its LWLocks for WALinsertions up to an expected LSN.First, LWLockWaitForVar() does not include a memory barrier, relying ona spinlock taken at the beginning of WaitXLogInsertionsToFinish(). Thiswas hidden behind two layers of routines in lwlock.c. This assumptionis now documented at the top of LWLockWaitForVar(), and detailed at bitmore within LWLockConflictsWithVar().Second, document why WaitXLogInsertionsToFinish() does not includememory barriers, relying on a spinlock at its top, which is, per Andres'input, fine for two different reasons, both depending on the fact thatthe caller of WaitXLogInsertionsToFinish() is waiting for a LSN up to acertain value.This area's documentation and assumptions could be improved more in thefuture, but at least that's a beginning.Author: Bharath Rupireddy, Andres FreundReviewed-by: Michael PaquierDiscussion:https://postgr.es/m/CALj2ACVF+6jLvqKe6xhDzCCkr=rfd6upaGc3477Pji1Ke9G7Bg@mail.gmail.com
1 parent62e9af4 commit66d86d4

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

‎src/backend/access/transam/xlog.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,17 @@ WaitXLogInsertionsToFinish(XLogRecPtr upto)
14951495
* calling LWLockUpdateVar. But if it has to sleep, it will
14961496
* advertise the insertion point with LWLockUpdateVar before
14971497
* sleeping.
1498+
*
1499+
* In this loop we are only waiting for insertions that started
1500+
* before WaitXLogInsertionsToFinish was called. The lack of
1501+
* memory barriers in the loop means that we might see locks as
1502+
* "unused" that have since become used. This is fine because
1503+
* they only can be used for later insertions that we would not
1504+
* want to wait on anyway. Not taking a lock to acquire the
1505+
* current insertingAt value means that we might see older
1506+
* insertingAt values. This is also fine, because if we read a
1507+
* value too old, we will add ourselves to the wait queue, which
1508+
* contains atomic operations.
14981509
*/
14991510
if (LWLockWaitForVar(&WALInsertLocks[i].l.lock,
15001511
&WALInsertLocks[i].l.insertingAt,

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,9 +1556,10 @@ LWLockConflictsWithVar(LWLock *lock, pg_atomic_uint64 *valptr, uint64 oldval,
15561556
/*
15571557
* Test first to see if it the slot is free right now.
15581558
*
1559-
* XXX: the caller uses a spinlock before this, so we don't need a memory
1560-
* barrier here as far as the current usage is concerned. But that might
1561-
* not be safe in general.
1559+
* XXX: the unique caller of this routine, WaitXLogInsertionsToFinish()
1560+
* via LWLockWaitForVar(), uses an implied barrier with a spinlock before
1561+
* this, so we don't need a memory barrier here as far as the current
1562+
* usage is concerned. But that might not be safe in general.
15621563
*/
15631564
mustwait= (pg_atomic_read_u32(&lock->state)&LW_VAL_EXCLUSIVE)!=0;
15641565

@@ -1601,6 +1602,10 @@ LWLockConflictsWithVar(LWLock *lock, pg_atomic_uint64 *valptr, uint64 oldval,
16011602
*
16021603
* Note: this function ignores shared lock holders; if the lock is held
16031604
* in shared mode, returns 'true'.
1605+
*
1606+
* Be aware that LWLockConflictsWithVar() does not include a memory barrier,
1607+
* hence the caller of this function may want to rely on an explicit barrier or
1608+
* an implied barrier via spinlock or LWLock to avoid memory ordering issues.
16041609
*/
16051610
bool
16061611
LWLockWaitForVar(LWLock*lock,pg_atomic_uint64*valptr,uint64oldval,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp