Avoid archiving XLOG_RUNNING_XACTS on idle server
authorSimon Riggs <simon@2ndQuadrant.com>
Mon, 4 Apr 2016 06:18:05 +0000 (07:18 +0100)
committerSimon Riggs <simon@2ndQuadrant.com>
Mon, 4 Apr 2016 06:18:05 +0000 (07:18 +0100)
If archive_timeout > 0 we should avoid logging XLOG_RUNNING_XACTS if idle.

Bug 13685 reported by Laurence Rowe, investigated in detail by Michael Paquier,
though this is not his proposed fix.
20151016203031.3019.72930@wrigleys.postgresql.org

Simple non-invasive patch to allow later backpatch to 9.4 and 9.5

src/backend/postmaster/bgwriter.c
src/backend/storage/ipc/standby.c

index 00f03d8acbe7ba54b4fc91aa28c80f2c508850fb..654e4f8bd5762802111a5e06233862cff9c95cfa 100644 (file)
@@ -330,8 +330,11 @@ BackgroundWriterMain(void)
                        if (now >= timeout &&
                                last_snapshot_lsn != GetXLogInsertRecPtr())
                        {
-                               last_snapshot_lsn = LogStandbySnapshot();
+                               XLogRecPtr log_standby_lsn = LogStandbySnapshot();
+
                                last_snapshot_ts = now;
+                               if (!XLogRecPtrIsInvalid(log_standby_lsn))
+                                       last_snapshot_lsn = log_standby_lsn;
                        }
                }
 
index 6a9bf842d3923affc66e251dcd277afcab1ec7e9..8b9b438ca929c1cae5ced8985d91cd45e5a5d294 100644 (file)
@@ -902,6 +902,7 @@ LogStandbySnapshot(void)
        RunningTransactions running;
        xl_standby_lock *locks;
        int                     nlocks;
+       static bool last_snapshot_overflowed = false;
 
        Assert(XLogStandbyInfoActive());
 
@@ -932,8 +933,28 @@ LogStandbySnapshot(void)
         * only a shared lock.
         */
        if (wal_level < WAL_LEVEL_LOGICAL)
+       {
                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.
+                *
+                * This ensures that we don't issue an empty WAL record, which can
+                * be annoying when used in conjunction with archive timeout.
+                */
+               if (running->xcnt == 0 &&
+                       nlocks == 0 &&
+                       XLogArchiveTimeout > 0 &&
+                       !last_snapshot_overflowed)
+               {
+                       LWLockRelease(XidGenLock);
+                       return InvalidXLogRecPtr;
+               }
+
+               last_snapshot_overflowed = running->subxid_overflow;
+       }
+
        recptr = LogCurrentRunningXacts(running);
 
        /* Release lock if we kept it longer ... */