Skip to content

Commit ef74c71

Browse files
committed
Fix bug in GenericXLogFinish().
Mark the buffers dirty before writing WAL. Discussion: https://postgr.es/m/25104133-7df8-cae3-b9a2-1c0aaa1c094a@iki.fi Reviewed-by: Heikki Linnakangas Backpatch-through: 11
1 parent 14661ba commit ef74c71

File tree

1 file changed

+26
-30
lines changed

1 file changed

+26
-30
lines changed

src/backend/access/transam/generic_xlog.c

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@ GenericXLogFinish(GenericXLogState *state)
347347

348348
START_CRIT_SECTION();
349349

350+
/*
351+
* Compute deltas if necessary, write changes to buffers, mark
352+
* buffers dirty, and register changes.
353+
*/
350354
for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
351355
{
352356
PageData *pageData = &state->pages[i];
@@ -359,41 +363,34 @@ GenericXLogFinish(GenericXLogState *state)
359363
page = BufferGetPage(pageData->buffer);
360364
pageHeader = (PageHeader) pageData->image;
361365

366+
/*
367+
* Compute delta while we still have both the unmodified page and
368+
* the new image. Not needed if we are logging the full image.
369+
*/
370+
if (!(pageData->flags & GENERIC_XLOG_FULL_IMAGE))
371+
computeDelta(pageData, page, (Page) pageData->image);
372+
373+
/*
374+
* Apply the image, being careful to zero the "hole" between
375+
* pd_lower and pd_upper in order to avoid divergence between
376+
* actual page state and what replay would produce.
377+
*/
378+
memcpy(page, pageData->image, pageHeader->pd_lower);
379+
memset(page + pageHeader->pd_lower, 0,
380+
pageHeader->pd_upper - pageHeader->pd_lower);
381+
memcpy(page + pageHeader->pd_upper,
382+
pageData->image + pageHeader->pd_upper,
383+
BLCKSZ - pageHeader->pd_upper);
384+
385+
MarkBufferDirty(pageData->buffer);
386+
362387
if (pageData->flags & GENERIC_XLOG_FULL_IMAGE)
363388
{
364-
/*
365-
* A full-page image does not require us to supply any xlog
366-
* data. Just apply the image, being careful to zero the
367-
* "hole" between pd_lower and pd_upper in order to avoid
368-
* divergence between actual page state and what replay would
369-
* produce.
370-
*/
371-
memcpy(page, pageData->image, pageHeader->pd_lower);
372-
memset(page + pageHeader->pd_lower, 0,
373-
pageHeader->pd_upper - pageHeader->pd_lower);
374-
memcpy(page + pageHeader->pd_upper,
375-
pageData->image + pageHeader->pd_upper,
376-
BLCKSZ - pageHeader->pd_upper);
377-
378389
XLogRegisterBuffer(i, pageData->buffer,
379390
REGBUF_FORCE_IMAGE | REGBUF_STANDARD);
380391
}
381392
else
382393
{
383-
/*
384-
* In normal mode, calculate delta and write it as xlog data
385-
* associated with this page.
386-
*/
387-
computeDelta(pageData, page, (Page) pageData->image);
388-
389-
/* Apply the image, with zeroed "hole" as above */
390-
memcpy(page, pageData->image, pageHeader->pd_lower);
391-
memset(page + pageHeader->pd_lower, 0,
392-
pageHeader->pd_upper - pageHeader->pd_lower);
393-
memcpy(page + pageHeader->pd_upper,
394-
pageData->image + pageHeader->pd_upper,
395-
BLCKSZ - pageHeader->pd_upper);
396-
397394
XLogRegisterBuffer(i, pageData->buffer, REGBUF_STANDARD);
398395
XLogRegisterBufData(i, pageData->delta, pageData->deltaLen);
399396
}
@@ -402,15 +399,14 @@ GenericXLogFinish(GenericXLogState *state)
402399
/* Insert xlog record */
403400
lsn = XLogInsert(RM_GENERIC_ID, 0);
404401

405-
/* Set LSN and mark buffers dirty */
402+
/* Set LSN */
406403
for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)
407404
{
408405
PageData *pageData = &state->pages[i];
409406

410407
if (BufferIsInvalid(pageData->buffer))
411408
continue;
412409
PageSetLSN(BufferGetPage(pageData->buffer), lsn);
413-
MarkBufferDirty(pageData->buffer);
414410
}
415411
END_CRIT_SECTION();
416412
}

0 commit comments

Comments
 (0)