mirror of
https://github.com/postgres/postgres.git
synced 2025-08-31 17:02:12 +03:00
Skip checkpoints, archiving on idle systems.
Some background activity (like checkpoints, archive timeout, standby snapshots) is not supposed to happen on an idle system. Unfortunately so far it was not easy to determine when a system is idle, which defeated some of the attempts to avoid redundant activity on an idle system. To make that easier, allow to make individual WAL insertions as not being "important". By checking whether any important activity happened since the last time an activity was performed, it now is easy to check whether some action needs to be repeated. Use the new facility for checkpoints, archive timeout and standby snapshots. The lack of a facility causes some issues in older releases, but in my opinion the consequences (superflous checkpoints / archived segments) aren't grave enough to warrant backpatching. Author: Michael Paquier, editorialized by Andres Freund Reviewed-By: Andres Freund, David Steele, Amit Kapila, Kyotaro HORIGUCHI Bug: #13685 Discussion: https://www.postgresql.org/message-id/20151016203031.3019.72930@wrigleys.postgresql.org https://www.postgresql.org/message-id/CAB7nPqQcPqxEM3S735Bd2RzApNqSNJVietAC=6kfkYv_45dKwA@mail.gmail.com Backpatch: -
This commit is contained in:
@@ -310,7 +310,7 @@ BackgroundWriterMain(void)
|
||||
* check whether there has been any WAL inserted since the last time
|
||||
* we've logged a running xacts.
|
||||
*
|
||||
* We do this logging in the bgwriter as its the only process that is
|
||||
* We do this logging in the bgwriter as it is the only process that is
|
||||
* run regularly and returns to its mainloop all the time. E.g.
|
||||
* Checkpointer, when active, is barely ever in its mainloop and thus
|
||||
* makes it hard to log regularly.
|
||||
@@ -324,11 +324,11 @@ BackgroundWriterMain(void)
|
||||
LOG_SNAPSHOT_INTERVAL_MS);
|
||||
|
||||
/*
|
||||
* only log if enough time has passed and some xlog record has
|
||||
* been inserted.
|
||||
* Only log if enough time has passed and interesting records have
|
||||
* been inserted since the last snapshot.
|
||||
*/
|
||||
if (now >= timeout &&
|
||||
last_snapshot_lsn != GetXLogInsertRecPtr())
|
||||
last_snapshot_lsn < GetLastImportantRecPtr())
|
||||
{
|
||||
last_snapshot_lsn = LogStandbySnapshot();
|
||||
last_snapshot_ts = now;
|
||||
|
@@ -573,15 +573,21 @@ CheckpointerMain(void)
|
||||
/*
|
||||
* CheckArchiveTimeout -- check for archive_timeout and switch xlog files
|
||||
*
|
||||
* This will switch to a new WAL file and force an archive file write
|
||||
* if any activity is recorded in the current WAL file, including just
|
||||
* a single checkpoint record.
|
||||
* This will switch to a new WAL file and force an archive file write if
|
||||
* meaningful activity is recorded in the current WAL file. This includes most
|
||||
* writes, including just a single checkpoint record, but excludes WAL records
|
||||
* that were inserted with the XLOG_MARK_UNIMPORTANT flag being set (like
|
||||
* snapshots of running transactions). Such records, depending on
|
||||
* configuration, occur on regular intervals and don't contain important
|
||||
* information. This avoids generating archives with a few unimportant
|
||||
* records.
|
||||
*/
|
||||
static void
|
||||
CheckArchiveTimeout(void)
|
||||
{
|
||||
pg_time_t now;
|
||||
pg_time_t last_time;
|
||||
XLogRecPtr last_switch_lsn;
|
||||
|
||||
if (XLogArchiveTimeout <= 0 || RecoveryInProgress())
|
||||
return;
|
||||
@@ -596,26 +602,33 @@ CheckArchiveTimeout(void)
|
||||
* Update local state ... note that last_xlog_switch_time is the last time
|
||||
* a switch was performed *or requested*.
|
||||
*/
|
||||
last_time = GetLastSegSwitchTime();
|
||||
last_time = GetLastSegSwitchData(&last_switch_lsn);
|
||||
|
||||
last_xlog_switch_time = Max(last_xlog_switch_time, last_time);
|
||||
|
||||
/* Now we can do the real check */
|
||||
/* Now we can do the real checks */
|
||||
if ((int) (now - last_xlog_switch_time) >= XLogArchiveTimeout)
|
||||
{
|
||||
XLogRecPtr switchpoint;
|
||||
|
||||
/* OK, it's time to switch */
|
||||
switchpoint = RequestXLogSwitch();
|
||||
|
||||
/*
|
||||
* If the returned pointer points exactly to a segment boundary,
|
||||
* assume nothing happened.
|
||||
* Switch segment only when "important" WAL has been logged since the
|
||||
* last segment switch.
|
||||
*/
|
||||
if ((switchpoint % XLogSegSize) != 0)
|
||||
ereport(DEBUG1,
|
||||
(errmsg("transaction log switch forced (archive_timeout=%d)",
|
||||
XLogArchiveTimeout)));
|
||||
if (GetLastImportantRecPtr() > last_switch_lsn)
|
||||
{
|
||||
XLogRecPtr switchpoint;
|
||||
|
||||
/* mark switch as unimportant, avoids triggering checkpoints */
|
||||
switchpoint = RequestXLogSwitch(true);
|
||||
|
||||
/*
|
||||
* If the returned pointer points exactly to a segment boundary,
|
||||
* assume nothing happened.
|
||||
*/
|
||||
if ((switchpoint % XLogSegSize) != 0)
|
||||
ereport(DEBUG1,
|
||||
(errmsg("transaction log switch forced (archive_timeout=%d)",
|
||||
XLogArchiveTimeout)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Update state in any case, so we don't retry constantly when the
|
||||
|
Reference in New Issue
Block a user