Properly remove ephemeral replication slots after a crash restart.
authorAndres Freund <andres@anarazel.de>
Thu, 24 Jul 2014 12:32:34 +0000 (14:32 +0200)
committerAndres Freund <andres@anarazel.de>
Thu, 24 Jul 2014 12:44:45 +0000 (14:44 +0200)
Ephemeral slots - slots that shouldn't survive database restarts -
weren't properly cleaned up after a immediate/crash restart. They were
ignored in the sense that they weren't restored into memory and thus
didn't cause unwanted resource retention; but they prevented a new
slot with the same name from being created.

Now ephemeral slots are fully removed during startup.

Backpatch to 9.4 where replication slots where added.

src/backend/replication/slot.c

index 5671ac1d14fdb4368e71a27a3cca7203106d55a0..b374c6eccf501b3f1176ad113a21b2411fd0be5b 100644 (file)
@@ -1192,6 +1192,24 @@ RestoreSlotFromDisk(const char *name)
                (errmsg("replication slot file %s: checksum mismatch, is %u, should be %u",
                        path, checksum, cp.checksum)));
 
+   /*
+    * If we crashed with an ephemeral slot active, don't restore but delete
+    * it.
+    */
+   if (cp.slotdata.persistency != RS_PERSISTENT)
+   {
+       sprintf(path, "pg_replslot/%s", name);
+
+       if (!rmtree(path, true))
+       {
+           ereport(WARNING,
+                   (errcode_for_file_access(),
+                    errmsg("could not remove directory \"%s\"", path)));
+       }
+       fsync_fname("pg_replslot", true);
+       return;
+   }
+
    /* nothing can be active yet, don't lock anything */
    for (i = 0; i < max_replication_slots; i++)
    {
@@ -1206,10 +1224,6 @@ RestoreSlotFromDisk(const char *name)
        memcpy(&slot->data, &cp.slotdata,
               sizeof(ReplicationSlotPersistentData));
 
-       /* Don't restore the slot if it's not parked as persistent. */
-       if (slot->data.persistency != RS_PERSISTENT)
-           return;
-
        /* initialize in memory state */
        slot->effective_xmin = cp.slotdata.xmin;
        slot->effective_catalog_xmin = cp.slotdata.catalog_xmin;