diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index 8b9b438..02d5f4f 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -902,7 +902,8 @@ LogStandbySnapshot(void) RunningTransactions running; xl_standby_lock *locks; int nlocks; - static bool last_snapshot_overflowed = false; + static int last_running_xcnt = 0; + static TransactionId last_running_latestCompletedXid = InvalidTransactionId; Assert(XLogStandbyInfoActive()); @@ -937,22 +938,30 @@ LogStandbySnapshot(void) LWLockRelease(ProcArrayLock); /* - * Don't bother to log anything if nothing is happening, if we are - * using archive_timeout > 0 and we didn't overflow snapshot last time. + * We have a slight problem if we are running with archive_timeout, + * because generating this record causes us to do an xlog switch, which + * then generates another checkpoint and we end up generating WAL files + * on an idle system. So we would like to suppress this message type, + * but doing can cause a problem if we are streaming the WAL since it + * could leave us in state where we cannot restart a standby, hence the + * solution is to suppress idle messages only if XLogArchiveTimeout > 0 * - * This ensures that we don't issue an empty WAL record, which can - * be annoying when used in conjunction with archive timeout. + * If we are idle AND we were idle last time AND nothing has changed, + * skip logging another idle message. */ if (running->xcnt == 0 && nlocks == 0 && XLogArchiveTimeout > 0 && - !last_snapshot_overflowed) + last_running_xcnt == 0 && + last_running_latestCompletedXid == running->latestCompletedXid) { LWLockRelease(XidGenLock); return InvalidXLogRecPtr; } - last_snapshot_overflowed = running->subxid_overflow; + /* Remember values for next time */ + last_running_xcnt = running->xcnt; + last_running_latestCompletedXid = running->latestCompletedXid; } recptr = LogCurrentRunningXacts(running);