1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-21 10:42:50 +03:00

Cleanup slots during drop database

Automatically drop all logical replication slots associated with a
database when the database is dropped. Previously we threw an ERROR
if a slot existed. Now we throw ERROR only if a slot is active in
the database being dropped.

Craig Ringer
This commit is contained in:
Simon Riggs
2017-03-28 10:05:21 -04:00
parent 4d33a7f2e7
commit ff539da316
7 changed files with 182 additions and 14 deletions

View File

@@ -845,19 +845,22 @@ dropdb(const char *dbname, bool missing_ok)
errmsg("cannot drop the currently open database")));
/*
* Check whether there are, possibly unconnected, logical slots that refer
* to the to-be-dropped database. The database lock we are holding
* prevents the creation of new slots using the database.
* Check whether there are active logical slots that refer to the
* to-be-dropped database. The database lock we are holding prevents the
* creation of new slots using the database or existing slots becoming
* active.
*/
if (ReplicationSlotsCountDBSlots(db_id, &nslots, &nslots_active))
(void) ReplicationSlotsCountDBSlots(db_id, &nslots, &nslots_active);
if (nslots_active)
{
ereport(ERROR,
(errcode(ERRCODE_OBJECT_IN_USE),
errmsg("database \"%s\" is used by a logical replication slot",
errmsg("database \"%s\" is used by an active logical replication slot",
dbname),
errdetail_plural("There is %d slot, %d of them active.",
"There are %d slots, %d of them active.",
nslots,
nslots, nslots_active)));
errdetail_plural("There is %d active slot",
"There are %d active slots",
nslots_active, nslots_active)));
}
/*
* Check for other backends in the target database. (Because we hold the
@@ -914,6 +917,11 @@ dropdb(const char *dbname, bool missing_ok)
*/
dropDatabaseDependencies(db_id);
/*
* Drop db-specific replication slots.
*/
ReplicationSlotsDropDBSlots(db_id);
/*
* Drop pages for this database that are in the shared buffer cache. This
* is important to ensure that no remaining backend tries to write out a
@@ -2124,11 +2132,17 @@ dbase_redo(XLogReaderState *record)
* InitPostgres() cannot fully re-execute concurrently. This
* avoids backends re-connecting automatically to same database,
* which can happen in some cases.
*
* This will lock out walsenders trying to connect to db-specific
* slots for logical decoding too, so it's safe for us to drop slots.
*/
LockSharedObjectForSession(DatabaseRelationId, xlrec->db_id, 0, AccessExclusiveLock);
ResolveRecoveryConflictWithDatabase(xlrec->db_id);
}
/* Drop any database-specific replication slots */
ReplicationSlotsDropDBSlots(xlrec->db_id);
/* Drop pages for this database that are in the shared buffer cache */
DropDatabaseBuffers(xlrec->db_id);