This is an automated email from the ASF dual-hosted git repository.

yjhjstz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git


The following commit(s) were added to refs/heads/main by this push:
     new f9ca4fac587 SIGSEGV in getCdbComponentInfo() when standby coordinator 
is on dedicated host (#1702)
f9ca4fac587 is described below

commit f9ca4fac587c4d529d33c5d47eecaada9328f2a4
Author: jangjang <[email protected]>
AuthorDate: Thu Apr 30 04:30:08 2026 +0900

    SIGSEGV in getCdbComponentInfo() when standby coordinator is on dedicated 
host (#1702)
    
    * Fix null dereference on dedicated hot standby coordinator
    
    getCdbComponentInfo() populates hostPrimaryCountHash with primary hosts 
only.
    When IS_HOT_STANDBY_QD() is true, mirror and standby hosts are also looked 
up
    in the hash but return NULL on dedicated standby nodes that host no primary
    segments. Replace Assert(found) with a null-safe check to prevent SIGSEGV.
---
 src/backend/cdb/cdbutil.c               | 18 ++++++++++++++----
 src/test/regress/expected/vacuum_gp.out |  9 ++++-----
 src/test/regress/sql/vacuum_gp.sql      |  3 +++
 3 files changed, 21 insertions(+), 9 deletions(-)

diff --git a/src/backend/cdb/cdbutil.c b/src/backend/cdb/cdbutil.c
index fbf3f8900f2..2503049b434 100644
--- a/src/backend/cdb/cdbutil.c
+++ b/src/backend/cdb/cdbutil.c
@@ -593,8 +593,13 @@ getCdbComponentInfo(void)
                        continue;
 
                hsEntry = (HostPrimaryCountEntry *) 
hash_search(hostPrimaryCountHash, cdbInfo->config->hostname, HASH_FIND, &found);
-               Assert(found);
-               cdbInfo->hostPrimaryCount = hsEntry->segmentCount;
+               Assert(found || IS_HOT_STANDBY_QD());
+               /*
+                * Standby and mirror entries can legitimately live on hosts 
that do not
+                * own any primary segments. In that case the lookup is absent 
and the
+                * count should be treated as zero instead of dereferencing a 
NULL entry.
+                */
+               cdbInfo->hostPrimaryCount = found ? hsEntry->segmentCount : 0;
        }
 
        for (i = 0; i < component_databases->total_entry_dbs; i++)
@@ -605,8 +610,13 @@ getCdbComponentInfo(void)
                        continue;
 
                hsEntry = (HostPrimaryCountEntry *) 
hash_search(hostPrimaryCountHash, cdbInfo->config->hostname, HASH_FIND, &found);
-               Assert(found);
-               cdbInfo->hostPrimaryCount = hsEntry->segmentCount;
+               Assert(found || IS_HOT_STANDBY_QD());
+               /*
+                * Standby and mirror entries can legitimately live on hosts 
that do not
+                * own any primary segments. In that case the lookup is absent 
and the
+                * count should be treated as zero instead of dereferencing a 
NULL entry.
+                */
+               cdbInfo->hostPrimaryCount = found ? hsEntry->segmentCount : 0;
        }
 
        hash_destroy(hostPrimaryCountHash);
diff --git a/src/test/regress/expected/vacuum_gp.out 
b/src/test/regress/expected/vacuum_gp.out
index daeb2504559..cac825d0cd4 100644
--- a/src/test/regress/expected/vacuum_gp.out
+++ b/src/test/regress/expected/vacuum_gp.out
@@ -446,6 +446,8 @@ create table relcache_leak_in_motion(v1 int);
 NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'v1' 
as the Apache Cloudberry data distribution key for this table.
 HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make 
sure column(s) chosen are the optimal data distribution key to minimize skew.
 insert into relcache_leak_in_motion values(generate_series(0, 10000));
+BEGIN;
+SET LOCAL synchronous_commit = local;
 SELECT gp_inject_fault('interconnect_stop_recv_chunk', 'interrupt', dbid)
   FROM gp_segment_configuration WHERE content = -1 and role='p';
  gp_inject_fault 
@@ -457,11 +459,8 @@ analyze relcache_leak_in_motion;
 ERROR:  canceling statement due to user request
 SELECT gp_inject_fault('interconnect_stop_recv_chunk', 'reset', dbid)
   FROM gp_segment_configuration WHERE content = -1 and role='p';
- gp_inject_fault 
------------------
- Success:
-(1 row)
-
+ERROR:  current transaction is aborted, commands ignored until end of 
transaction block
+COMMIT;
 -- start_ignore
 drop table if exists relcache_leak_in_motion;
 -- end_ignore
diff --git a/src/test/regress/sql/vacuum_gp.sql 
b/src/test/regress/sql/vacuum_gp.sql
index 198a80f4a93..ed4bfe4f699 100644
--- a/src/test/regress/sql/vacuum_gp.sql
+++ b/src/test/regress/sql/vacuum_gp.sql
@@ -298,11 +298,14 @@ drop table if exists relcache_leak_in_motion;
 -- end_ignore
 create table relcache_leak_in_motion(v1 int);
 insert into relcache_leak_in_motion values(generate_series(0, 10000));
+BEGIN;
+SET LOCAL synchronous_commit = local;
 SELECT gp_inject_fault('interconnect_stop_recv_chunk', 'interrupt', dbid)
   FROM gp_segment_configuration WHERE content = -1 and role='p';
 analyze relcache_leak_in_motion;
 SELECT gp_inject_fault('interconnect_stop_recv_chunk', 'reset', dbid)
   FROM gp_segment_configuration WHERE content = -1 and role='p';
+COMMIT;
 -- start_ignore
 drop table if exists relcache_leak_in_motion;
 -- end_ignore


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to