Skip to content

Commit 1130206

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 0fef581 commit 1130206

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
@@ -1101,6 +1101,7 @@ RestoreSlotFromDisk(const char *name)
11011101
{
11021102
ReplicationSlotOnDisk cp;
11031103
int i;
1104+
char slotdir[MAXPGPATH + 12];
11041105
char path[MAXPGPATH + 22];
11051106
int fd;
11061107
bool restored = false;
@@ -1110,13 +1111,14 @@ RestoreSlotFromDisk(const char *name)
11101111
/* no need to lock here, no concurrent access allowed yet */
11111112

11121113
/* delete temp file if it exists */
1113-
sprintf(path, "pg_replslot/%s/state.tmp", name);
1114+
sprintf(slotdir, "pg_replslot/%s", name);
1115+
sprintf(path, "%s/state.tmp", slotdir);
11141116
if (unlink(path) < 0 && errno != ENOENT)
11151117
ereport(PANIC,
11161118
(errcode_for_file_access(),
11171119
errmsg("could not remove file \"%s\": %m", path)));
11181120

1119-
sprintf(path, "pg_replslot/%s/state", name);
1121+
sprintf(path, "%s/state", slotdir);
11201122

11211123
elog(DEBUG1, "restoring replication slot from \"%s\"", path);
11221124

@@ -1149,7 +1151,7 @@ RestoreSlotFromDisk(const char *name)
11491151

11501152
/* Also sync the parent directory */
11511153
START_CRIT_SECTION();
1152-
fsync_fname(path, true);
1154+
fsync_fname(slotdir, true);
11531155
END_CRIT_SECTION();
11541156

11551157
/* read part of statefile that's guaranteed to be version independent */
@@ -1224,13 +1226,11 @@ RestoreSlotFromDisk(const char *name)
12241226
*/
12251227
if (cp.slotdata.persistency != RS_PERSISTENT)
12261228
{
1227-
sprintf(path, "pg_replslot/%s", name);
1228-
1229-
if (!rmtree(path, true))
1229+
if (!rmtree(slotdir, true))
12301230
{
12311231
ereport(WARNING,
12321232
(errcode_for_file_access(),
1233-
errmsg("could not remove directory \"%s\"", path)));
1233+
errmsg("could not remove directory \"%s\"", slotdir)));
12341234
}
12351235
fsync_fname("pg_replslot", true);
12361236
return;

0 commit comments

Comments
 (0)