I am running pgpool2 with PostgreSQL streaming replication and a larger topology:
- pgpool2 version: 4.7.1
- PostgreSQL version: 17.9
- Backend topology: 1 primary + 11 standbys
- Backend mode: streaming replication
I use pgpool2 exclusively for load balancing. I would like to configure cascading replication for 5 of the standbys, as described in the PostgreSQL documentation: https://www.postgresql.org/docs/current/warm-standby.html#CASCADING-REPLICATION
Example topology
host1 primary
host2 standby, replicates directly from host1
host3 standby, replicates directly from host1
host4 standby, replicates directly from host1
host5 standby, replicates directly from host1
host6 standby, replicates directly from host1
host7 standby, replicates directly from host1
host8 cascading standby, replicates from host7
host9 cascading standby, replicates from host7
host10 cascading standby, replicates from host7
host11 cascading standby, replicates from host7
host12 cascading standby, replicates from host7
So the intended replication tree is:
host1
├── host2
├── host3
├── host4
├── host5
├── host6
└── host7
├── host8
├── host9
├── host10
├── host11
└── host12
Issue
After enabling cascading replication, pgpool2 repeatedly logs messages from sr_check_worker, and some standby nodes no longer show values in the replication_state and replication_sync_state columns.
Actual behavior
After configuring 5 standbys to replicate from another standby, pgpool.log repeatedly contains entries like this:
2026-04-29 09:12:52.393: sr_check_worker pid 127667: LOG: verify_backend_node_status: primary 6 does not connect to standby 1
2026-04-29 09:12:52.393: sr_check_worker pid 127667: DETAIL: pgpool.conf backend: (host="host7" port=5432) does not match PostgreSQL primary_conninfo: (host="host1" port=5432)
2026-04-29 09:12:52.394: sr_check_worker pid 127667: LOG: verify_backend_node_status: primary 6 does not connect to standby 2
2026-04-29 09:12:52.394: DETAIL: pgpool.conf backend: (host="host7" port=5432) does not match PostgreSQL primary_conninfo: (host="host1" port=5432)
2026-04-29 09:12:52.395: sr_check_worker pid 127667: LOG: verify_backend_node_status: primary 6 does not connect to standby 3
2026-04-29 09:12:52.395: DETAIL: pgpool.conf backend: (host="host7" port=5432) does not match PostgreSQL primary_conninfo: (host="host1" port=5432)
2026-04-29 09:12:52.396: sr_check_worker pid 127667: LOG: verify_backend_node_status: primary 6 does not connect to standby 4
2026-04-29 09:12:52.396: DETAIL: pgpool.conf backend: (host="host7" port=5432) does not match PostgreSQL primary_conninfo: (host="host1" port=5432)
2026-04-29 09:12:52.398: sr_check_worker pid 127667: LOG: verify_backend_node_status: primary 6 does not connect to standby 5
2026-04-29 09:12:52.398: DETAIL: pgpool.conf backend: (host="host7" port=5432) does not match PostgreSQL primary_conninfo: (host="host1" port=5432)
2026-04-29 09:12:52.484: sr_check_worker pid 127667: LOG: verify_backend_node_status: primary 6 owns only 6 standbys out of 11
It looks like pgpool2 is checking whether every standby's primary_conninfo points to the same backend, and treats a cascading topology as incorrect because some standbys intentionally point to another standby.
Example of SHOW POOL NODES;
node_id | hostname | port | status | pg_status | lb_weight | role | pg_role | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change
---------+----------+------+--------+-----------+-----------+---------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
0 | host1 | 5432 | up | up | 0.166667 | primary | primary | 428 | false | 0 | | | 2026-04-29 09:20:29
1 | host2 | 5432 | up | up | 0.166667 | standby | standby | 89 | true | 0.000000 second | streaming | sync | 2026-04-29 09:20:29
2 | host3 | 5432 | up | up | 0.166667 | standby | standby | 2 | false | 0.000000 second | streaming | potential | 2026-04-29 09:20:29
3 | host4 | 5432 | up | up | 0.166667 | standby | standby | 87 | false | 0.000000 second | streaming | potential | 2026-04-29 09:20:29
4 | host5 | 5432 | up | up | 0.166667 | standby | standby | 0 | false | 0.000000 second | streaming | potential | 2026-04-29 09:20:29
5 | host6 | 5432 | up | up | 0.166667 | standby | standby | 2 | false | 0.000000 second | streaming | potential | 2026-04-29 09:20:29
6 | host7 | 5432 | up | up | 0.000000 | standby | standby | 0 | false | 0.000000 second | streaming | async | 2026-04-29 09:20:29
7 | host8 | 5432 | up | up | 0.000000 | standby | standby | 0 | false | 0.000000 second | | | 2026-04-29 09:20:29
8 | host9 | 5432 | up | up | 0.000000 | standby | standby | 0 | false | 0.000000 second | | | 2026-04-29 09:20:29
9 | host10 | 5432 | up | up | 0.000000 | standby | standby | 0 | false | 0.000000 second | | | 2026-04-29 09:20:29
10 | host11 | 5432 | up | up | 0.000000 | standby | standby | 0 | false | 0.000000 second | | | 2026-04-29 09:20:29
11 | host12 | 5432 | up | up | 0.000000 | standby | standby | 0 | false | 0.000000 second | | | 2026-04-29 09:20:29
For the cascading standbys, the replication_state and replication_sync_state columns are empty.
Expected behavior
- pgpool2 should support PostgreSQL cascading replication in streaming replication mode.
- For cascading standbys, pgpool2 should recognize that
primary_conninfo may point to an upstream standby rather than the top-level primary.
- pgpool2 should not repeatedly log warnings/errors for a valid cascading replication topology.
- The
replication_state and replication_sync_state columns should also be populated where pgpool2 can determine the replication status.
I am running pgpool2 with PostgreSQL streaming replication and a larger topology:
I use pgpool2 exclusively for load balancing. I would like to configure cascading replication for 5 of the standbys, as described in the PostgreSQL documentation: https://www.postgresql.org/docs/current/warm-standby.html#CASCADING-REPLICATION
Example topology
So the intended replication tree is:
Issue
After enabling cascading replication, pgpool2 repeatedly logs messages from
sr_check_worker, and some standby nodes no longer show values in thereplication_stateandreplication_sync_statecolumns.Actual behavior
After configuring 5 standbys to replicate from another standby, pgpool.log repeatedly contains entries like this:
It looks like pgpool2 is checking whether every standby's
primary_conninfopoints to the same backend, and treats a cascading topology as incorrect because some standbys intentionally point to another standby.Example of
SHOW POOL NODES;For the cascading standbys, the
replication_stateandreplication_sync_statecolumns are empty.Expected behavior
primary_conninfomay point to an upstream standby rather than the top-level primary.replication_stateandreplication_sync_statecolumns should also be populated where pgpool2 can determine the replication status.