diff options
author | Fujii Masao <fujii@postgresql.org> | 2021-07-21 11:19:00 +0900 |
---|---|---|
committer | Fujii Masao <fujii@postgresql.org> | 2021-07-21 11:19:00 +0900 |
commit | 7fcf2faf9c7dd473208fd6d5565f88d7f733782b (patch) | |
tree | 36a9f917da6e5d6a7199cc0ef40c227e0e7f038a /src/backend/access/transam/xlog.c | |
parent | d9809bf8694c17e05537c5dd96cde3e67c02d52a (diff) | |
download | postgresql-7fcf2faf9c7dd473208fd6d5565f88d7f733782b.tar.gz postgresql-7fcf2faf9c7dd473208fd6d5565f88d7f733782b.zip |
Make XLOG_FPI_FOR_HINT records honor full_page_writes setting.
Commit 2c03216d83 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
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 2ee95151392..3479402272b 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -10148,7 +10148,10 @@ xlog_redo(XLogReaderState *record) uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK; XLogRecPtr lsn = record->EndRecPtr; - /* in XLOG rmgr, backup blocks are only used by XLOG_FPI records */ + /* + * In XLOG rmgr, backup blocks are only used by XLOG_FPI and + * XLOG_FPI_FOR_HINT records. + */ Assert(info == XLOG_FPI || info == XLOG_FPI_FOR_HINT || !XLogRecHasAnyBlockRefs(record)); @@ -10356,25 +10359,32 @@ xlog_redo(XLogReaderState *record) else if (info == XLOG_FPI || info == XLOG_FPI_FOR_HINT) { /* - * Full-page image (FPI) records contain nothing else but a backup - * block (or multiple backup blocks). Every block reference must - * include a full-page image - otherwise there would be no point in - * this record. + * XLOG_FPI records contain nothing else but one or more block + * references. Every block reference must include a full-page image + * even if full_page_writes was disabled when the record was generated + * - otherwise there would be no point in this record. + * + * XLOG_FPI_FOR_HINT records are generated when a page needs to be + * WAL-logged because of a hint bit update. They are only generated + * when checksums and/or wal_log_hints are enabled. They may include + * no full-page images if full_page_writes was disabled when they were + * generated. In this case there is nothing to do here. * * No recovery conflicts are generated by these generic records - if a * resource manager needs to generate conflicts, it has to define a * separate WAL record type and redo routine. - * - * XLOG_FPI_FOR_HINT records are generated when a page needs to be - * WAL- logged because of a hint bit update. They are only generated - * when checksums are enabled. There is no difference in handling - * XLOG_FPI and XLOG_FPI_FOR_HINT records, they use a different info - * code just to distinguish them for statistics purposes. */ for (uint8 block_id = 0; block_id <= record->max_block_id; block_id++) { Buffer buffer; + if (!XLogRecHasBlockImage(record, block_id)) + { + if (info == XLOG_FPI) + elog(ERROR, "XLOG_FPI record did not contain a full-page image"); + continue; + } + if (XLogReadBufferForRedo(record, block_id, &buffer) != BLK_RESTORED) elog(ERROR, "unexpected XLogReadBufferForRedo result when restoring backup block"); UnlockReleaseBuffer(buffer); |