aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2018-09-02 12:40:58 -0700
committerMichael Paquier <michael@paquier.xyz>2018-09-02 12:40:58 -0700
commit02b1b01d8ed4fad10ad4560604dc45b06968f64a (patch)
tree07f68bafb0e9bac4a006372f6314cc56cbfd4f2a /src
parentd368c6c711d03b8bb674274b2b3653985f305248 (diff)
downloadpostgresql-02b1b01d8ed4fad10ad4560604dc45b06968f64a.tar.gz
postgresql-02b1b01d8ed4fad10ad4560604dc45b06968f64a.zip
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-
Diffstat (limited to 'src')
-rw-r--r--src/backend/replication/slot.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index b42861d6259..aff100b192a 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -1103,6 +1103,7 @@ RestoreSlotFromDisk(const char *name)
{
ReplicationSlotOnDisk cp;
int i;
+ char slotdir[MAXPGPATH + 12];
char path[MAXPGPATH + 22];
int fd;
bool restored = false;
@@ -1112,13 +1113,14 @@ RestoreSlotFromDisk(const char *name)
/* no need to lock here, no concurrent access allowed yet */
/* delete temp file if it exists */
- sprintf(path, "pg_replslot/%s/state.tmp", name);
+ sprintf(slotdir, "pg_replslot/%s", name);
+ sprintf(path, "%s/state.tmp", slotdir);
if (unlink(path) < 0 && errno != ENOENT)
ereport(PANIC,
(errcode_for_file_access(),
errmsg("could not remove file \"%s\": %m", path)));
- sprintf(path, "pg_replslot/%s/state", name);
+ sprintf(path, "%s/state", slotdir);
elog(DEBUG1, "restoring replication slot from \"%s\"", path);
@@ -1151,7 +1153,7 @@ RestoreSlotFromDisk(const char *name)
/* Also sync the parent directory */
START_CRIT_SECTION();
- fsync_fname(path, true);
+ fsync_fname(slotdir, true);
END_CRIT_SECTION();
/* read part of statefile that's guaranteed to be version independent */
@@ -1226,13 +1228,11 @@ RestoreSlotFromDisk(const char *name)
*/
if (cp.slotdata.persistency != RS_PERSISTENT)
{
- sprintf(path, "pg_replslot/%s", name);
-
- if (!rmtree(path, true))
+ if (!rmtree(slotdir, true))
{
ereport(WARNING,
(errcode_for_file_access(),
- errmsg("could not remove directory \"%s\"", path)));
+ errmsg("could not remove directory \"%s\"", slotdir)));
}
fsync_fname("pg_replslot", true);
return;