/* * pg_switch_xlog: switch to next xlog file */ Datum pg_switch_xlog(PG_FUNCTION_ARGS) { XLogRecPtr switchpoint; char location[MAXFNAMELEN]; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to switch transaction log files")))); if (RecoveryInProgress()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is in progress"), errhint("WAL control functions cannot be executed during recovery."))); switchpoint = RequestXLogSwitch(); /* * As a convenience, return the WAL location of the switch record */ snprintf(location, sizeof(location), "%X/%X", switchpoint.xlogid, switchpoint.xrecoff); PG_RETURN_TEXT_P(cstring_to_text(location)); }
/* * CheckArchiveTimeout -- check for archive_timeout and switch xlog files * * 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; now = (pg_time_t) time(NULL); /* First we do a quick check using possibly-stale local state. */ if ((int) (now - last_xlog_switch_time) < XLogArchiveTimeout) return; /* * Update local state ... note that last_xlog_switch_time is the last time * a switch was performed *or requested*. */ last_time = GetLastSegSwitchData(&last_switch_lsn); last_xlog_switch_time = Max(last_xlog_switch_time, last_time); /* Now we can do the real checks */ if ((int) (now - last_xlog_switch_time) >= XLogArchiveTimeout) { /* * Switch segment only when "important" WAL has been logged since the * last segment switch (last_switch_lsn points to end of segment * switch occurred in). */ 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) elog(DEBUG1, "write-ahead log switch forced (archive_timeout=%d)", XLogArchiveTimeout); } /* * Update state in any case, so we don't retry constantly when the * system is idle. */ last_xlog_switch_time = now; } }
/* * 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. */ static void CheckArchiveTimeout(void) { pg_time_t now; pg_time_t last_time; if (XLogArchiveTimeout <= 0 || RecoveryInProgress()) return; now = (pg_time_t) time(NULL); /* First we do a quick check using possibly-stale local state. */ if ((int) (now - last_xlog_switch_time) < XLogArchiveTimeout) return; /* * Update local state ... note that last_xlog_switch_time is the last time * a switch was performed *or requested*. */ last_time = GetLastSegSwitchTime(); last_xlog_switch_time = Max(last_xlog_switch_time, last_time); /* Now we can do the real check */ 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. */ 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 * system is idle. */ last_xlog_switch_time = now; } }
/* * pg_switch_xlog: switch to next xlog file * * Permission checking for this function is managed through the normal * GRANT system. */ Datum pg_switch_xlog(PG_FUNCTION_ARGS) { XLogRecPtr switchpoint; if (RecoveryInProgress()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("recovery is in progress"), errhint("WAL control functions cannot be executed during recovery."))); switchpoint = RequestXLogSwitch(); /* * As a convenience, return the WAL location of the switch record */ PG_RETURN_LSN(switchpoint); }