Skip to content

Commit 49bf815

Browse files
committed
Drop slot's LWLock before returning from SaveSlotToPath()
When SaveSlotToPath() is called with elevel=LOG, the early exits didn't release the slot's io_in_progress_lock. This could result in a walsender being stuck on the lock forever. A possible way to get into this situation is if the offending code paths are triggered in a low disk space situation. Author: Pavan Deolasee <pavan.deolasee@2ndquadrant.com> Reported-by: Craig Ringer <craig@2ndquadrant.com> Discussion: https://www.postgresql.org/message-id/flat/56a138c5-de61-f553-7e8f-6789296de785%402ndquadrant.com
1 parent 958aa43 commit 49bf815

File tree

1 file changed

+10
-0
lines changed

1 file changed

+10
-0
lines changed

src/backend/replication/slot.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,12 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
12561256
fd = OpenTransientFile(tmppath, O_CREAT | O_EXCL | O_WRONLY | PG_BINARY);
12571257
if (fd < 0)
12581258
{
1259+
/*
1260+
* If not an ERROR, then release the lock before returning. In case
1261+
* of an ERROR, the error recovery path automatically releases the
1262+
* lock, but no harm in explicitly releasing even in that case.
1263+
*/
1264+
LWLockRelease(&slot->io_in_progress_lock);
12591265
ereport(elevel,
12601266
(errcode_for_file_access(),
12611267
errmsg("could not create file \"%s\": %m",
@@ -1287,6 +1293,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
12871293

12881294
pgstat_report_wait_end();
12891295
CloseTransientFile(fd);
1296+
LWLockRelease(&slot->io_in_progress_lock);
12901297

12911298
/* if write didn't set errno, assume problem is no disk space */
12921299
errno = save_errno ? save_errno : ENOSPC;
@@ -1306,6 +1313,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
13061313

13071314
pgstat_report_wait_end();
13081315
CloseTransientFile(fd);
1316+
LWLockRelease(&slot->io_in_progress_lock);
13091317
errno = save_errno;
13101318
ereport(elevel,
13111319
(errcode_for_file_access(),
@@ -1317,6 +1325,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
13171325

13181326
if (CloseTransientFile(fd) != 0)
13191327
{
1328+
LWLockRelease(&slot->io_in_progress_lock);
13201329
ereport(elevel,
13211330
(errcode_for_file_access(),
13221331
errmsg("could not close file \"%s\": %m",
@@ -1327,6 +1336,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
13271336
/* rename to permanent file, fsync file and directory */
13281337
if (rename(tmppath, path) != 0)
13291338
{
1339+
LWLockRelease(&slot->io_in_progress_lock);
13301340
ereport(elevel,
13311341
(errcode_for_file_access(),
13321342
errmsg("could not rename file \"%s\" to \"%s\": %m",

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy