Skip to content

Commit 504f059

Browse files
committed
Fix initial sync of slot parent directory when restoring status
At the beginning of recovery, information from replication slots is recovered from disk to memory. In order to ensure the durability of the information, the status file as well as its parent directory are synced. It happens that the sync on the parent directory was done directly using the status file path, which is logically incorrect, and the current code has been doing a sync on the same object twice in a row. Reported-by: Konstantin Knizhnik Diagnosed-by: Konstantin Knizhnik Author: Michael Paquier Discussion: https://postgr.es/m/9eb1a6d5-b66f-2640-598d-c5ea46b8f68a@postgrespro.ru Backpatch-through: 9.4-
1 parent 9b0c58e commit 504f059

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

src/backend/replication/slot.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,7 @@ RestoreSlotFromDisk(const char *name)
13461346
{
13471347
ReplicationSlotOnDisk cp;
13481348
int i;
1349+
char slotdir[MAXPGPATH + 12];
13491350
char path[MAXPGPATH + 22];
13501351
int fd;
13511352
bool restored = false;
@@ -1355,13 +1356,14 @@ RestoreSlotFromDisk(const char *name)
13551356
/* no need to lock here, no concurrent access allowed yet */
13561357

13571358
/* delete temp file if it exists */
1358-
sprintf(path, "pg_replslot/%s/state.tmp", name);
1359+
sprintf(slotdir, "pg_replslot/%s", name);
1360+
sprintf(path, "%s/state.tmp", slotdir);
13591361
if (unlink(path) < 0 && errno != ENOENT)
13601362
ereport(PANIC,
13611363
(errcode_for_file_access(),
13621364
errmsg("could not remove file \"%s\": %m", path)));
13631365

1364-
sprintf(path, "pg_replslot/%s/state", name);
1366+
sprintf(path, "%s/state", slotdir);
13651367

13661368
elog(DEBUG1, "restoring replication slot from \"%s\"", path);
13671369

@@ -1396,7 +1398,7 @@ RestoreSlotFromDisk(const char *name)
13961398

13971399
/* Also sync the parent directory */
13981400
START_CRIT_SECTION();
1399-
fsync_fname(path, true);
1401+
fsync_fname(slotdir, true);
14001402
END_CRIT_SECTION();
14011403

14021404
/* read part of statefile that's guaranteed to be version independent */
@@ -1475,13 +1477,11 @@ RestoreSlotFromDisk(const char *name)
14751477
*/
14761478
if (cp.slotdata.persistency != RS_PERSISTENT)
14771479
{
1478-
sprintf(path, "pg_replslot/%s", name);
1479-
1480-
if (!rmtree(path, true))
1480+
if (!rmtree(slotdir, true))
14811481
{
14821482
ereport(WARNING,
14831483
(errcode_for_file_access(),
1484-
errmsg("could not remove directory \"%s\"", path)));
1484+
errmsg("could not remove directory \"%s\"", slotdir)));
14851485
}
14861486
fsync_fname("pg_replslot", true);
14871487
return;

0 commit comments

Comments
 (0)