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

Commit358cde3

Browse files
committed
Fix race condition that lead to WALInsertLock deadlock with commit_delay.
If a call to WaitForXLogInsertionsToFinish() returned a value in the middleof a page, and another backend then started to insert a record to the samepage, and then you called WaitXLogInsertionsToFinish() again, the secondcall might return a smaller value than the first call. The problem was inGetXLogBuffer(), which always updated the insertingAt value to thebeginning of the requested page, not the actual requested location. Becauseof that, the second call might return a xlog pointer to the beginning ofthe page, while the first one returned a later position on the same page.XLogFlush() performs two calls to WaitXLogInsertionsToFinish() insuccession, and holds WALWriteLock on the second call, which can deadlockif the second call to WaitXLogInsertionsToFinish() blocks.Reported by Spiros Ioannou. Backpatch to 9.4, where the more scalableWALInsertLock mechanism, and this bug, was introduced.
1 parenta4b09af commit358cde3

File tree

1 file changed

+24
-3
lines changed
  • src/backend/access/transam

1 file changed

+24
-3
lines changed

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,11 +1664,32 @@ GetXLogBuffer(XLogRecPtr ptr)
16641664
endptr=XLogCtl->xlblocks[idx];
16651665
if (expectedEndPtr!=endptr)
16661666
{
1667+
XLogRecPtrinitializedUpto;
1668+
16671669
/*
1668-
* Let others know that we're finished inserting the record up to the
1669-
* page boundary.
1670+
* Before calling AdvanceXLInsertBuffer(), which can block, let others
1671+
* know how far we're finished with inserting the record.
1672+
*
1673+
* NB: If 'ptr' points to just after the page header, advertise a
1674+
* position at the beginning of the page rather than 'ptr' itself. If
1675+
* there are no other insertions running, someone might try to flush
1676+
* up to our advertised location. If we advertised a position after
1677+
* the page header, someone might try to flush the page header, even
1678+
* though page might actually not be initialized yet. As the first
1679+
* inserter on the page, we are effectively responsible for making
1680+
* sure that it's initialized, before we let insertingAt to move past
1681+
* the page header.
16701682
*/
1671-
WALInsertLockUpdateInsertingAt(expectedEndPtr-XLOG_BLCKSZ);
1683+
if (ptr %XLOG_BLCKSZ==SizeOfXLogShortPHD&&
1684+
ptr %XLOG_SEG_SIZE>XLOG_BLCKSZ)
1685+
initializedUpto=ptr-SizeOfXLogShortPHD;
1686+
elseif (ptr %XLOG_BLCKSZ==SizeOfXLogLongPHD&&
1687+
ptr %XLOG_SEG_SIZE<XLOG_BLCKSZ)
1688+
initializedUpto=ptr-SizeOfXLogLongPHD;
1689+
else
1690+
initializedUpto=ptr;
1691+
1692+
WALInsertLockUpdateInsertingAt(initializedUpto);
16721693

16731694
AdvanceXLInsertBuffer(ptr, false);
16741695
endptr=XLogCtl->xlblocks[idx];

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp