v1-0001-Fix-stuck-shutdown-due-to-unflushed-records.patch

application/octet-stream

Filename: v1-0001-Fix-stuck-shutdown-due-to-unflushed-records.patch
Type: application/octet-stream
Part: 0
Message: Shutdown indefinitely stuck due to unflushed FPI_FOR_HINT record

Patch

Format: format-patch
Series: patch v1-0001
Subject: Fix stuck shutdown due to unflushed records
File+
src/backend/access/transam/xlog.c 11 0
From f62b6b45594b4d58ffe739ca42ecd3aca6605c4c Mon Sep 17 00:00:00 2001
From: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Date: Fri, 20 Feb 2026 18:15:12 +0100
Subject: Fix stuck shutdown due to unflushed records

Shutdown sequence may be stuck indefinitely under the following
circumstances:
- Data checksums is enabled
- A logical replication walsender is running
- A select in an explicit ongoing transaction pruned a heap page and
  logged a FPI_FOR_HINT record. This record is likely going to be a
  contrecord and start a new page.

Starting the shutdown will kill this ongoing transaction. Since the
transaction doesn't have an allocated xid, the FPI_FOR_HINT record will
be left unflushed.

When the checkpointer starts ShutdownXLOG(), all walsenders will be
notified to stop. However, the logical replication walsender will be
stuck in an infinite loop, trying to read this unflushed record, never
reaching the stop state and blocking the whole shutdown sequence.

This patch fixes the issue by flushing all records before signaling
walsenders to stop.
---
 src/backend/access/transam/xlog.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 13ec6225b85..aa490176aaf 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -6727,6 +6727,8 @@ GetLastSegSwitchData(XLogRecPtr *lastSwitchLSN)
 void
 ShutdownXLOG(int code, Datum arg)
 {
+	XLogRecPtr	WriteRqstPtr;
+
 	/*
 	 * We should have an aux process resource owner to use, and we should not
 	 * be in a transaction that's installed some other resowner.
@@ -6740,6 +6742,15 @@ ShutdownXLOG(int code, Datum arg)
 	ereport(IsPostmasterEnvironment ? LOG : NOTICE,
 			(errmsg("shutting down")));
 
+	/*
+	 * We may have unflushed records, make sure everything is flushed before
+	 * stopping the walsenders.
+	 */
+	SpinLockAcquire(&XLogCtl->info_lck);
+	WriteRqstPtr = XLogCtl->LogwrtRqst.Write;
+	SpinLockRelease(&XLogCtl->info_lck);
+	XLogFlush(WriteRqstPtr);
+
 	/*
 	 * Signal walsenders to move to stopping state.
 	 */
-- 
2.52.0