postgres.git / summary / log / commit / refs

commit    504f059f5a198cff558e1c95a55aa63e03e2c3a8
Author:   Michael Paquier <michael@paquier.xyz>
Date:     Sun Sep 02 19:40:45 2018 +0000
First released in: 12.0, 9.4.20, 9.5.15, 9.6.11, 10.6, 11.0

    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-


src/backend/replication/slot.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index 17e00c4d5c6..9c05dabaf7a 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -1346,6 +1346,7 @@ RestoreSlotFromDisk(const char *name) { ReplicationSlotOnDisk cp; int i; + char slotdir[MAXPGPATH + 12]; char path[MAXPGPATH + 22]; int fd; bool restored = false; @@ -1355,13 +1356,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); @@ -1396,7 +1398,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 */ @@ -1475,13 +1477,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; [parent: 9b0c58e6d43a]