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]