From: Kevin K Biju <kevinkbiju@gmail.com>
To: pgsql-hackers@lists.postgresql.org
Subject: Replace O_EXCL with O_TRUNC for creation of state.tmp in SaveSlotToPath
Date: Tue, 30 Sep 2025 17:21:05 +0530
Message-ID: <CAM45KeHa32soKL_G8Vk38CWvTBeOOXcsxAPAs7Jt7yPRf2mbVA@mail.gmail.com> (raw)
Hi,
We have encountered a few instances where logical replication errors out
during SaveSlotToPath() after creating the state.tmp file, but before it
was renamed (due to ENOSPC, for example). In these cases, since state.tmp
is not cleaned up and is created with the O_EXCL flag, further invocations
of SaveSlotToPath() for this slot will error out on OpenTransientFile()
with EEXIST, completely blocking slot metadata persistence. The only
explicit cleanup for state.tmp occurs during server startup as part of
RestoreSlotFromDisk().
It doesn't seem that this function relies on data written to state.tmp
previously, so O_EXCL is unnecessary. Attaching a patch that swaps O_EXCL
for O_TRUNC, ensuring a fresh state.tmp is available for writing.
Thanks,
Kevin
Attachments:replslot_state_tmp_otrunc.patch (application/octet-stream, 532B) downloaddiff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.cindex fd0fdb96d42..edd9f844f23 100644--- a/src/backend/replication/slot.c+++ b/src/backend/replication/slot.c@@ -2332,7 +2332,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
sprintf(tmppath, "%s/state.tmp", dir);
sprintf(path, "%s/state", dir);
- fd = OpenTransientFile(tmppath, O_CREAT | O_EXCL | O_WRONLY | PG_BINARY);+ fd = OpenTransientFile(tmppath, O_CREAT | O_TRUNC | O_WRONLY | PG_BINARY);
if (fd < 0)
{
/*
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: kevinkbiju@gmail.com, pgsql-hackers@lists.postgresql.org
Subject: Re: Replace O_EXCL with O_TRUNC for creation of state.tmp in SaveSlotToPath
In-Reply-To: <CAM45KeHa32soKL_G8Vk38CWvTBeOOXcsxAPAs7Jt7yPRf2mbVA@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox