• Heikki Linnakangas's avatar
    Fix race condition that lead to WALInsertLock deadlock with commit_delay. · 358cde32
    Heikki Linnakangas authored
    If a call to WaitForXLogInsertionsToFinish() returned a value in the middle
    of a page, and another backend then started to insert a record to the same
    page, and then you called WaitXLogInsertionsToFinish() again, the second
    call might return a smaller value than the first call. The problem was in
    GetXLogBuffer(), which always updated the insertingAt value to the
    beginning of the requested page, not the actual requested location. Because
    of that, the second call might return a xlog pointer to the beginning of
    the page, while the first one returned a later position on the same page.
    XLogFlush() performs two calls to WaitXLogInsertionsToFinish() in
    succession, and holds WALWriteLock on the second call, which can deadlock
    if the second call to WaitXLogInsertionsToFinish() blocks.
    
    Reported by Spiros Ioannou. Backpatch to 9.4, where the more scalable
    WALInsertLock mechanism, and this bug, was introduced.
    358cde32
xlog.c 358 KB