Thread

Commits

  1. Refactor replorigin_session_setup() for better readability.

  2. Prevent unintended dropping of active replication origins.

  3. Add optional pid parameter to pg_replication_origin_session_setup().

  1. [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2024-08-12T18:43:48Z

    Hello all,
    While working on our internal tools that utilise replication, we
    realised that a new parameter was added to the internal C function
    corresponding to pg_replication_origin_session_setup.
    However this parameter wasn't included in the user-facing API [1].
    
    In 'src/backend/replication/logical/origin.c' at line 1359,
    pg_replication_origin_session_setup function calls
    
        replorigin_session_setup(origin, 0);
    
    where currently 0 is assigned to the acquired_by parameter of the
    replorigin_session_setup.
    
    I made this patch to the master which adds a way to control this
    parameter by adding a new version of the
    pg_replication_origin_session_setup function with user facing
    parameters 'text int4' in place of the current 'text' while keeping
    the existing variant
    (ensuring backwards compatibility). Could someone take a look at it?
    
    [1]: https://www.postgresql.org/docs/current/functions-admin.html#PG-REPLICATION-ORIGIN-SESSION-SETUP
    ---
    
    Thanks for the help,
    Doruk Yılmaz
    
  2. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Euler Taveira <euler@eulerto.com> — 2024-08-12T21:48:17Z

    On Mon, Aug 12, 2024, at 3:43 PM, Doruk Yilmaz wrote:
    > Hello all,
    
    Hi!
    
    > While working on our internal tools that utilise replication, we
    > realised that a new parameter was added to the internal C function
    > corresponding to pg_replication_origin_session_setup.
    > However this parameter wasn't included in the user-facing API [1].
    
    I'm curious about your use case. Is it just because the internal function has a
    different signature or your tool is capable of apply logical replication changes
    in parallel using the SQL API?
    
    > I made this patch to the master which adds a way to control this
    > parameter by adding a new version of the
    > pg_replication_origin_session_setup function with user facing
    > parameters 'text int4' in place of the current 'text' while keeping
    > the existing variant
    > (ensuring backwards compatibility). Could someone take a look at it?
    
    I did a quick look at your patch and have a few suggestions.
    
    * no documentation changes. Since the function you are changing has a new
    signature, this change should be reflected in the documentation.
    * no need for a new internal function. The second parameter (PID) can be
    optional and defaults to 0 in this case. See how we changed the
    pg_create_logical_replication_slot along the years add some IN parameters like
    twophase and failover in the recent versions.
    * add a CF entry [1] for this patch so we don't forget it. Another advantage is
    that this patch is covered by CI [2][3].
    
    
    [1] https://commitfest.postgresql.org/49/
    [2] https://wiki.postgresql.org/wiki/Cfbot
    [3] http://cfbot.cputube.org/index.html
    
    
    --
    Euler Taveira
    EDB   https://www.enterprisedb.com/
    
  3. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2024-08-15T20:53:17Z

    Hello again,
    
    On Tue, Aug 13, 2024 at 12:48 AM Euler Taveira <euler@eulerto.com> wrote:
    > I'm curious about your use case. Is it just because the internal function has a
    > different signature or your tool is capable of apply logical replication changes
    > in parallel using the SQL API?
    
    The latter is correct, it applies logical replication changes in parallel.
    Since multiple connections may commit, we need all of them to be able
    to advance the replication origin.
    
    > * no documentation changes. Since the function you are changing has a new
    > signature, this change should be reflected in the documentation.
    > * no need for a new internal function. The second parameter (PID) can be
    > optional and defaults to 0 in this case. See how we changed the
    > pg_create_logical_replication_slot along the years add some IN parameters like
    > twophase and failover in the recent versions.
    
    I updated/rewrote the patch to reflect these suggestions.
    It now has the same DEFAULT 0 style used in pg_create_logical_replication_slot.
    I also updated the documentation.
    
    > * add a CF entry [1] for this patch so we don't forget it. Another advantage is
    > that this patch is covered by CI [2][3].
    Sadly I still can't log in to the Commitfest due to the cool-off
    period. I will create an entry as soon as this period ends.
    
    Thanks for all the feedback,
    Doruk Yılmaz
    
  4. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Euler Taveira <euler@eulerto.com> — 2025-01-08T21:55:45Z

    On Thu, Aug 15, 2024, at 5:53 PM, Doruk Yilmaz wrote:
    > Hello again,
    > 
    > On Tue, Aug 13, 2024 at 12:48 AM Euler Taveira <euler@eulerto.com> wrote:
    > > I'm curious about your use case. Is it just because the internal function has a
    > > different signature or your tool is capable of apply logical replication changes
    > > in parallel using the SQL API?
    > 
    > The latter is correct, it applies logical replication changes in parallel.
    > Since multiple connections may commit, we need all of them to be able
    > to advance the replication origin.
    > 
    > > * no documentation changes. Since the function you are changing has a new
    > > signature, this change should be reflected in the documentation.
    > > * no need for a new internal function. The second parameter (PID) can be
    > > optional and defaults to 0 in this case. See how we changed the
    > > pg_create_logical_replication_slot along the years add some IN parameters like
    > > twophase and failover in the recent versions.
    > 
    > I updated/rewrote the patch to reflect these suggestions.
    > It now has the same DEFAULT 0 style used in pg_create_logical_replication_slot.
    > I also updated the documentation.
    
    [after a long hiatus...]
    
    I tested your patch again and it does what is advertised. I changed your patch
    a bit. The main change was the documentation. You didn't explain what this new
    parameter is for. I tried to explain but don't want to add lots of details.
    (There is a section that explain how parallel apply processes work behind the
    scenes.) I also renamed it from acquired_by to pid to be more descriptive. I
    fixed some white space issues too. I noticed that there are no tests. This
    doesn't appear to be a shortcoming from this patch but we need to cover some of
    these replication functions with an additional test file in another patch.
    Finally, I wrote a commit message and it is RfC.
    
    session 1:
    
    postgres=# select * from pg_replication_origin;
    roident | roname 
    ---------+--------
    (0 rows)
    
    postgres=# SELECT pg_backend_pid();
    pg_backend_pid 
    ----------------
             260732
    (1 row)
    
    postgres=# SELECT pg_replication_origin_create('test');
    pg_replication_origin_create 
    ------------------------------
                                1
    (1 row)
    
    postgres=# SELECT pg_replication_origin_session_setup('test', 0);
    pg_replication_origin_session_setup 
    -------------------------------------
     
    (1 row)
    
    postgres=# select * from pg_replication_origin;
    roident | roname 
    ---------+--------
           1 | test
    (1 row)
    
    session 2:
    
    postgres=# SELECT pg_replication_origin_session_setup('test', 260732);
    pg_replication_origin_session_setup 
    -------------------------------------
     
    (1 row)
    
    session 3:
    
    postgres=# SELECT pg_replication_origin_session_setup('test', 12345);
    ERROR:  could not find replication state slot for replication origin with OID 1 which was acquired by 12345
    
    
    --
    Euler Taveira
    EDB   https://www.enterprisedb.com/
    
  5. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-03-01T17:52:23Z

    I noticed that the patch needs rebasing, so here is the rebased version.
    Hopefully it makes to the commitfest.
    
    Doruk Yılmaz
    
  6. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2025-03-03T03:38:59Z

    On Thu, Jan 9, 2025 at 3:26 AM Euler Taveira <euler@eulerto.com> wrote:
    >
    > On Thu, Aug 15, 2024, at 5:53 PM, Doruk Yilmaz wrote:
    >
    > Hello again,
    >
    > On Tue, Aug 13, 2024 at 12:48 AM Euler Taveira <euler@eulerto.com> wrote:
    > > I'm curious about your use case. Is it just because the internal function has a
    > > different signature or your tool is capable of apply logical replication changes
    > > in parallel using the SQL API?
    >
    > The latter is correct, it applies logical replication changes in parallel.
    > Since multiple connections may commit, we need all of them to be able
    > to advance the replication origin.
    >
    
    To use replication_origin by multiple processes, one must maintain the
    commit order as we do internally by allowing the leader process to
    wait for the parallel worker to finish the commit. See comments atop
    replorigin_session_setup(). Now, we could expose the pid parameter as
    proposed by the patch after documenting the additional requirements,
    but I am afraid that users may directly start using the API without
    following the commit order principle, which can lead to incorrect
    replication. So, isn't it better to do something to avoid the misuse
    of this feature before exposing it?
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  7. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-07-28T21:13:27Z

    On Mon, Mar 3, 2025 at 6:39 AM Amit Kapila <amit.kapila16@gmail.com> wrote:
    >
    > To use replication_origin by multiple processes, one must maintain the
    > commit order as we do internally by allowing the leader process to
    > wait for the parallel worker to finish the commit. See comments atop
    > replorigin_session_setup(). Now, we could expose the pid parameter as
    > proposed by the patch after documenting the additional requirements,
    > but I am afraid that users may directly start using the API without
    > following the commit order principle, which can lead to incorrect
    > replication. So, isn't it better to do something to avoid the misuse
    > of this feature before exposing it?
    
    Wouldn't mentioning/describing needing to follow the commit order
    principle on the documentation be enough for this?
    It is quite an advanced feature that I don't believe person intending
    to use it won't start with reading documentation first.
    
    
    Is there any updates on the commit? I see that intended commitfest window ended.
    
    Thanks,
    Doruk Yılmaz
    
    
    
    
  8. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2025-07-29T05:13:32Z

    On Tue, Jul 29, 2025 at 2:43 AM Doruk Yilmaz <doruk@mixrank.com> wrote:
    >
    > On Mon, Mar 3, 2025 at 6:39 AM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > >
    > > To use replication_origin by multiple processes, one must maintain the
    > > commit order as we do internally by allowing the leader process to
    > > wait for the parallel worker to finish the commit. See comments atop
    > > replorigin_session_setup(). Now, we could expose the pid parameter as
    > > proposed by the patch after documenting the additional requirements,
    > > but I am afraid that users may directly start using the API without
    > > following the commit order principle, which can lead to incorrect
    > > replication. So, isn't it better to do something to avoid the misuse
    > > of this feature before exposing it?
    >
    > Wouldn't mentioning/describing needing to follow the commit order
    > principle on the documentation be enough for this?
    > It is quite an advanced feature that I don't believe person intending
    > to use it won't start with reading documentation first.
    >
    
    That is true but I still feel there has to be some mechanism where we
    can catch and give an ERROR to the user, if it doesn't follow the
    same. For example, pg_replication_origin_advance() always allows going
    backwards in terms of LSN which means if one doesn't follow commit
    order, it can lead to breaking the replication as after restart the
    client can ask to start replication from some prior point.
    
    >
    > Is there any updates on the commit?
    >
    
    I think we are still under discussion about the requirements and
    design for this API. Can you tell us the use case? Did you also intend
    to use it for parallel apply, if so, can you also tell at a high
    level, how you are planning to manage origin? It will help us to
    extend the API(s) in a meaningful way.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  9. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-07-29T18:30:43Z

    On Mon, Jul 29, 2025 at 8:13 AM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > That is true but I still feel there has to be some mechanism where we
    > can catch and give an ERROR to the user, if it doesn't follow the
    > same. For example, pg_replication_origin_advance() always allows going
    > backwards in terms of LSN which means if one doesn't follow commit
    > order, it can lead to breaking the replication as after restart the
    > client can ask to start replication from some prior point.
    If you have any ideas for safeguards or API changes, I'd be happy to
    help implement them or discuss them.
    > Can you tell us the use case? Did you also intend to use it for parallel apply, if so, can you also tell at a high
    > level, how you are planning to manage origin?
    Yes, we use it for parallel apply. We have a custom logical
    replication system that applies changes using multiple worker
    processes, each with their own database connection.
    Our use case requires multiple connections to be able to advance the
    same replication origin. We handle this by having a master process
    coordinate the workers, where each worker process calls
    pg_replication_origin_session_setup with the master's PID as the
    second parameter.
    We may send operations out of order but we always commit in order, so
    there's no chance of creating inconsistencies. There's the chance of
    deadlocks, but these can be detected. It's really similar to the
    existing parallel apply implementation - the main difference is that
    we're applying from jsonl files instead of directly from another
    database.
    Currently we use a local patch to expose the PID parameter, but having
    this upstream would be great. It causes a lot of headaches for us to
    use a patched PostgreSQL.
    Thanks,
    Doruk Yılmaz
    
    
    
    
  10. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2025-08-11T06:44:01Z

    On Wed, Jul 30, 2025 at 12:00 AM Doruk Yilmaz <doruk@mixrank.com> wrote:
    >
    > On Mon, Jul 29, 2025 at 8:13 AM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > > That is true but I still feel there has to be some mechanism where we
    > > can catch and give an ERROR to the user, if it doesn't follow the
    > > same. For example, pg_replication_origin_advance() always allows going
    > > backwards in terms of LSN which means if one doesn't follow commit
    > > order, it can lead to breaking the replication as after restart the
    > > client can ask to start replication from some prior point.
    > If you have any ideas for safeguards or API changes, I'd be happy to
    > help implement them or discuss them.
    > > Can you tell us the use case? Did you also intend to use it for parallel apply, if so, can you also tell at a high
    > > level, how you are planning to manage origin?
    > Yes, we use it for parallel apply. We have a custom logical
    > replication system that applies changes using multiple worker
    > processes, each with their own database connection.
    > Our use case requires multiple connections to be able to advance the
    > same replication origin.
    >
    
    How do you advance the origin? Did you use
    pg_replication_origin_advance()? If so, you should be aware that it
    can be used for initial setup; see comment in that API code: "Can't
    sensibly pass a local commit to be flushed at checkpoint - this xact
    hasn't committed yet. This is why this function should be used to set
    up the initial replication state, but not for replay." I wonder if you
    are using pg_replication_origin_advance(), won't its current
    implementation has the potential to cause a problem for your usecase?
    I think the problem it can cause is it may miss a transaction to apply
    after restart because we can use remote_lsn without a corresponding
    transaction (local_lsn) flushed on the subscriber. This can happen
    because ideally we want the transaction that is not successfully
    flushed to be replayed after restart.
    
    In general, I was thinking of adding a restriction
    pg_replication_origin_advance() such that it gives an ERROR when a
    user tries to move remote_lsn backward unless requested explicitly.
    
    It would be good to know the opinion of others involved in the
    original change of maintaining commit order for parallel apply of
    large transactions.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  11. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-08-11T17:11:34Z

    On Mon, Aug 11, 2025 at 9:44 AM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > How do you advance the origin? Did you use > pg_replication_origin_advance()? If so, you should be aware that it
    > can be used for initial setup; see comment in that API code...
    
    No, we don't use pg_replication_origin_advance(). We use
    pg_replication_origin_xact_setup() instead as I mentioned before.
    
    Each worker does the following:
    1. Sets up its own replication-origin session with
    pg_replication_origin_session_setup() (using the master process PID).
    2. Applies changes inside transactions.
    3. Right before commit, calls pg_replication_origin_xact_setup(lsn,
    commit_timestamp).
    4. Commits only if everything succeeded, so the origin only advances
    on a real commit.
    
    That way, the origin LSN moves forward only when the transaction is
    actually committed. If something fails or the process crashes, the
    origin stays at the last successful commit, and on restart we replay
    from the correct spot. It's safer than advancing the origin without
    knowing the transaction made it to disk.
    
    So the issue you described is not relevant for our implementation.
    
    
    
    
  12. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2025-08-12T09:27:49Z

    On Mon, Aug 11, 2025 at 10:41 PM Doruk Yilmaz <doruk@mixrank.com> wrote:
    >
    > On Mon, Aug 11, 2025 at 9:44 AM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > > How do you advance the origin? Did you use > pg_replication_origin_advance()? If so, you should be aware that it
    > > can be used for initial setup; see comment in that API code...
    >
    > No, we don't use pg_replication_origin_advance(). We use
    > pg_replication_origin_xact_setup() instead as I mentioned before.
    >
    > Each worker does the following:
    > 1. Sets up its own replication-origin session with
    > pg_replication_origin_session_setup() (using the master process PID).
    > 2. Applies changes inside transactions.
    > 3. Right before commit, calls pg_replication_origin_xact_setup(lsn,
    > commit_timestamp).
    > 4. Commits only if everything succeeded, so the origin only advances
    > on a real commit.
    >
    > That way, the origin LSN moves forward only when the transaction is
    > actually committed. If something fails or the process crashes, the
    > origin stays at the last successful commit, and on restart we replay
    > from the correct spot. It's safer than advancing the origin without
    > knowing the transaction made it to disk.
    >
    
    Your use looks good to me. So, maybe we can update the docs with the
    dangers if the users of API doesn't follow commit order then it may
    lead to data inconsistency should be sufficient. Additionally, we may
    want to give an example as to how to use this API for parallel apply.
    
    Thoughts?
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  13. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-08-18T18:55:19Z

    > Your use looks good to me. So, maybe we can update the docs with the
    > dangers if the users of API doesn't follow commit order then it may
    > lead to data inconsistency should be sufficient. Additionally, we may
    > want to give an example as to how to use this API for parallel apply.
    
    That sounds reasonable. I’ve updated the patch and added more
    information to the documentation covering the topics you mentioned.
    I also added a Caution block so potential users won’t miss it. I hope
    this patch meets your expectations.
    
  14. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2025-08-22T05:50:06Z

    Dear Doruk,
    
    > That sounds reasonable. I’ve updated the patch and added more
    > information to the documentation covering the topics you mentioned.
    > I also added a Caution block so potential users won’t miss it. I hope
    > this patch meets your expectations.
    
    Can you explain more why we must extend the SQL interface? I read your use
    case [1], and looks like that a new type of background worker is introduced in
    your system. If so, why doesn't the worker directly call C-lang interface
    replorigin_session_setup()?
    Personally considered, SQL functions are usable by unfamiliar users so that this
    change may be dangerous. It is better if developers can use C APIs instead.
    
    [1]: https://www.postgresql.org/message-id/CAMPB6wckvkKrXVPH5j8Ske2cVedkb-TRLdnOb5e74zYM1CynGw%40mail.gmail.com
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED
    
  15. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-08-22T12:51:59Z

    Dear Hayato,
    
    > Can you explain more why we must extend the SQL interface?
    
    In our system the workers aren't background workers and we don't ship
    a server-side extension; they're plain external processes (Python in
    our case) talking over standard database connections. In many
    deployments -especially managed Postgres- we can't load custom C code
    even if we wanted to. That's why we want to expose the existing pid
    knob via SQL: it lets ordinary client sessions participate in the
    same, already-implemented origin coordination without maintaining a
    fork or an extension.
    This patch doesn't invent a new capability, it just makes the internal
    behavior reachable from SQL. The new argument is optional and defaults
    to the current behavior, so nothing changes for existing users. It
    also keeps the feature usable from any language/runtime that
    coordinates parallel apply at the application layer. And I don't
    believe it is that dangerous or risky. The actual code we use in
    python is not that complex that I believe a person using replication
    already should be able to set it up. I don't understand why being able
    to achieve parallel replication is not accessible via SQL already.
    
    I am happy to do changes to the patch if you think there should be
    more guardrails.
    
    Thanks,
    Doruk Yılmaz
    
    
    
    
  16. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2025-08-25T10:43:11Z

    Dear Doruk,
    
    > In our system the workers aren't background workers and we don't ship
    > a server-side extension; they're plain external processes (Python in
    > our case) talking over standard database connections. In many
    > deployments -especially managed Postgres- we can't load custom C code
    > even if we wanted to. That's why we want to expose the existing pid
    > knob via SQL: it lets ordinary client sessions participate in the
    > same, already-implemented origin coordination without maintaining a
    > fork or an extension.
    
    So, your python process establishes two connections, for publisher (replication connection)
    and subscriber (normal connection). It receives changes from the publisher,
    constructs SQL statements from the received results, and sends to subscriber's
    backend, is it right?
    I'm not sure it is the common approach, but I see your point that you cannot
    install your extensions on managed postgres.
    
    Anyway, I still feel bit dangerous but OK if others can accept.
    
    Regarding the patch, I want to ask one point.
    ```
    +CREATE OR REPLACE FUNCTION
    +  pg_replication_origin_session_setup(node_name text, pid integer DEFAULT 0)
    +RETURNS void
    +LANGUAGE INTERNAL
    +STRICT VOLATILE
    +AS 'pg_replication_origin_session_setup';
    ...
    { oid => '6006',
       descr => 'configure session to maintain replication progress tracking for the passed in origin',
       proname => 'pg_replication_origin_session_setup', provolatile => 'v',
    -  proparallel => 'u', prorettype => 'void', proargtypes => 'text',
    +  proparallel => 'u', prorettype => 'void', proargtypes => 'text int4',
       prosrc => 'pg_replication_origin_session_setup' },
    ```
    
    Is there a rule which attribute is clarified and others are not?
    For example, VOLATILE is specified on both side, STRICT is written only in the
    system_functions.sql, and PARALLEL UNSAFE is set on pg_proc.dat.
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED
    
    
  17. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-09-03T12:43:25Z

    Dear Hayato,
    
    > So, your python process establishes two connections, for publisher (replication connection)
    > and subscriber (normal connection). It receives changes from the publisher,
    > constructs SQL statements from the received results, and sends to subscriber's
    > backend, is it right?
    
    Actually, it's a bit simpler than that - there are no two connections.
    Our program reads changes from JSONL files rather than directly from a
    publisher connection.
    We have multiple Python processes, each with a single database
    connection to the subscriber,
    reading from these files and applying changes in parallel.
    
    > Is there a rule which attribute is clarified and others are not?
    > For example, VOLATILE is specified on both side, STRICT is written only in the
    > system_functions.sql, and PARALLEL UNSAFE is set on pg_proc.dat.
    
    In pg_proc.dat, I believe the STRICT, IMMUTABLE, and PARALLEL SAFE are
    the defaults (check out pg_proc.h).
    So in pg_proc.dat, the ones that are specified are the ones that
    aren't defaults,
    there is provolatile => 'v' (for VOLATILE) and proparallel => 'u' (for
    UNSAFE), but no prostrict since it's already true by default.
    In system_functions.sql, I went with being explicit about all the
    attributes for clarity as it is the code declaration.
    If you want, I can also make the pg_proc.dat explicit.
    
    Thanks,
    Doruk Yılmaz
    
    
    
    
  18. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2025-09-06T05:09:48Z

    On Wed, Sep 3, 2025 at 6:13 PM Doruk Yilmaz <doruk@mixrank.com> wrote:
    >
    > Dear Hayato,
    >
    > > So, your python process establishes two connections, for publisher (replication connection)
    > > and subscriber (normal connection). It receives changes from the publisher,
    > > constructs SQL statements from the received results, and sends to subscriber's
    > > backend, is it right?
    >
    > Actually, it's a bit simpler than that - there are no two connections.
    > Our program reads changes from JSONL files rather than directly from a
    > publisher connection.
    > We have multiple Python processes, each with a single database
    > connection to the subscriber,
    > reading from these files and applying changes in parallel.
    >
    > > Is there a rule which attribute is clarified and others are not?
    > > For example, VOLATILE is specified on both side, STRICT is written only in the
    > > system_functions.sql, and PARALLEL UNSAFE is set on pg_proc.dat.
    >
    > In pg_proc.dat, I believe the STRICT, IMMUTABLE, and PARALLEL SAFE are
    > the defaults (check out pg_proc.h).
    > So in pg_proc.dat, the ones that are specified are the ones that
    > aren't defaults,
    > there is provolatile => 'v' (for VOLATILE) and proparallel => 'u' (for
    > UNSAFE), but no prostrict since it's already true by default.
    > In system_functions.sql, I went with being explicit about all the
    > attributes for clarity as it is the code declaration.
    >
    
    Then why didn't you specified PARALLEL UNSAFE as well?
    
    BTW, yesterday a new thread started with the same requirement [1]. It
    uses a slightly different way to define the new function. do you have
    any opinion on it?
    
    [1] - https://www.postgresql.org/message-id/CAE2gYzyTSNvHY1%2BiWUwykaLETSuAZsCWyryokjP6rG46ZvRgQA%40mail.gmail.com
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  19. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-09-08T17:22:22Z

    > Then why didn't you specified PARALLEL UNSAFE as well?
    
    You are correct, I missed marking the function as PARALLEL UNSAFE.
    I’ve attached a revised patch with the correct annotation.
    
    > BTW, yesterday a new thread started with the same requirement [1]. It
    > uses a slightly different way to define the new function. do you have
    > any opinion on it?
    
    I don’t think introducing a separate function is a good idea. It’s
    effectively the same behavior, technical debt, and maintenance
    overhead without a clear benefit.
    Our patch keeps a single function with a default parameter, so it’s
    not a breaking change. So I believe our approach is preferable.
    But I would say that, the fact that another patch is proposing the
    same capability indicates there’s broader demand for this change.
    
  20. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2025-09-16T04:37:15Z

    Dear Doruk,
    
    Thanks for updating the patch and sorry for being late.
    The new patch looks good to me.
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED
    
    
  21. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Doruk Yilmaz <doruk@mixrank.com> — 2025-09-16T21:49:32Z

    Dear Hayato,
    
    Thanks for the feedback on the patch, I'm glad the latest version looks good.
    I was wondering if there is anything else I need to do on my end, or
    any other process I should be aware of, for this patch to move
    forward? I'm happy to make any further adjustments or provide more
    information if needed.
    
    Thanks,
    Doruk Yılmaz
    
    
    
    
  22. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2025-09-17T06:19:20Z

    On Tue, Sep 16, 2025 at 10:07 AM Hayato Kuroda (Fujitsu)
    <kuroda.hayato@fujitsu.com> wrote:
    >
    > Dear Doruk,
    >
    > Thanks for updating the patch and sorry for being late.
    > The new patch looks good to me.
    >
    
    Can we think of writing a few tests for this newly exposed functionality?
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  23. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2025-09-17T09:22:45Z

    Dear Amit,
    
    > Can we think of writing a few tests for this newly exposed functionality?
    
    I considered a test, please see attached files. 0001 was not changed from v6 and
    0002 contained tests. Here, two sessions were opened and confirmed that they can
    set the same origin.
    
    BTW, while testing I found the existing issue of this function. Since the
    session_replication_state is set before the pid check, there is a case that
    session origin retains in case of failure. Here is a quick reproducer:
    
    ```
    postgres=# SELECT pg_replication_origin_create('origin');
     pg_replication_origin_create 
    ------------------------------
                                1
    (1 row)
    
    postgres=# -- run origin_session_setup with incorrect parameter
    postgres=# SELECT pg_replication_origin_session_setup('origin', -1);
    ERROR:  could not find replication state slot for replication origin with OID 1 which was acquired by -1
    postgres=# -- run origin_session_setup again with correct parameter
    postgres=# SELECT pg_replication_origin_session_setup('origin');
    ERROR:  cannot setup replication origin when one is already setup
    ```
    
    The issue has exist since we introduces the parallel apply, but it has not been
    found till now. Because parallel apply workers have not specified the invalid
    pid. It can be more likely to happen so it's time to fix at the same time.
    
    Idea for fix is that use local replication state and then at end assign it to
    process-level. 0003 implemented that.
    
    How do you feel?
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED 
    
    
  24. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2025-09-18T07:37:11Z

    Dear hackers,
    
    > I considered a test, please see attached files. 0001 was not changed from v6 and
    > 0002 contained tests. Here, two sessions were opened and confirmed that they
    > can
    > set the same origin.
    
    After considering and verifying more, it is more efficient to test via isolation
    tester. Attached patchset does like that.
    On my env, the duration became 10x faster because it does not start the instance
    within the test.
    
    In the test file, two sessions s0 and s1 are launched, they set the same session
    origin. They insert local_lsn to a table and confirm latter insertion has larger
    value.
    
    One hacky point is to obtain pid for s0 from s1. Below contains my analysis.
    
    application_name is controlled by the isolation_main.c and isolationtester.c.
    When the isolation test works, initially isolation_main starts and launches
    isolaiontester process, one per spec file.
    In main.c, the application_name is set to "isolation/${testname}" at the starter
    function. Then, after isolationtester parses the spec file, it appends given
    name to each session. This is done at line 193.
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED
    
    
  25. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2025-09-18T11:02:56Z

    On Thu, Sep 18, 2025 at 1:07 PM Hayato Kuroda (Fujitsu)
    <kuroda.hayato@fujitsu.com> wrote:
    >
    > Dear hackers,
    >
    > > I considered a test, please see attached files.
    >
    
    Few comments:
    1. +step "s0_compare" {
    +    SELECT s0.lsn < s1.lsn
    +    FROM local_lsn_store as s0, local_lsn_store as s1
    +    WHERE s0.session = 0 AND s1.session = 1;
    +}
    
    This appears to be a bit tricky to compare the values. Doing a
    sequential scan won't guarantee the order of rows' appearance. Can't
    we somehow get the two rows ordered by session_id and compare their
    values?
    
    2.
    + else if (candidate_state->acquired_by != acquired_by)
    + {
    + if (initialized)
    + candidate_state->roident = InvalidRepOriginId;
    +
      elog(ERROR, "could not find replication state slot for replication
    origin with OID %u which was acquired by %d",
      node, acquired_by);
    + }
    
    This doesn't appear neat. Instead, how about checking this case before
    setting current_state as shown in attached. If we do that, we
    shouldn't even need new variables like current_state and initialized.
    Additionally, as shown in attached, it is better to make this a
    user-facing error by using ereport.
    
    3. Merge all patches as I don't see the need to do any backpatch here.
    
    -- 
    With Regards,
    Amit Kapila.
    
  26. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2025-09-18T14:19:32Z

    Dear Amit,
    
    > 
    > Few comments:
    > 1. +step "s0_compare" {
    > +    SELECT s0.lsn < s1.lsn
    > +    FROM local_lsn_store as s0, local_lsn_store as s1
    > +    WHERE s0.session = 0 AND s1.session = 1;
    > +}
    > 
    > This appears to be a bit tricky to compare the values. Doing a
    > sequential scan won't guarantee the order of rows' appearance. Can't
    > we somehow get the two rows ordered by session_id and compare their
    > values?
    
    I considered another way to use the CTE for session 0. How do you feel?
    
    > 2.
    > + else if (candidate_state->acquired_by != acquired_by)
    > + {
    > + if (initialized)
    > + candidate_state->roident = InvalidRepOriginId;
    > +
    >   elog(ERROR, "could not find replication state slot for replication
    > origin with OID %u which was acquired by %d",
    >   node, acquired_by);
    > + }
    > 
    > This doesn't appear neat. Instead, how about checking this case before
    > setting current_state as shown in attached. If we do that, we
    > shouldn't even need new variables like current_state and initialized.
    
    Your approach cannot work when the specified origin is not used yet after the
    instance starts. In this case the origin has not exist in the replication_states
    yet and new slot is initialized.
    
    Per current understanding, two ERRORs are needed to avoid adding new variables;
    first one is in the loop, and second one is in session_replication_state == NULL
    case. Latter one indicates the case that origin is inactive but PID is specified
    so different error message can be set.
    
    > Additionally, as shown in attached, it is better to make this a
    > user-facing error by using ereport.
    
    Indeed, elog() were replaced with ereport().
    
    > 3. Merge all patches as I don't see the need to do any backpatch here.
    
    Sure.
    
    Attached patch includes all changes. Thought?
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED
    
    
  27. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Zhijie Hou (Fujitsu) <houzj.fnst@fujitsu.com> — 2025-12-23T08:54:03Z

    Hi,
    
    When testing the new parameter in pg_replication_origin_session_setup(), I
    noticed a bug allowing the origin in use to be dropped. The issue arises when
    two backends set up the same origin; if the second backend resets the origin
    first, it resets the acquired_by flag regardless of whether the first backend is
    using it. This allows the origin to be dropped, enabling the slot in shared
    memory to be reused, which is unintended.
    
    About the fix, simply adding a check for acquired_by field does not work,
    because if the first backend resets the origin first, it still risks being
    dropped while second backend uses it.
    
    To fully resolve this, I tried to add a reference count (refcount) for the
    origin. The count is incremented when a backend sets up the origin and
    decremented upon a reset. As a result, the replication origin is only dropped
    when the reference count reaches zero.
    
    Thanks to Kuroda-San for discussing and reviewing this patch off-list.
    
    Best Regards,
    Hou zj
    
  28. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2025-12-24T09:12:15Z

    On Tue, Dec 23, 2025 at 2:24 PM Zhijie Hou (Fujitsu)
    <houzj.fnst@fujitsu.com> wrote:
    >
    > When testing the new parameter in pg_replication_origin_session_setup(), I
    > noticed a bug allowing the origin in use to be dropped. The issue arises when
    > two backends set up the same origin; if the second backend resets the origin
    > first, it resets the acquired_by flag regardless of whether the first backend is
    > using it. This allows the origin to be dropped, enabling the slot in shared
    > memory to be reused, which is unintended.
    >
    > About the fix, simply adding a check for acquired_by field does not work,
    > because if the first backend resets the origin first, it still risks being
    > dropped while second backend uses it.
    >
    > To fully resolve this, I tried to add a reference count (refcount) for the
    > origin. The count is incremented when a backend sets up the origin and
    > decremented upon a reset. As a result, the replication origin is only dropped
    > when the reference count reaches zero.
    >
    > Thanks to Kuroda-San for discussing and reviewing this patch off-list.
    >
    
    Thanks to both of you for the report and patch. I'll look into it
    sometime during the next CF.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  29. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    shveta malik <shveta.malik@gmail.com> — 2026-01-05T09:45:08Z

    On Tue, Dec 23, 2025 at 2:24 PM Zhijie Hou (Fujitsu)
    <houzj.fnst@fujitsu.com> wrote:
    >
    > Hi,
    >
    > When testing the new parameter in pg_replication_origin_session_setup(), I
    > noticed a bug allowing the origin in use to be dropped. The issue arises when
    > two backends set up the same origin; if the second backend resets the origin
    > first, it resets the acquired_by flag regardless of whether the first backend is
    > using it. This allows the origin to be dropped, enabling the slot in shared
    > memory to be reused, which is unintended.
    >
    > About the fix, simply adding a check for acquired_by field does not work,
    > because if the first backend resets the origin first, it still risks being
    > dropped while second backend uses it.
    >
    > To fully resolve this, I tried to add a reference count (refcount) for the
    > origin. The count is incremented when a backend sets up the origin and
    > decremented upon a reset. As a result, the replication origin is only dropped
    > when the reference count reaches zero.
    >
    > Thanks to Kuroda-San for discussing and reviewing this patch off-list.
    >
    
    Thanks Hou-San and Kuroda-San.
    
    What should be the expected behavior when Session1 resets the origin
    (changing acquired_pid from its own PID to 0), while Session2 is
    already connected to the origin and Session3 also attempts to reuse
    the same origin?
    
    Currently it asserts:
    
    Session1:
    select pg_replication_origin_create('origin');
    SELECT pg_replication_origin_session_setup('origin');
    
    Session2:
    SELECT pg_replication_origin_session_setup('origin',48028);
    
    Session1:
    SELECT pg_replication_origin_session_reset();
    
    Session3:
    SELECT pg_replication_origin_session_setup('origin');
    This asserts at:
    TRAP: failed Assert("session_replication_state->refcount == 0"), File:
    "origin.c", Line: 1231, PID: 48037
    
    thanks
    Shveta
    
    
    
    
  30. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    shveta malik <shveta.malik@gmail.com> — 2026-01-05T10:30:15Z

    On Mon, Jan 5, 2026 at 3:15 PM shveta malik <shveta.malik@gmail.com> wrote:
    >
    > On Tue, Dec 23, 2025 at 2:24 PM Zhijie Hou (Fujitsu)
    > <houzj.fnst@fujitsu.com> wrote:
    > >
    > > Hi,
    > >
    > > When testing the new parameter in pg_replication_origin_session_setup(), I
    > > noticed a bug allowing the origin in use to be dropped. The issue arises when
    > > two backends set up the same origin; if the second backend resets the origin
    > > first, it resets the acquired_by flag regardless of whether the first backend is
    > > using it. This allows the origin to be dropped, enabling the slot in shared
    > > memory to be reused, which is unintended.
    > >
    > > About the fix, simply adding a check for acquired_by field does not work,
    > > because if the first backend resets the origin first, it still risks being
    > > dropped while second backend uses it.
    > >
    > > To fully resolve this, I tried to add a reference count (refcount) for the
    > > origin. The count is incremented when a backend sets up the origin and
    > > decremented upon a reset. As a result, the replication origin is only dropped
    > > when the reference count reaches zero.
    > >
    > > Thanks to Kuroda-San for discussing and reviewing this patch off-list.
    > >
    >
    > Thanks Hou-San and Kuroda-San.
    >
    > What should be the expected behavior when Session1 resets the origin
    > (changing acquired_pid from its own PID to 0), while Session2 is
    > already connected to the origin and Session3 also attempts to reuse
    > the same origin?
    >
    > Currently it asserts:
    >
    > Session1:
    > select pg_replication_origin_create('origin');
    > SELECT pg_replication_origin_session_setup('origin');
    >
    > Session2:
    > SELECT pg_replication_origin_session_setup('origin',48028);
    >
    > Session1:
    > SELECT pg_replication_origin_session_reset();
    >
    > Session3:
    > SELECT pg_replication_origin_session_setup('origin');
    > This asserts at:
    > TRAP: failed Assert("session_replication_state->refcount == 0"), File:
    > "origin.c", Line: 1231, PID: 48037
    >
    
    I checked the behavior on HEAD. Session3 is able to set up the origin
    and sets its own PID in acquired_pid. But it is unclear to me which
    PID should be recorded in acquired_pid - Session2’s PID, since it set
    up the origin earlier, or Session3’s PID. Or does this even make any
    difference?
    
    I found one more related issue on HEAD, sharing it here:
    
    When the first backend creates and sets up the origin, followed by a
    second backend setting it up, and then the first backend resets it
    while the second backend attempts to drop it, an assertion is
    triggered:
    TRAP: failed Assert("session_replication_state->roident !=
    InvalidRepOriginId"), File: "origin.c", Line: 1257, PID: 48438
    
    thanks
    Shveta
    
    
    
    
  31. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-01-09T09:00:47Z

    On Mon, Jan 5, 2026 at 4:00 PM shveta malik <shveta.malik@gmail.com> wrote:
    >
    > On Mon, Jan 5, 2026 at 3:15 PM shveta malik <shveta.malik@gmail.com> wrote:
    > >
    > > On Tue, Dec 23, 2025 at 2:24 PM Zhijie Hou (Fujitsu)
    > > <houzj.fnst@fujitsu.com> wrote:
    > > >
    > > > Hi,
    > > >
    > > > When testing the new parameter in pg_replication_origin_session_setup(), I
    > > > noticed a bug allowing the origin in use to be dropped. The issue arises when
    > > > two backends set up the same origin; if the second backend resets the origin
    > > > first, it resets the acquired_by flag regardless of whether the first backend is
    > > > using it. This allows the origin to be dropped, enabling the slot in shared
    > > > memory to be reused, which is unintended.
    > > >
    > > > About the fix, simply adding a check for acquired_by field does not work,
    > > > because if the first backend resets the origin first, it still risks being
    > > > dropped while second backend uses it.
    > > >
    > > > To fully resolve this, I tried to add a reference count (refcount) for the
    > > > origin. The count is incremented when a backend sets up the origin and
    > > > decremented upon a reset. As a result, the replication origin is only dropped
    > > > when the reference count reaches zero.
    > > >
    > > > Thanks to Kuroda-San for discussing and reviewing this patch off-list.
    > > >
    > >
    > > Thanks Hou-San and Kuroda-San.
    > >
    > > What should be the expected behavior when Session1 resets the origin
    > > (changing acquired_pid from its own PID to 0), while Session2 is
    > > already connected to the origin and Session3 also attempts to reuse
    > > the same origin?
    > >
    > > Currently it asserts:
    > >
    > > Session1:
    > > select pg_replication_origin_create('origin');
    > > SELECT pg_replication_origin_session_setup('origin');
    > >
    > > Session2:
    > > SELECT pg_replication_origin_session_setup('origin',48028);
    > >
    > > Session1:
    > > SELECT pg_replication_origin_session_reset();
    > >
    > > Session3:
    > > SELECT pg_replication_origin_session_setup('origin');
    > > This asserts at:
    > > TRAP: failed Assert("session_replication_state->refcount == 0"), File:
    > > "origin.c", Line: 1231, PID: 48037
    > >
    >
    > I checked the behavior on HEAD. Session3 is able to set up the origin
    > and sets its own PID in acquired_pid. But it is unclear to me which
    > PID should be recorded in acquired_pid - Session2’s PID, since it set
    > up the origin earlier, or Session3’s PID. Or does this even make any
    > difference?
    >
    > I found one more related issue on HEAD, sharing it here:
    >
    > When the first backend creates and sets up the origin, followed by a
    > second backend setting it up, and then the first backend resets it
    > while the second backend attempts to drop it, an assertion is
    > triggered:
    > TRAP: failed Assert("session_replication_state->roident !=
    > InvalidRepOriginId"), File: "origin.c", Line: 1257, PID: 48438
    >
    
    Can we address these problems by prohibiting leader worker to reset
    when pa workers are still associated with the origin? The way for
    leader to know if pa workers are associated with origin is by checking
    following condition: acquired_by == MyProcpid AND refcount > 1.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  32. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2026-01-09T11:28:35Z

    Dear Amit, Shveta,
    
    > > >
    > > > Thanks Hou-San and Kuroda-San.
    > > >
    > > > What should be the expected behavior when Session1 resets the origin
    > > > (changing acquired_pid from its own PID to 0), while Session2 is
    > > > already connected to the origin and Session3 also attempts to reuse
    > > > the same origin?
    > > >
    > > > Currently it asserts:
    > > >
    > > > Session1:
    > > > select pg_replication_origin_create('origin');
    > > > SELECT pg_replication_origin_session_setup('origin');
    > > >
    > > > Session2:
    > > > SELECT pg_replication_origin_session_setup('origin',48028);
    > > >
    > > > Session1:
    > > > SELECT pg_replication_origin_session_reset();
    > > >
    > > > Session3:
    > > > SELECT pg_replication_origin_session_setup('origin');
    > > > This asserts at:
    > > > TRAP: failed Assert("session_replication_state->refcount == 0"), File:
    > > > "origin.c", Line: 1231, PID: 48037
    > > >
    
    FYI, this happened because v1 assumed refcount was 0 if acquired_by was 0.
    But your proposed scenario met it.
    
    > > I checked the behavior on HEAD. Session3 is able to set up the origin
    > > and sets its own PID in acquired_pid. But it is unclear to me which
    > > PID should be recorded in acquired_pid - Session2’s PID, since it set
    > > up the origin earlier, or Session3’s PID. Or does this even make any
    > > difference?
    
    To clarify, I think the behavior on HEAD is not correct. The backend should
    acquire the active origin if it expressly specifies the PID. Otherwise, users
    may acquire unintentionally and advance it.
    
    > Can we address these problems by prohibiting leader worker to reset
    > when pa workers are still associated with the origin? The way for
    > leader to know if pa workers are associated with origin is by checking
    > following condition: acquired_by == MyProcpid AND refcount > 1.
    
    I think it's okay. IIUC, the idea is to avoid that active origin has invalid
    acquired_by attribute. The replication origin was extended to support parallel
    apply of logical replication, and it is reasonable to force the same approach.
    Attached 0001 implemented that.
    
    One concern with the implementation is that acquired_by can be zero if the process
    exits without releasing the origin; this can happen if the first acquired process
    exits while the second is still using it.
    Regarding our logical replication, it won't be problematic because the leader
    worker ensures all parallel workers finish before it exits.
    
    To address the issue, I propose that another process should not be able to
    acquire the origin if the acquired_by of the active origin is 0. The problem
    should be resolved within the SQL interface, since it occurs there.
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED
    
    
  33. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    shveta malik <shveta.malik@gmail.com> — 2026-01-12T06:01:02Z

    On Fri, Jan 9, 2026 at 4:58 PM Hayato Kuroda (Fujitsu)
    <kuroda.hayato@fujitsu.com> wrote:
    >
    > Dear Amit, Shveta,
    >
    > > > >
    > > > > Thanks Hou-San and Kuroda-San.
    > > > >
    > > > > What should be the expected behavior when Session1 resets the origin
    > > > > (changing acquired_pid from its own PID to 0), while Session2 is
    > > > > already connected to the origin and Session3 also attempts to reuse
    > > > > the same origin?
    > > > >
    > > > > Currently it asserts:
    > > > >
    > > > > Session1:
    > > > > select pg_replication_origin_create('origin');
    > > > > SELECT pg_replication_origin_session_setup('origin');
    > > > >
    > > > > Session2:
    > > > > SELECT pg_replication_origin_session_setup('origin',48028);
    > > > >
    > > > > Session1:
    > > > > SELECT pg_replication_origin_session_reset();
    > > > >
    > > > > Session3:
    > > > > SELECT pg_replication_origin_session_setup('origin');
    > > > > This asserts at:
    > > > > TRAP: failed Assert("session_replication_state->refcount == 0"), File:
    > > > > "origin.c", Line: 1231, PID: 48037
    > > > >
    >
    > FYI, this happened because v1 assumed refcount was 0 if acquired_by was 0.
    > But your proposed scenario met it.
    >
    > > > I checked the behavior on HEAD. Session3 is able to set up the origin
    > > > and sets its own PID in acquired_pid. But it is unclear to me which
    > > > PID should be recorded in acquired_pid - Session2’s PID, since it set
    > > > up the origin earlier, or Session3’s PID. Or does this even make any
    > > > difference?
    >
    > To clarify, I think the behavior on HEAD is not correct. The backend should
    > acquire the active origin if it expressly specifies the PID. Otherwise, users
    > may acquire unintentionally and advance it.
    
    I agree.
    
    >
    > > Can we address these problems by prohibiting leader worker to reset
    > > when pa workers are still associated with the origin? The way for
    > > leader to know if pa workers are associated with origin is by checking
    > > following condition: acquired_by == MyProcpid AND refcount > 1.
    >
    > I think it's okay. IIUC, the idea is to avoid that active origin has invalid
    > acquired_by attribute. The replication origin was extended to support parallel
    > apply of logical replication, and it is reasonable to force the same approach.
    > Attached 0001 implemented that.
    >
    > One concern with the implementation is that acquired_by can be zero if the process
    > exits without releasing the origin; this can happen if the first acquired process
    > exits while the second is still using it.
    > Regarding our logical replication, it won't be problematic because the leader
    > worker ensures all parallel workers finish before it exits.
    >
    > To address the issue, I propose that another process should not be able to
    > acquire the origin if the acquired_by of the active origin is 0. The problem
    > should be resolved within the SQL interface, since it occurs there.
    >
    
    +1.
    
    Please find a few comments:
    
    1)
    + /*
    + * The replication origin cannot be reset if the replication origin is
    + * firstly acquired by this backend and other processes are actively using
    + * now. This can cause acquired_by to be zero and active replication origin
    + * might be dropped.
    + */
    + if (session_replication_state->acquired_by == MyProcPid &&
    + session_replication_state->refcount > 1)
    + ereport(ERROR,
    + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
    + errmsg_plural("another process is acquiring the replication origin",
    +    "other processes are acquiring the replication origin",
    +
    
    Since user is not aware of internal acquired_by logic, the error might
    not make much sense to him as to why one session is able to reset
    while another is not. Shall we make it:
    
    ERROR:  cannot reset replication origin "origin_name" while it is
    still shared by other processes
    DETAIL:  the current session is the first process for this replication
    origin, and other processes are sharing it.
    HINT:  ensure this replication origin is reset in all other processes first.
    
    2)
    When the first session leaves, while the second session is still using
    origin, the third session is able to drop the origin which is not
    right.
    I think replorigin_state_clear() needs a change.
    'if (state->acquired_by != 0)' check should be replaced by 'if
    (state->refcount > 0)'
    
    Patch 001 had correct changes in replorigin_state_clear(), IMO we
    still need those
    
    3)
    When first session leaves, while second session is still using origin,
    now correctly third session is not able to join it. It gives error:
    postgres=# SELECT pg_replication_origin_session_setup('origin');
    ERROR: replication origin with ID 1 is already active for another process
    
    Error is not very informative provided the fact that now sharing is
    allowed. Shall it be:
    
    ERROR:  replication origin "origin_name" cannot be acquired while it
    is still in use
    DETAIL:  the process that first acquired this origin exited without
    releasing it.
    HINT:  wait until all processes sharing this origin have released it.
    Or
    HINT:  ensure this replication origin is reset in all other processes first.
    
    4)
    + /* Number of backend that is currently using this origin. */
    
    Number of backend that is --> Count of backends that are
    
    thanks
    Shveta
    
    
    
    
  34. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-01-13T02:56:54Z

    On Mon, Jan 12, 2026 at 11:31 AM shveta malik <shveta.malik@gmail.com> wrote:
    >
    > Please find a few comments:
    >
    > 1)
    > + /*
    > + * The replication origin cannot be reset if the replication origin is
    > + * firstly acquired by this backend and other processes are actively using
    > + * now. This can cause acquired_by to be zero and active replication origin
    > + * might be dropped.
    > + */
    > + if (session_replication_state->acquired_by == MyProcPid &&
    > + session_replication_state->refcount > 1)
    > + ereport(ERROR,
    > + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
    > + errmsg_plural("another process is acquiring the replication origin",
    > +    "other processes are acquiring the replication origin",
    > +
    >
    > Since user is not aware of internal acquired_by logic, the error might
    > not make much sense to him as to why one session is able to reset
    > while another is not. Shall we make it:
    >
    > ERROR:  cannot reset replication origin "origin_name" while it is
    > still shared by other processes
    > DETAIL:  the current session is the first process for this replication
    > origin, and other processes are sharing it.
    > HINT:  ensure this replication origin is reset in all other processes first.
    >
    
    How about a slightly tweaked version of these messages:
    ERROR: cannot reset replication origin "origin_name" because it is
    still in use by other processes
    DETAIL: This session is the first process for this replication origin,
    and other processes are currently sharing it.
    HINT: Reset the replication origin in all other processes before retrying.
    
    > 2)
    > When the first session leaves, while the second session is still using
    > origin, the third session is able to drop the origin which is not
    > right.
    > I think replorigin_state_clear() needs a change.
    > 'if (state->acquired_by != 0)' check should be replaced by 'if
    > (state->refcount > 0)'
    >
    > Patch 001 had correct changes in replorigin_state_clear(), IMO we
    > still need those
    >
    > 3)
    > When first session leaves, while second session is still using origin,
    > now correctly third session is not able to join it. It gives error:
    > postgres=# SELECT pg_replication_origin_session_setup('origin');
    > ERROR: replication origin with ID 1 is already active for another process
    >
    > Error is not very informative provided the fact that now sharing is
    > allowed. Shall it be:
    >
    
    Yeah, sharing is allowed but only when used in parallel context by
    passing PID. I think a slightly modified version of the above message
    such as: "replication origin with ID 1 is already active in another
    process" should be sufficient.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  35. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2026-01-13T04:09:31Z

    Dear Amit, Shveta,
    
    Thanks for suggestions. PSA new patches.
    
    > > Since user is not aware of internal acquired_by logic, the error might
    > > not make much sense to him as to why one session is able to reset
    > > while another is not. Shall we make it:
    > >
    > > ERROR:  cannot reset replication origin "origin_name" while it is
    > > still shared by other processes
    > > DETAIL:  the current session is the first process for this replication
    > > origin, and other processes are sharing it.
    > > HINT:  ensure this replication origin is reset in all other processes first.
    > >
    > 
    > How about a slightly tweaked version of these messages:
    > ERROR: cannot reset replication origin "origin_name" because it is
    > still in use by other processes
    > DETAIL: This session is the first process for this replication origin,
    > and other processes are currently sharing it.
    > HINT: Reset the replication origin in all other processes before retrying.
    
    I followed the Amit's idea, but the origin ID is used instead of origin name.
    I read other functions, and the name is directly output when 1) the specified
    origin does not exist or 2) the name is reserved. We seem to use ID as much as
    possible.
    
    > 
    > > 2)
    > > When the first session leaves, while the second session is still using
    > > origin, the third session is able to drop the origin which is not
    > > right.
    > > I think replorigin_state_clear() needs a change.
    > > 'if (state->acquired_by != 0)' check should be replaced by 'if
    > > (state->refcount > 0)'
    > >
    > > Patch 001 had correct changes in replorigin_state_clear(), IMO we
    > > still need those
    
    Good finding. I put it in 0002 because it handles some cases related with
    acquired_by = 0.
    
    > >
    > > 3)
    > > When first session leaves, while second session is still using origin,
    > > now correctly third session is not able to join it. It gives error:
    > > postgres=# SELECT pg_replication_origin_session_setup('origin');
    > > ERROR: replication origin with ID 1 is already active for another process
    > >
    > > Error is not very informative provided the fact that now sharing is
    > > allowed. Shall it be:
    > >
    > 
    > Yeah, sharing is allowed but only when used in parallel context by
    > passing PID. I think a slightly modified version of the above message
    > such as: "replication origin with ID 1 is already active in another
    > process" should be sufficient.
    
    Fixed but ereport() was used because I thought this is usar-facing. Feel free to
    change to elog() again based on your matter.
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED
    
    
  36. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    shveta malik <shveta.malik@gmail.com> — 2026-01-13T05:34:06Z

    On Tue, Jan 13, 2026 at 9:39 AM Hayato Kuroda (Fujitsu)
    <kuroda.hayato@fujitsu.com> wrote:
    >
    > Dear Amit, Shveta,
    >
    > Thanks for suggestions. PSA new patches.
    >
    > > > Since user is not aware of internal acquired_by logic, the error might
    > > > not make much sense to him as to why one session is able to reset
    > > > while another is not. Shall we make it:
    > > >
    > > > ERROR:  cannot reset replication origin "origin_name" while it is
    > > > still shared by other processes
    > > > DETAIL:  the current session is the first process for this replication
    > > > origin, and other processes are sharing it.
    > > > HINT:  ensure this replication origin is reset in all other processes first.
    > > >
    > >
    > > How about a slightly tweaked version of these messages:
    > > ERROR: cannot reset replication origin "origin_name" because it is
    > > still in use by other processes
    > > DETAIL: This session is the first process for this replication origin,
    > > and other processes are currently sharing it.
    > > HINT: Reset the replication origin in all other processes before retrying.
    >
    > I followed the Amit's idea, but the origin ID is used instead of origin name.
    > I read other functions, and the name is directly output when 1) the specified
    > origin does not exist or 2) the name is reserved. We seem to use ID as much as
    > possible.
    >
    > >
    > > > 2)
    > > > When the first session leaves, while the second session is still using
    > > > origin, the third session is able to drop the origin which is not
    > > > right.
    > > > I think replorigin_state_clear() needs a change.
    > > > 'if (state->acquired_by != 0)' check should be replaced by 'if
    > > > (state->refcount > 0)'
    > > >
    > > > Patch 001 had correct changes in replorigin_state_clear(), IMO we
    > > > still need those
    >
    > Good finding. I put it in 0002 because it handles some cases related with
    > acquired_by = 0.
    >
    > > >
    > > > 3)
    > > > When first session leaves, while second session is still using origin,
    > > > now correctly third session is not able to join it. It gives error:
    > > > postgres=# SELECT pg_replication_origin_session_setup('origin');
    > > > ERROR: replication origin with ID 1 is already active for another process
    > > >
    > > > Error is not very informative provided the fact that now sharing is
    > > > allowed. Shall it be:
    > > >
    > >
    > > Yeah, sharing is allowed but only when used in parallel context by
    > > passing PID. I think a slightly modified version of the above message
    > > such as: "replication origin with ID 1 is already active in another
    > > process" should be sufficient.
    >
    > Fixed but ereport() was used because I thought this is usar-facing. Feel free to
    > change to elog() again based on your matter.
    >
    
    Thanks for the patch. All scenarios (known to me) seem to work well.
    Few trivial comments:
    
    1)
    +step s1_reset: SELECT pg_replication_origin_session_reset();
    
    After the above step, please add a step to attempt dropping the
    replication origin. The original issue was that once s1 releases the
    origin, it becomes eligible for dropping, so the test should
    explicitly verify this behavior.
    
    2)
    Also before the above step, please add a step where s0 tries to reset
    the origin while s1 is still acquiring it. It is needed to cover the
    path where s0 should fail to release origin.
    
    3)
    + /*
    + * Reset the PID only if the current backend is the first to set up this
    + * origin. This prevents resetting the PID when other backends are still
    + * using this origin.
    + */
    
    The second sentence seems contradictory to the logic, as we are
    resetting the PID here regardless of whether other backends are using
    it.
    
    Suggestion:
    /*
     * Reset the PID only if the current backend is the first to set up this
     * origin. This avoids clearing the first process's PID when any other
     * session releases the origin.
     */
    
    4)
    + * 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.
    + */
    
    Slight tweak:
    
    /*
     * The origin is in use, but PID is not recorded. This can happen if
     * the process that originally acquired the origin exited without releasing it.
     * To ensure correctness, other processes cannot acquire the origin
     * until all processes currently using it have released it.
    
    thanks
    Shveta
    
    
    
    
  37. RE: [Patch] add new parameter to pg_replication_origin_session_setup

    Hayato Kuroda (Fujitsu) <kuroda.hayato@fujitsu.com> — 2026-01-14T03:43:47Z

    Dear Shveta,
    
    > 1)
    > +step s1_reset: SELECT pg_replication_origin_session_reset();
    > 
    > After the above step, please add a step to attempt dropping the
    > replication origin. The original issue was that once s1 releases the
    > origin, it becomes eligible for dropping, so the test should
    > explicitly verify this behavior.
    
    I think it is bit difficult because pg_replication_origin_drop() has PID in the
    ERROR message. Also, this patch prevents first process resets the origin, i.e.,
    the exact same situation won't happen anymore. Not fixed.
    
    > 2)
    > Also before the above step, please add a step where s0 tries to reset
    > the origin while s1 is still acquiring it. It is needed to cover the
    > path where s0 should fail to release origin.
    
    The step has already existed, see below.
    
    ```
    step s0_reset: SELECT pg_replication_origin_session_reset();
    ERROR:  cannot reset replication origin with ID 1 because it is still in use by other processes
    step s1_reset: SELECT pg_replication_origin_session_reset();
    pg_replication_origin_session_reset
    -----------------------------------
                                       
    (1 row)
    ```
    
    Others are corrected and adjusted by me, see the attached.
    0001 and 0002 are combined because no one claimed them.
    
    Best regards,
    Hayato Kuroda
    FUJITSU LIMITED
    
    
  38. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    shveta malik <shveta.malik@gmail.com> — 2026-01-14T04:08:55Z

    On Wed, Jan 14, 2026 at 9:13 AM Hayato Kuroda (Fujitsu)
    <kuroda.hayato@fujitsu.com> wrote:
    >
    > Dear Shveta,
    >
    > > 1)
    > > +step s1_reset: SELECT pg_replication_origin_session_reset();
    > >
    > > After the above step, please add a step to attempt dropping the
    > > replication origin. The original issue was that once s1 releases the
    > > origin, it becomes eligible for dropping, so the test should
    > > explicitly verify this behavior.
    >
    > I think it is bit difficult because pg_replication_origin_drop() has PID in the
    > ERROR message. Also, this patch prevents first process resets the origin, i.e.,
    > the exact same situation won't happen anymore. Not fixed.
    >
    
    Okay.
    
    > > 2)
    > > Also before the above step, please add a step where s0 tries to reset
    > > the origin while s1 is still acquiring it. It is needed to cover the
    > > path where s0 should fail to release origin.
    >
    > The step has already existed, see below.
    >
    
    Okay, sorry I missed it somehow.
    
    > ```
    > step s0_reset: SELECT pg_replication_origin_session_reset();
    > ERROR:  cannot reset replication origin with ID 1 because it is still in use by other processes
    > step s1_reset: SELECT pg_replication_origin_session_reset();
    > pg_replication_origin_session_reset
    > -----------------------------------
    >
    > (1 row)
    > ```
    >
    > Others are corrected and adjusted by me, see the attached.
    > 0001 and 0002 are combined because no one claimed them.
    >
    
    Thanks. The patch LGTM.
    
    thanks
    Shveta
    
    
    
    
  39. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-01-14T09:58:23Z

    On Wed, Jan 14, 2026 at 9:13 AM Hayato Kuroda (Fujitsu)
    <kuroda.hayato@fujitsu.com> wrote:
    >
    > Others are corrected and adjusted by me, see the attached.
    > 0001 and 0002 are combined because no one claimed them.
    >
    
    A change similar to what you did in replorigin_state_clear() was
    required in replorigin_advance() to prevent advancing origin via APIs
    when it is still in use. I made that change and pushed the patch.
    Thanks for working on it.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  40. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Heikki Linnakangas <hlinnaka@iki.fi> — 2026-02-03T19:08:21Z

    The new error message is not great:
    
    postgres=# select pg_replication_origin_session_setup('myorigin', 12345678);
    ERROR:  could not find replication state slot for replication origin 
    with OID 1 which was acquired by 12345678
    
    Firstly, replication origin is not an OID. Secondly, it's a little 
    confusing because the "replication state slot" is in fact present. 
    However, it's currently inactive, i.e. not "acquired" by the given PID.
    
    I propose to change that to:
    
    postgres=# select pg_replication_origin_session_setup('myorigin', 12345678);
    ERROR:  replication origin with ID 1 is not active for PID 12345678
    
    That's more in line with this neighboring message:
    
    ERROR:  replication origin with ID 1 is already active for PID 701228
    
    
    I also wonder if the error code is appropriate. That error uses 
    ERRCODE_OBJECT_IN_USE, but if the problem is that the origin is 
    currently *not* active, that seems backwards. I didn't change that in 
    the attached patch, but it's something to think about.
    
    
    The second patch rearranges the if-else statements to check those 
    conditions. I found the current logic hard to follow, this makes them 
    feel more natural, in my opinion at least. It has one user-visible 
    effect: If you call the function with acquired_pid != 0 and the origin 
    has no state slot, *and* there are no free slots, you previously got 
    this error:
    
    postgres=# select pg_replication_origin_session_setup('other', 123);
    ERROR:  could not find free replication state slot for replication 
    origin with ID 2
    HINT:  Increase "max_active_replication_origins" and try again.
    
    Now you get this:
    
    postgres=# select pg_replication_origin_session_setup('other', 123);
    ERROR:  cannot use PID 123 for inactive replication origin with ID 2
    
    Both error messages are more or less appropriate in that situation, but 
    I think the new behavior is slightly better. The fact that the origin is 
    inactive feels like the bigger problem here.
    
    - Heikki
    
  41. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    shveta malik <shveta.malik@gmail.com> — 2026-02-04T06:02:29Z

    On Wed, Feb 4, 2026 at 12:38 AM Heikki Linnakangas <hlinnaka@iki.fi> wrote:
    >
    > The new error message is not great:
    >
    > postgres=# select pg_replication_origin_session_setup('myorigin', 12345678);
    > ERROR:  could not find replication state slot for replication origin
    > with OID 1 which was acquired by 12345678
    >
    > Firstly, replication origin is not an OID. Secondly, it's a little
    > confusing because the "replication state slot" is in fact present.
    > However, it's currently inactive, i.e. not "acquired" by the given PID.
    >
    > I propose to change that to:
    >
    > postgres=# select pg_replication_origin_session_setup('myorigin', 12345678);
    > ERROR:  replication origin with ID 1 is not active for PID 12345678
    >
    > That's more in line with this neighboring message:
    >
    > ERROR:  replication origin with ID 1 is already active for PID 701228
    
    Thank You for your suggestions here. The suggested error message looks
    better. Thus patch001 LGTM.
    
    >
    > I also wonder if the error code is appropriate. That error uses
    > ERRCODE_OBJECT_IN_USE, but if the problem is that the origin is
    > currently *not* active, that seems backwards. I didn't change that in
    > the attached patch, but it's something to think about.
    
    I agree that ERRCODE_OBJECT_IN_USE doesn’t seem like the best fit in
    below code. IMO, ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE would be
    more suitable.But let's hear from others.
    
    if (curstate->acquired_by != acquired_by)
    {
    ereport(ERROR,
    (errcode(ERRCODE_OBJECT_IN_USE),
    errmsg("replication origin with ID %d is not active for PID %d",
    curstate->roident, acquired_by)));
    }
    
    >
    > The second patch rearranges the if-else statements to check those
    > conditions. I found the current logic hard to follow, this makes them
    > feel more natural, in my opinion at least.
    
    I’m not fully convinced that it makes the code clearer or better to
    understand. For example, consider the following error case:
    
    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)));
    
    
    The condition was self explanatory earlier. The condition has now been
    rewritten (or reduced) to:
    if (acquired_by == 0 && curstate->refcount > 0)
    
    However, this is not exactly the same as the earlier logic. On closer
    inspection, the condition 'curstate->acquired_by == 0', while no
    longer stated explicitly, was implicitly guaranteed by the preceding
    error block:
    
    if (curstate->acquired_by != 0)
        ERROR;
    
    One way to make this clearer would be to structure the logic as:
    
    if (curstate->acquired_by != 0)
        ERROR;
    else if (curstate->refcount > 0)
        ERROR;
    
    Even then, it is still not clear why this error (the case where
    curstate->refcount > 0 and curstate->acquired_by == 0) is raised only
    when acquired_by == 0, or how the same situation is expected to be
    handled when acquired_by != 0. The earlier code was clearer in this
    regard (at least to me), as it first handled the
    'curstate->acquired_by != acquired_by' case, making the overall logic
    somehow easier to understand. Perhaps we can try by adding a comment
    or restructure in some other way if possible and needed?
    
    > It has one user-visible
    > effect: If you call the function with acquired_pid != 0 and the origin
    > has no state slot, *and* there are no free slots, you previously got
    > this error:
    >
    > postgres=# select pg_replication_origin_session_setup('other', 123);
    > ERROR:  could not find free replication state slot for replication
    > origin with ID 2
    > HINT:  Increase "max_active_replication_origins" and try again.
    >
    > Now you get this:
    >
    > postgres=# select pg_replication_origin_session_setup('other', 123);
    > ERROR:  cannot use PID 123 for inactive replication origin with ID 2
    >
    > Both error messages are more or less appropriate in that situation, but
    > I think the new behavior is slightly better. The fact that the origin is
    > inactive feels like the bigger problem here.
    
    I am okay with this change though. Let's see what others have to say.
    
    thanks
    Shveta
    
    
    
    
  42. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-02-11T05:23:02Z

    On Wed, Feb 4, 2026 at 12:38 AM Heikki Linnakangas <hlinnaka@iki.fi> wrote:
    >
    > The new error message is not great:
    >
    > postgres=# select pg_replication_origin_session_setup('myorigin', 12345678);
    > ERROR:  could not find replication state slot for replication origin
    > with OID 1 which was acquired by 12345678
    >
    > Firstly, replication origin is not an OID. Secondly, it's a little
    > confusing because the "replication state slot" is in fact present.
    > However, it's currently inactive, i.e. not "acquired" by the given PID.
    >
    > I propose to change that to:
    >
    > postgres=# select pg_replication_origin_session_setup('myorigin', 12345678);
    > ERROR:  replication origin with ID 1 is not active for PID 12345678
    >
    > That's more in line with this neighboring message:
    >
    > ERROR:  replication origin with ID 1 is already active for PID 701228
    >
    
    +1 for the new message.
    
    >
    > I also wonder if the error code is appropriate. That error uses
    > ERRCODE_OBJECT_IN_USE, but if the problem is that the origin is
    > currently *not* active, that seems backwards. I didn't change that in
    > the attached patch, but it's something to think about.
    >
    
    The other way to look at this is that the origin is already active for
    some other pid which is not the same as what is given by the user in
    the second parameter, so OBJECT_IN_USE sounds okay from that angle.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  43. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-02-11T10:10:50Z

    On Wed, Feb 4, 2026 at 11:32 AM shveta malik <shveta.malik@gmail.com> wrote:
    >
    > On Wed, Feb 4, 2026 at 12:38 AM Heikki Linnakangas <hlinnaka@iki.fi> wrote:
    > >
    >
    > >
    > > The second patch rearranges the if-else statements to check those
    > > conditions. I found the current logic hard to follow, this makes them
    > > feel more natural, in my opinion at least.
    >
    > I’m not fully convinced that it makes the code clearer or better to
    > understand. For example, consider the following error case:
    >
    > 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)));
    >
    >
    > The condition was self explanatory earlier. The condition has now been
    > rewritten (or reduced) to:
    > if (acquired_by == 0 && curstate->refcount > 0)
    >
    > However, this is not exactly the same as the earlier logic. On closer
    > inspection, the condition 'curstate->acquired_by == 0', while no
    > longer stated explicitly, was implicitly guaranteed by the preceding
    > error block:
    >
    > if (curstate->acquired_by != 0)
    >     ERROR;
    >
    > One way to make this clearer would be to structure the logic as:
    >
    > if (curstate->acquired_by != 0)
    >     ERROR;
    > else if (curstate->refcount > 0)
    >     ERROR;
    >
    > Even then, it is still not clear why this error (the case where
    > curstate->refcount > 0 and curstate->acquired_by == 0) is raised only
    > when acquired_by == 0, or how the same situation is expected to be
    > handled when acquired_by != 0. The earlier code was clearer in this
    > regard (at least to me), as it first handled the
    > 'curstate->acquired_by != acquired_by' case, making the overall logic
    > somehow easier to understand. Perhaps we can try by adding a comment
    > or restructure in some other way if possible and needed?
    >
    
    I see your point but one advantage with the proposed code change is
    that it started to appear that we can extend this part of code easily
    in the future as it separates most of the handling related to when a
    user has given acquired_by parameter's value as zero and non-zero.
    
    > > It has one user-visible
    > > effect: If you call the function with acquired_pid != 0 and the origin
    > > has no state slot, *and* there are no free slots, you previously got
    > > this error:
    > >
    > > postgres=# select pg_replication_origin_session_setup('other', 123);
    > > ERROR:  could not find free replication state slot for replication
    > > origin with ID 2
    > > HINT:  Increase "max_active_replication_origins" and try again.
    > >
    > > Now you get this:
    > >
    > > postgres=# select pg_replication_origin_session_setup('other', 123);
    > > ERROR:  cannot use PID 123 for inactive replication origin with ID 2
    > >
    > > Both error messages are more or less appropriate in that situation, but
    > > I think the new behavior is slightly better. The fact that the origin is
    > > inactive feels like the bigger problem here.
    >
    > I am okay with this change though. Let's see what others have to say.
    >
    
    Either message is fine with me in this situation.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  44. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    shveta malik <shveta.malik@gmail.com> — 2026-02-11T11:39:26Z

    On Wed, Feb 11, 2026 at 3:41 PM Amit Kapila <amit.kapila16@gmail.com> wrote:
    >
    > On Wed, Feb 4, 2026 at 11:32 AM shveta malik <shveta.malik@gmail.com> wrote:
    > >
    > > On Wed, Feb 4, 2026 at 12:38 AM Heikki Linnakangas <hlinnaka@iki.fi> wrote:
    > > >
    > >
    > > >
    > > > The second patch rearranges the if-else statements to check those
    > > > conditions. I found the current logic hard to follow, this makes them
    > > > feel more natural, in my opinion at least.
    > >
    > > I’m not fully convinced that it makes the code clearer or better to
    > > understand. For example, consider the following error case:
    > >
    > > 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)));
    > >
    > >
    > > The condition was self explanatory earlier. The condition has now been
    > > rewritten (or reduced) to:
    > > if (acquired_by == 0 && curstate->refcount > 0)
    > >
    > > However, this is not exactly the same as the earlier logic. On closer
    > > inspection, the condition 'curstate->acquired_by == 0', while no
    > > longer stated explicitly, was implicitly guaranteed by the preceding
    > > error block:
    > >
    > > if (curstate->acquired_by != 0)
    > >     ERROR;
    > >
    > > One way to make this clearer would be to structure the logic as:
    > >
    > > if (curstate->acquired_by != 0)
    > >     ERROR;
    > > else if (curstate->refcount > 0)
    > >     ERROR;
    > >
    > > Even then, it is still not clear why this error (the case where
    > > curstate->refcount > 0 and curstate->acquired_by == 0) is raised only
    > > when acquired_by == 0, or how the same situation is expected to be
    > > handled when acquired_by != 0. The earlier code was clearer in this
    > > regard (at least to me), as it first handled the
    > > 'curstate->acquired_by != acquired_by' case, making the overall logic
    > > somehow easier to understand. Perhaps we can try by adding a comment
    > > or restructure in some other way if possible and needed?
    > >
    >
    > I see your point but one advantage with the proposed code change is
    > that it started to appear that we can extend this part of code easily
    > in the future as it separates most of the handling related to when a
    > user has given acquired_by parameter's value as zero and non-zero.
    
    Okay, yes. So I am okay with it. The slight change I suggested (if to
    else-if) and a comment will make it more clean.
    
    >
    > > > It has one user-visible
    > > > effect: If you call the function with acquired_pid != 0 and the origin
    > > > has no state slot, *and* there are no free slots, you previously got
    > > > this error:
    > > >
    > > > postgres=# select pg_replication_origin_session_setup('other', 123);
    > > > ERROR:  could not find free replication state slot for replication
    > > > origin with ID 2
    > > > HINT:  Increase "max_active_replication_origins" and try again.
    > > >
    > > > Now you get this:
    > > >
    > > > postgres=# select pg_replication_origin_session_setup('other', 123);
    > > > ERROR:  cannot use PID 123 for inactive replication origin with ID 2
    > > >
    > > > Both error messages are more or less appropriate in that situation, but
    > > > I think the new behavior is slightly better. The fact that the origin is
    > > > inactive feels like the bigger problem here.
    > >
    > > I am okay with this change though. Let's see what others have to say.
    > >
    >
    > Either message is fine with me in this situation.
    >
    > --
    > With Regards,
    > Amit Kapila.
    
    
    
    
  45. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-02-16T08:52:57Z

    On Wed, Feb 11, 2026 at 10:53 AM Amit Kapila <amit.kapila16@gmail.com> wrote:
    >
    > On Wed, Feb 4, 2026 at 12:38 AM Heikki Linnakangas <hlinnaka@iki.fi> wrote:
    > >
    > > The new error message is not great:
    > >
    > > postgres=# select pg_replication_origin_session_setup('myorigin', 12345678);
    > > ERROR:  could not find replication state slot for replication origin
    > > with OID 1 which was acquired by 12345678
    > >
    > > Firstly, replication origin is not an OID. Secondly, it's a little
    > > confusing because the "replication state slot" is in fact present.
    > > However, it's currently inactive, i.e. not "acquired" by the given PID.
    > >
    > > I propose to change that to:
    > >
    > > postgres=# select pg_replication_origin_session_setup('myorigin', 12345678);
    > > ERROR:  replication origin with ID 1 is not active for PID 12345678
    > >
    > > That's more in line with this neighboring message:
    > >
    > > ERROR:  replication origin with ID 1 is already active for PID 701228
    > >
    >
    > +1 for the new message.
    >
    
    Heikki, would you like to take care of improvements proposed by you?
    Otherwise, I am happy to take care of them.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  46. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Michael Paquier <michael@paquier.xyz> — 2026-03-25T02:45:37Z

    On Mon, Feb 16, 2026 at 02:22:57PM +0530, Amit Kapila wrote:
    > Heikki, would you like to take care of improvements proposed by you?
    > Otherwise, I am happy to take care of them.
    
    This thread has stalled.  Heikki, Amit, are there any actions planned
    by the end of the release cycle?
    --
    Michael
    
  47. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-03-25T03:02:51Z

    On Wed, Mar 25, 2026 at 8:15 AM Michael Paquier <michael@paquier.xyz> wrote:
    >
    > On Mon, Feb 16, 2026 at 02:22:57PM +0530, Amit Kapila wrote:
    > > Heikki, would you like to take care of improvements proposed by you?
    > > Otherwise, I am happy to take care of them.
    >
    > This thread has stalled.  Heikki, Amit, are there any actions planned
    > by the end of the release cycle?
    >
    
    I'll take care of this in the next few days unless I see any
    response/feedback from Heikki or others.
    
    -- 
    With Regards,
    Amit Kapila.
    
    
    
    
  48. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-03-25T08:21:14Z

    On Wed, Feb 11, 2026 at 5:09 PM shveta malik <shveta.malik@gmail.com> wrote:
    >
    > On Wed, Feb 11, 2026 at 3:41 PM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > >
    > >
    > > I see your point but one advantage with the proposed code change is
    > > that it started to appear that we can extend this part of code easily
    > > in the future as it separates most of the handling related to when a
    > > user has given acquired_by parameter's value as zero and non-zero.
    >
    > Okay, yes. So I am okay with it. The slight change I suggested (if to
    > else-if) and a comment will make it more clean.
    >
    
    I have tried to address both your suggestions in the attached. See, if
    this looks okay to you now?
    
    -- 
    With Regards,
    Amit Kapila.
    
  49. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    shveta malik <shveta.malik@gmail.com> — 2026-03-25T09:33:27Z

    On Wed, Mar 25, 2026 at 1:51 PM Amit Kapila <amit.kapila16@gmail.com> wrote:
    >
    > On Wed, Feb 11, 2026 at 5:09 PM shveta malik <shveta.malik@gmail.com> wrote:
    > >
    > > On Wed, Feb 11, 2026 at 3:41 PM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > > >
    > > >
    > > > I see your point but one advantage with the proposed code change is
    > > > that it started to appear that we can extend this part of code easily
    > > > in the future as it separates most of the handling related to when a
    > > > user has given acquired_by parameter's value as zero and non-zero.
    > >
    > > Okay, yes. So I am okay with it. The slight change I suggested (if to
    > > else-if) and a comment will make it more clean.
    > >
    >
    > I have tried to address both your suggestions in the attached. See, if
    > this looks okay to you now?
    >
    
    LGTM now, thanks!
    
    thanks
    Shveta
    
    
    
    
  50. Re: [Patch] add new parameter to pg_replication_origin_session_setup

    Amit Kapila <amit.kapila16@gmail.com> — 2026-03-26T06:40:08Z

    On Wed, Mar 25, 2026 at 3:03 PM shveta malik <shveta.malik@gmail.com> wrote:
    >
    > On Wed, Mar 25, 2026 at 1:51 PM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > >
    > > On Wed, Feb 11, 2026 at 5:09 PM shveta malik <shveta.malik@gmail.com> wrote:
    > > >
    > > > On Wed, Feb 11, 2026 at 3:41 PM Amit Kapila <amit.kapila16@gmail.com> wrote:
    > > > >
    > > > >
    > > > > I see your point but one advantage with the proposed code change is
    > > > > that it started to appear that we can extend this part of code easily
    > > > > in the future as it separates most of the handling related to when a
    > > > > user has given acquired_by parameter's value as zero and non-zero.
    > > >
    > > > Okay, yes. So I am okay with it. The slight change I suggested (if to
    > > > else-if) and a comment will make it more clean.
    > > >
    > >
    > > I have tried to address both your suggestions in the attached. See, if
    > > this looks okay to you now?
    > >
    >
    > LGTM now, thanks!
    >
    
    Pushed.
    
    -- 
    With Regards,
    Amit Kapila.