Fix sr worker to not send wrong query to standby server in corner case.
authorTatsuo Ishii <ishii@sraoss.co.jp>
Sun, 5 Feb 2023 07:13:15 +0000 (16:13 +0900)
committerTatsuo Ishii <ishii@sraoss.co.jp>
Sun, 5 Feb 2023 07:13:15 +0000 (16:13 +0900)
When ALWAYS_PRIMARY flag is set, PRIMARY_NODE_ID macro returns node
id, rather than -1 even if the primary is down. This confuses the test
if a node is primary or not, because PRIMARY_NODE_ID macro returns
main node id.  In this case streaming replication delay check worker
sends "SELECT pg_current_wal_lsn()" or "SELECT
pg_current_xlog_location()" depending on PostgreSQL's version to
standby which of course raises an error.

To fix this, test the primary node is down or not, and if it's down,
skip the replication delay loop. If primary is down, there's no point
to perform streaming replication delay checking anyway.

Discussion: https://www.pgpool.net/pipermail/pgpool-hackers/2023-February/004279.html
Backpatch-through: 4.0

src/streaming_replication/pool_worker_child.c

index 746f1817bfe1ffd4a426d9063aae34712e9fac92..92411ea9ab02b1b9cf3276dc1ce1b86d78f2ffef 100644 (file)
@@ -350,6 +350,20 @@ check_replication_time_lag(void)
                return;
        }
 
+       if (!VALID_BACKEND(REAL_PRIMARY_NODE_ID))
+       {
+               /*
+                * No need to check replication delay if primary is down. This could
+                * happen if ALWAYS_PRIMARY flag is on because REAL_PRIMARY_NODE_ID
+                * macro returns the node id which ALWAYS_PRIMARY flag is set to.  If
+                * we do not check this, subsequent test (i == PRIMARY_NODE_ID) in the
+                * for loop below will return unexpected result because
+                * PRIMARY_NODE_ID macro returns MAIN_NODE_ID, which could be a
+                * standby server.
+                */
+               return;
+       }
+
        /*
         * Register a error context callback to throw proper context message
         */