mirror of
https://github.com/postgres/postgres.git
synced 2025-11-18 02:02:55 +03:00
Add optional pid parameter to pg_replication_origin_session_setup().
Commit 216a784829 introduced parallel apply workers, allowing multiple
processes to share a replication origin. To support this,
replorigin_session_setup() was extended to accept a pid argument
identifying the process using the origin.
This commit exposes that capability through the SQL interface function
pg_replication_origin_session_setup() by adding an optional pid parameter.
This enables multiple processes to coordinate replication using the same
origin when using SQL-level replication functions.
This change allows the non-builtin logical replication solutions to
implement parallel apply for large transactions.
Additionally, an existing internal error was made user-facing, as it can
now be triggered via the exposed SQL API.
Author: Doruk Yilmaz <doruk@mixrank.com>
Author: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>
Reviewed-by: Euler Taveira <euler@eulerto.com>
Discussion: https://postgr.es/m/CAMPB6wfe4zLjJL8jiZV5kjjpwBM2=rTRme0UCL7Ra4L8MTVdOg@mail.gmail.com
Discussion: https://postgr.es/m/CAE2gYzyTSNvHY1+iWUwykaLETSuAZsCWyryokjP6rG46ZvRgQA@mail.gmail.com
This commit is contained in:
@@ -650,6 +650,13 @@ LANGUAGE INTERNAL
|
||||
CALLED ON NULL INPUT VOLATILE PARALLEL SAFE
|
||||
AS 'pg_stat_reset_slru';
|
||||
|
||||
CREATE OR REPLACE FUNCTION
|
||||
pg_replication_origin_session_setup(node_name text, pid integer DEFAULT 0)
|
||||
RETURNS void
|
||||
LANGUAGE INTERNAL
|
||||
STRICT VOLATILE PARALLEL UNSAFE
|
||||
AS 'pg_replication_origin_session_setup';
|
||||
|
||||
--
|
||||
-- The default permissions for functions mean that anyone can execute them.
|
||||
-- A number of functions shouldn't be executable by just anyone, but rather
|
||||
@@ -751,7 +758,7 @@ REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_progress(boolean) FROM
|
||||
|
||||
REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_reset() FROM public;
|
||||
|
||||
REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_setup(text) FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_replication_origin_session_setup(text, integer) FROM public;
|
||||
|
||||
REVOKE EXECUTE ON FUNCTION pg_replication_origin_xact_reset() FROM public;
|
||||
|
||||
|
||||
@@ -1167,6 +1167,14 @@ replorigin_session_setup(RepOriginId node, int acquired_by)
|
||||
curstate->roident, curstate->acquired_by)));
|
||||
}
|
||||
|
||||
else if (curstate->acquired_by != acquired_by)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_IN_USE),
|
||||
errmsg("could not find replication state slot for replication origin with OID %u which was acquired by %d",
|
||||
node, acquired_by)));
|
||||
}
|
||||
|
||||
/* ok, found slot */
|
||||
session_replication_state = curstate;
|
||||
break;
|
||||
@@ -1181,6 +1189,12 @@ replorigin_session_setup(RepOriginId node, int acquired_by)
|
||||
errhint("Increase \"max_active_replication_origins\" and try again.")));
|
||||
else if (session_replication_state == NULL)
|
||||
{
|
||||
if (acquired_by)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
errmsg("cannot use PID %d for inactive replication origin with ID %d",
|
||||
acquired_by, node)));
|
||||
|
||||
/* initialize new slot */
|
||||
session_replication_state = &replication_states[free_slot];
|
||||
Assert(session_replication_state->remote_lsn == InvalidXLogRecPtr);
|
||||
@@ -1193,9 +1207,8 @@ replorigin_session_setup(RepOriginId node, int acquired_by)
|
||||
|
||||
if (acquired_by == 0)
|
||||
session_replication_state->acquired_by = MyProcPid;
|
||||
else if (session_replication_state->acquired_by != acquired_by)
|
||||
elog(ERROR, "could not find replication state slot for replication origin with OID %u which was acquired by %d",
|
||||
node, acquired_by);
|
||||
else
|
||||
Assert(session_replication_state->acquired_by == acquired_by);
|
||||
|
||||
LWLockRelease(ReplicationOriginLock);
|
||||
|
||||
@@ -1374,12 +1387,14 @@ pg_replication_origin_session_setup(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *name;
|
||||
RepOriginId origin;
|
||||
int pid;
|
||||
|
||||
replorigin_check_prerequisites(true, false);
|
||||
|
||||
name = text_to_cstring((text *) DatumGetPointer(PG_GETARG_DATUM(0)));
|
||||
origin = replorigin_by_name(name, false);
|
||||
replorigin_session_setup(origin, 0);
|
||||
pid = PG_GETARG_INT32(1);
|
||||
replorigin_session_setup(origin, pid);
|
||||
|
||||
replorigin_session_origin = origin;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user