aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2014-07-24 14:32:34 +0200
committerAndres Freund <andres@anarazel.de>2014-07-24 14:44:45 +0200
commit93a028f569232fa498279841cb61ad11c2df5c85 (patch)
tree5bb10e79bb0b3fe1d9d30edcdae31c7434eb06e6 /src
parent32d78894c2a92cbb2fe7b9160936fee31672e7d9 (diff)
downloadpostgresql-93a028f569232fa498279841cb61ad11c2df5c85.tar.gz
postgresql-93a028f569232fa498279841cb61ad11c2df5c85.zip
Properly remove ephemeral replication slots after a crash restart.
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/replication/slot.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index 5671ac1d14f..b374c6eccf5 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -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;