From 7ba371e30e4b2c13734a2dfeee3cf06d41ab1c1d Mon Sep 17 00:00:00 2001 From: Hayato Kuroda Date: Fri, 9 Jan 2026 19:31:57 +0900 Subject: [PATCH v4 2/2] Handle corner cases related with origin The attribute acquired_by can still be 0 while processes are acquiring the origin. This can happen if the first process exits while holding the origin. This commit handles corner cases related to it: - rejects acquiring origin if it does not have a valid acquired_by but counter > 0. - ensures origins cannot be dropped if the counter > 0. --- src/backend/replication/logical/origin.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c index 389d2b38d20..b9132b3475d 100644 --- a/src/backend/replication/logical/origin.c +++ b/src/backend/replication/logical/origin.c @@ -386,16 +386,19 @@ restart: if (state->roident == roident) { /* found our slot, is it busy? */ - if (state->acquired_by != 0) + if (state->refcount > 0) { ConditionVariable *cv; if (nowait) ereport(ERROR, (errcode(ERRCODE_OBJECT_IN_USE), - errmsg("could not drop replication origin with ID %d, in use by PID %d", - state->roident, - state->acquired_by))); + (state->acquired_by != 0) + ? errmsg("could not drop replication origin with ID %d, in use by PID %d", + state->roident, + state->acquired_by) + : errmsg("could not drop replication origin with ID %d, in use by another process", + state->roident))); /* * We must wait and then retry. Since we don't know which CV @@ -1192,6 +1195,18 @@ replorigin_session_setup(RepOriginId node, int acquired_by) node, acquired_by))); } + /* + * PID was not noted in the origin. This can happen the process + * originally acquired the origin exits without releasing. To make the + * staus clean again, other processes cannot acquire the origin till + * all using ones release. + */ + else if (curstate->acquired_by == 0 && curstate->refcount > 0) + ereport(ERROR, + (errcode(ERRCODE_OBJECT_IN_USE), + errmsg("replication origin with ID %d is already active in another process", + curstate->roident))); + /* ok, found slot */ session_replication_state = curstate; break; -- 2.47.3