From be7ff5eb7b962efd53fa6a22b6ec8329910de0eb Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Fri, 5 Feb 2021 14:57:33 +1100 Subject: [PATCH v2] replorigin_drop_by_name. Drop the origin by name as a single operation. The whole function is locked to prevent concurrent drops. Discussion: https://www.postgresql.org/message-id/CAHut%2BPuW8DWV5fskkMWWMqzt-x7RPcNQOtJQBp6SdwyRghCk7A%40mail.gmail.com --- src/backend/replication/logical/origin.c | 72 +++++++++++++++++++++++--------- src/include/replication/origin.h | 1 + 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index 9bd761a..2cd226b 100644 --- a/src/backend/replication/logical/origin.c +++ b/src/backend/replication/logical/origin.c @@ -324,25 +324,14 @@ replorigin_create(char *roname) /* - * Drop replication origin. - * - * Needs to be called in a transaction. + * Common code to drop a replication origin. */ -void -replorigin_drop(RepOriginId roident, bool nowait) +static void +replorigin_drop_guts(Relation rel, RepOriginId roident, bool nowait) { HeapTuple tuple; - Relation rel; int i; - Assert(IsTransactionState()); - - /* - * To interlock against concurrent drops, we hold ExclusiveLock on - * pg_replication_origin throughout this function. - */ - rel = table_open(ReplicationOriginRelationId, ExclusiveLock); - /* * First, clean up the slot state info, if there is any matching slot. */ @@ -415,6 +404,55 @@ restart: ReleaseSysCache(tuple); CommandCounterIncrement(); +} + +/* + * Drop replication origin (by name). + * + * Needs to be called in a transaction. + */ +void +replorigin_drop_by_name(char *name, bool missing_ok, bool nowait) +{ + RepOriginId roident; + Relation rel; + + Assert(IsTransactionState()); + + /* + * To interlock against concurrent drops, we hold ExclusiveLock on + * pg_replication_origin throughout this function. + */ + rel = table_open(ReplicationOriginRelationId, ExclusiveLock); + + roident = replorigin_by_name(name, missing_ok); + + if (OidIsValid(roident)) + replorigin_drop_guts(rel, roident, nowait); + + /* now release lock again */ + table_close(rel, ExclusiveLock); +} + +/* + * Drop replication origin (by id). + * + * Needs to be called in a transaction. + */ +void +replorigin_drop(RepOriginId roident, bool nowait) +{ + Relation rel; + + Assert(IsTransactionState()); + + /* + * To interlock against concurrent drops, we hold ExclusiveLock on + * pg_replication_origin throughout this function. + */ + rel = table_open(ReplicationOriginRelationId, ExclusiveLock); + + replorigin_drop_guts(rel, roident, nowait); /* now release lock again */ table_close(rel, ExclusiveLock); @@ -1256,16 +1294,12 @@ Datum pg_replication_origin_drop(PG_FUNCTION_ARGS) { char *name; - RepOriginId roident; replorigin_check_prerequisites(false, false); name = text_to_cstring((text *) DatumGetPointer(PG_GETARG_DATUM(0))); - roident = replorigin_by_name(name, false); - Assert(OidIsValid(roident)); - - replorigin_drop(roident, true); + replorigin_drop_by_name(name, false /* missing_ok */, true /* nowait */); pfree(name); diff --git a/src/include/replication/origin.h b/src/include/replication/origin.h index 731445a..e13c238 100644 --- a/src/include/replication/origin.h +++ b/src/include/replication/origin.h @@ -41,6 +41,7 @@ extern PGDLLIMPORT TimestampTz replorigin_session_origin_timestamp; extern RepOriginId replorigin_by_name(char *name, bool missing_ok); extern RepOriginId replorigin_create(char *name); extern void replorigin_drop(RepOriginId roident, bool nowait); +extern void replorigin_drop_by_name(char *name, bool missing_ok, bool nowait); extern bool replorigin_by_oid(RepOriginId roident, bool missing_ok, char **roname); -- 1.8.3.1