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.
This commit is contained in:
Andres Freund 2014-07-24 14:32:34 +02:00
parent 32d78894c2
commit 93a028f569
1 changed files with 18 additions and 4 deletions

View 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;