diff options
author | Andres Freund <andres@anarazel.de> | 2014-07-24 14:32:34 +0200 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2014-07-24 14:44:41 +0200 |
commit | fece13d7477720bcbf02af795bed695c54d1250c (patch) | |
tree | c3e193eccfaba0474369e5ba22d735712f5a5266 /src | |
parent | 8da262879ef5e53620b9e6a0da82510d09c105cb (diff) | |
download | postgresql-fece13d7477720bcbf02af795bed695c54d1250c.tar.gz postgresql-fece13d7477720bcbf02af795bed695c54d1250c.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.c | 22 |
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; |