*** a/src/backend/access/transam/xlog.c --- b/src/backend/access/transam/xlog.c *************** *** 79,84 **** bool XLogArchiveMode = false; --- 79,85 ---- char *XLogArchiveCommand = NULL; bool EnableHotStandby = false; bool fullPageWrites = true; + bool enableLoggingHintbit = false; bool log_checkpoints = false; int sync_method = DEFAULT_SYNC_METHOD; int wal_level = WAL_LEVEL_MINIMAL; *************** *** 5265,5270 **** BootStrapXLOG(void) --- 5266,5272 ---- ControlFile->max_locks_per_xact = max_locks_per_xact; ControlFile->wal_level = wal_level; ControlFile->data_checksum_version = bootstrap_data_checksum_version; + ControlFile->enable_logging_hintbit = enableLoggingHintbit; /* some additional ControlFile fields are set in WriteControlFile() */ *************** *** 8921,8926 **** static void --- 8923,8929 ---- XLogReportParameters(void) { if (wal_level != ControlFile->wal_level || + enableLoggingHintbit != ControlFile->enable_logging_hintbit || MaxConnections != ControlFile->MaxConnections || max_worker_processes != ControlFile->max_worker_processes || max_prepared_xacts != ControlFile->max_prepared_xacts || *************** *** 8943,8948 **** XLogReportParameters(void) --- 8946,8952 ---- xlrec.max_prepared_xacts = max_prepared_xacts; xlrec.max_locks_per_xact = max_locks_per_xact; xlrec.wal_level = wal_level; + xlrec.enable_logging_hintbit = enableLoggingHintbit; rdata.buffer = InvalidBuffer; rdata.data = (char *) &xlrec; *************** *** 8957,8962 **** XLogReportParameters(void) --- 8961,8967 ---- ControlFile->max_prepared_xacts = max_prepared_xacts; ControlFile->max_locks_per_xact = max_locks_per_xact; ControlFile->wal_level = wal_level; + ControlFile->enable_logging_hintbit = enableLoggingHintbit; UpdateControlFile(); } } *************** *** 9343,9348 **** xlog_redo(XLogRecPtr lsn, XLogRecord *record) --- 9348,9354 ---- ControlFile->max_prepared_xacts = xlrec.max_prepared_xacts; ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact; ControlFile->wal_level = xlrec.wal_level; + ControlFile->enable_logging_hintbit = enableLoggingHintbit; /* * Update minRecoveryPoint to ensure that if recovery is aborted, we *** a/src/backend/postmaster/postmaster.c --- b/src/backend/postmaster/postmaster.c *************** *** 817,822 **** PostmasterMain(int argc, char *argv[]) --- 817,825 ---- if (XLogArchiveMode && wal_level == WAL_LEVEL_MINIMAL) ereport(ERROR, (errmsg("WAL archival (archive_mode=on) requires wal_level \"archive\" or \"hot_standby\""))); + if (enableLoggingHintbit && wal_level == WAL_LEVEL_MINIMAL) + ereport(ERROR, + (errmsg("Logging hintbit (enable_logging_hintbit = on) requires wal_level \"archive\" or \"hot_standby\""))); if (max_wal_senders > 0 && wal_level == WAL_LEVEL_MINIMAL) ereport(ERROR, (errmsg("WAL streaming (max_wal_senders > 0) requires wal_level \"archive\" or \"hot_standby\""))); *** a/src/backend/storage/buffer/bufmgr.c --- b/src/backend/storage/buffer/bufmgr.c *************** *** 2626,2633 **** MarkBufferDirtyHint(Buffer buffer, bool buffer_std) bool delayChkpt = false; /* ! * If checksums are enabled, and the buffer is permanent, then a full ! * page image may be required even for some hint bit updates to * protect against torn pages. This full page image is only necessary * if the hint bit update is the first change to the page since the * last checkpoint. --- 2626,2633 ---- bool delayChkpt = false; /* ! * If checksums or logging hintbit are enabled, and the buffer is permanent, ! * then a full page image may be required even for some hint bit updates to * protect against torn pages. This full page image is only necessary * if the hint bit update is the first change to the page since the * last checkpoint. *************** *** 2635,2641 **** MarkBufferDirtyHint(Buffer buffer, bool buffer_std) * We don't check full_page_writes here because that logic is included * when we call XLogInsert() since the value changes dynamically. */ ! if (DataChecksumsEnabled() && (bufHdr->flags & BM_PERMANENT)) { /* * If we're in recovery we cannot dirty a page because of a hint. --- 2635,2641 ---- * We don't check full_page_writes here because that logic is included * when we call XLogInsert() since the value changes dynamically. */ ! if ((DataChecksumsEnabled() || enableLoggingHintbit) && (bufHdr->flags & BM_PERMANENT)) { /* * If we're in recovery we cannot dirty a page because of a hint. *** a/src/backend/utils/misc/guc.c --- b/src/backend/utils/misc/guc.c *************** *** 841,846 **** static struct config_bool ConfigureNamesBool[] = --- 841,847 ---- false, NULL, NULL, NULL }, + { {"full_page_writes", PGC_SIGHUP, WAL_SETTINGS, gettext_noop("Writes full pages to WAL when first modified after a checkpoint."), *************** *** 854,859 **** static struct config_bool ConfigureNamesBool[] = --- 855,871 ---- true, NULL, NULL, NULL }, + + { + {"enable_logging_hintbit", PGC_SIGHUP, WAL_SETTINGS, + gettext_noop("Writes hintbit log to WAL when first updated after a checkpoint"), + NULL + }, + &enableLoggingHintbit, + false, + NULL, NULL, NULL + }, + { {"log_checkpoints", PGC_SIGHUP, LOGGING_WHAT, gettext_noop("Logs each checkpoint."), *** a/src/backend/utils/misc/postgresql.conf.sample --- b/src/backend/utils/misc/postgresql.conf.sample *************** *** 181,186 **** --- 181,187 ---- # fsync_writethrough # open_sync #full_page_writes = on # recover from partial page writes + #enable_logging_hintbit = off # turns logging WAL when updating hintbit #wal_buffers = -1 # min 32kB, -1 sets based on shared_buffers # (change requires restart) #wal_writer_delay = 200ms # 1-10000 milliseconds *** a/src/bin/pg_controldata/pg_controldata.c --- b/src/bin/pg_controldata/pg_controldata.c *************** *** 291,295 **** main(int argc, char *argv[]) --- 291,297 ---- (ControlFile.float8ByVal ? _("by value") : _("by reference"))); printf(_("Data page checksum version: %u\n"), ControlFile.data_checksum_version); + printf(_("Enable logging hintbit: %u\n"), + ControlFile.enable_logging_hintbit); return 0; } *** a/src/include/access/xlog.h --- b/src/include/access/xlog.h *************** *** 189,194 **** extern bool XLogArchiveMode; --- 189,195 ---- extern char *XLogArchiveCommand; extern bool EnableHotStandby; extern bool fullPageWrites; + extern bool enableLoggingHintbit; extern bool log_checkpoints; extern int num_xloginsert_slots; *** a/src/include/access/xlog_internal.h --- b/src/include/access/xlog_internal.h *************** *** 209,214 **** typedef struct xl_parameter_change --- 209,215 ---- int max_prepared_xacts; int max_locks_per_xact; int wal_level; + bool enable_logging_hintbit; } xl_parameter_change; /* logs restore point */ *** a/src/include/catalog/pg_control.h --- b/src/include/catalog/pg_control.h *************** *** 219,224 **** typedef struct ControlFileData --- 219,227 ---- /* CRC of all above ... MUST BE LAST! */ pg_crc32 crc; + + /* Enable logging WAL when updating hintbit */ + bool enable_logging_hintbit; } ControlFileData; /*