From 5fd34ffd7e2afd3a3a8d4e655a9df46f3057ea3b Mon Sep 17 00:00:00 2001
From: usernamedt <usernamedt@yandex-team.com>
Date: Wed, 25 Oct 2023 17:09:52 +0200
Subject: [PATCH] Cleanup old files if checkpoint is skipped

Currently, if Postgres has nothing to write, it would skip the checkpoint creation defined by the checkpoint timeout setting. However, we might face a temporary archiving problem (for example, some network issues) that might lead to a pile of wal files stuck in pg_wal. After this temporary issue has gone, we would still be unable to archive them since we effectively skip the checkpoint because we have nothing to write.

This commit adds logic to clean up the old WAL segments even if checkpoint is skipped.
---
 src/backend/access/transam/xlog.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index b541be8eec2..36a12dbb2ad 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6625,6 +6625,22 @@ CreateCheckPoint(int flags)
 			END_CRIT_SECTION();
 			ereport(DEBUG1,
 					(errmsg_internal("checkpoint skipped because system is idle")));
+
+			/*
+			 * We still might want to remove some old xlog files. For example,
+			 * if there was a temporary archiving problem so we could not remove
+			 * them at the previous checkpoint but now we can actually do that.
+			 */
+			XLByteToSeg(last_important_lsn, _logSegNo, wal_segment_size);
+			KeepLogSeg(last_important_lsn, &_logSegNo);
+			_logSegNo--;
+			RemoveOldXlogFiles(_logSegNo, RedoRecPtr, last_important_lsn, ControlFile->checkPointCopy.ThisTimeLineID);
+
+			/*
+			 * Make more log segments if needed.  (Do this after recycling old log
+			 * segments, since that may supply some of the needed files.)
+			 */
+			PreallocXlogFiles(last_important_lsn, ControlFile->checkPointCopy.ThisTimeLineID);
 			return;
 		}
 	}
-- 
2.39.1

