MarkBufferDirtyHint() and LSN update

Поиск
Список
Период
Сортировка
От Antonin Houska
Тема MarkBufferDirtyHint() and LSN update
Дата
Msg-id 28452.1572443058@antos
обсуждение исходный текст
Ответы Re: MarkBufferDirtyHint() and LSN update  (Tomas Vondra <tomas.vondra@2ndquadrant.com>)
Re: MarkBufferDirtyHint() and LSN update  (Robert Haas <robertmhaas@gmail.com>)
Список pgsql-hackers
Please consider this scenario (race conditions):

1. FlushBuffer() has written the buffer but hasn't yet managed to clear the
BM_DIRTY flag (however BM_JUST_DIRTIED could be cleared by now).

2. Another backend modified a hint bit and called MarkBufferDirtyHint().

3. In MarkBufferDirtyHint(), if XLogHintBitIsNeeded() evaluates to true
(e.g. due to checksums enabled), new LSN is computed, however it's not
assigned to the page because the buffer is still dirty:

    if (!(buf_state & BM_DIRTY))
    {
        ...

        if (!XLogRecPtrIsInvalid(lsn))
            PageSetLSN(page, lsn);
    }

4. MarkBufferDirtyHint() completes.

5. In the first session, FlushBuffer()->TerminateBufferIO() will not clear
BM_DIRTY because MarkBufferDirtyHint() has eventually set
BM_JUST_DIRTIED. Thus the hint bit change itself will be written by the next
call of FlushBuffer(). However page LSN is hasn't been updated so the
requirement that WAL must be flushed first is not met.

I think that PageSetLSN() should be called regardless BM_DIRTY. Do I miss any
subtle detail?

-- 
Antonin Houska
Web: https://www.cybertec-postgresql.com



В списке pgsql-hackers по дате отправления:

Предыдущее
От: Michael Paquier
Дата:
Сообщение: Re: Problem with synchronous replication
Следующее
От: Peter Eisentraut
Дата:
Сообщение: Remove HAVE_LONG_LONG_INT