Skip to content

Commit 7fcf2fa

Browse files
committed
Make XLOG_FPI_FOR_HINT records honor full_page_writes setting.
Commit 2c03216 changed XLOG_FPI_FOR_HINT records so that they always included full-page images even when full_page_writes was disabled. However, in this setting, they don't need to do that because hint bit updates don't need to be protected from torn writes. Therefore, this commit makes XLOG_FPI_FOR_HINT records honor full_page_writes setting. That is, XLOG_FPI_FOR_HINT records may include no full-page images if full_page_writes is disabled, and WAL replay of them does nothing. Reported-by: Zhang Wenjie Author: Kyotaro Horiguchi Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/tencent_60F11973A111EED97A8596FFECC4A91ED405@qq.com
1 parent d9809bf commit 7fcf2fa

File tree

2 files changed

+22
-15
lines changed

2 files changed

+22
-15
lines changed

src/backend/access/transam/xlog.c

+21-11
Original file line numberDiff line numberDiff line change
@@ -10148,7 +10148,10 @@ xlog_redo(XLogReaderState *record)
1014810148
uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1014910149
XLogRecPtr lsn = record->EndRecPtr;
1015010150

10151-
/* in XLOG rmgr, backup blocks are only used by XLOG_FPI records */
10151+
/*
10152+
* In XLOG rmgr, backup blocks are only used by XLOG_FPI and
10153+
* XLOG_FPI_FOR_HINT records.
10154+
*/
1015210155
Assert(info == XLOG_FPI || info == XLOG_FPI_FOR_HINT ||
1015310156
!XLogRecHasAnyBlockRefs(record));
1015410157

@@ -10356,25 +10359,32 @@ xlog_redo(XLogReaderState *record)
1035610359
else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT)
1035710360
{
1035810361
/*
10359-
* Full-page image (FPI) records contain nothing else but a backup
10360-
* block (or multiple backup blocks). Every block reference must
10361-
* include a full-page image - otherwise there would be no point in
10362-
* this record.
10362+
* XLOG_FPI records contain nothing else but one or more block
10363+
* references. Every block reference must include a full-page image
10364+
* even if full_page_writes was disabled when the record was generated
10365+
* - otherwise there would be no point in this record.
10366+
*
10367+
* XLOG_FPI_FOR_HINT records are generated when a page needs to be
10368+
* WAL-logged because of a hint bit update. They are only generated
10369+
* when checksums and/or wal_log_hints are enabled. They may include
10370+
* no full-page images if full_page_writes was disabled when they were
10371+
* generated. In this case there is nothing to do here.
1036310372
*
1036410373
* No recovery conflicts are generated by these generic records - if a
1036510374
* resource manager needs to generate conflicts, it has to define a
1036610375
* separate WAL record type and redo routine.
10367-
*
10368-
* XLOG_FPI_FOR_HINT records are generated when a page needs to be
10369-
* WAL- logged because of a hint bit update. They are only generated
10370-
* when checksums are enabled. There is no difference in handling
10371-
* XLOG_FPI and XLOG_FPI_FOR_HINT records, they use a different info
10372-
* code just to distinguish them for statistics purposes.
1037310376
*/
1037410377
for (uint8 block_id = 0; block_id <= record->max_block_id; block_id++)
1037510378
{
1037610379
Buffer buffer;
1037710380

10381+
if (!XLogRecHasBlockImage(record, block_id))
10382+
{
10383+
if (info == XLOG_FPI)
10384+
elog(ERROR, "XLOG_FPI record did not contain a full-page image");
10385+
continue;
10386+
}
10387+
1037810388
if (XLogReadBufferForRedo(record, block_id, &buffer) != BLK_RESTORED)
1037910389
elog(ERROR, "unexpected XLogReadBufferForRedo result when restoring backup block");
1038010390
UnlockReleaseBuffer(buffer);

src/backend/access/transam/xloginsert.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,6 @@ XLogRegisterBlock(uint8 block_id, RelFileNode *rnode, ForkNumber forknum,
287287
{
288288
registered_buffer *regbuf;
289289

290-
/* This is currently only used to WAL-log a full-page image of a page */
291-
Assert(flags & REGBUF_FORCE_IMAGE);
292290
Assert(begininsert_called);
293291

294292
if (block_id >= max_registered_block_id)
@@ -995,7 +993,7 @@ XLogSaveBufferForHint(Buffer buffer, bool buffer_std)
995993

996994
if (lsn <= RedoRecPtr)
997995
{
998-
int flags;
996+
int flags = 0;
999997
PGAlignedBlock copied_buffer;
1000998
char *origdata = (char *) BufferGetBlock(buffer);
1001999
RelFileNode rnode;
@@ -1022,7 +1020,6 @@ XLogSaveBufferForHint(Buffer buffer, bool buffer_std)
10221020

10231021
XLogBeginInsert();
10241022

1025-
flags = REGBUF_FORCE_IMAGE;
10261023
if (buffer_std)
10271024
flags |= REGBUF_STANDARD;
10281025

0 commit comments

Comments
 (0)