v4-0002-Handle-corner-cases-related-with-origin.patch
application/octet-stream
Filename: v4-0002-Handle-corner-cases-related-with-origin.patch
Type: application/octet-stream
Part: 1
Patch
Format: format-patch
Series: patch v4-0002
Subject: Handle corner cases related with origin
| File | + | − |
|---|---|---|
| src/backend/replication/logical/origin.c | 19 | 4 |
From 7ba371e30e4b2c13734a2dfeee3cf06d41ab1c1d Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <kuroda.hayato@fujitsu.com>
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