《GaussDB 内部探秘:进程、目录、端口与线程》

   昨天的文章直接介绍了 GaussDB 分布式集群的运维与诊断命令,对于还不熟悉 GaussDB 的读者来说,可能会显得有些突兀。鉴于本人写公众号的目的是通俗易懂地分享知识。因此,本文将从 进程、目录、端口三个方面入手,通过实际命令和输出结果,直观地分析 GaussDB 集群中的各个组件是如何运行的,帮助大家更清楚地了解和认识 GaussDB

为了照顾新读者,介绍一下此次的部署情况:

组件名称 gaussdb1 gaussdb2 gaussdb3
CM 集群管理 Primary Standby
GTM 全局事务 Standby Primary
CN 协调节点 ✅️ ✅️ ✅️
DN 数据节点 ✅️ ✅️ ✅️
ETCD ✅️ ✅️ ✅️

其中 DN 划分为 3 个 分片组(DN Group),每个分片由 1 个 Primary DN 和 2 个 Standby DN 组成,形成“一主两备”的三副本架构。每个节点上 3 个 DN, 1 个 Primary DN 和 2 个 Standby DN。第一个分片组的主 DN 在节点1 上,第二个分片组的 主 DN 在节点 2 上,第三个分片组的 主 DN 在节点 3 上。dn_masterdn_slavedn_dummy 分别是每个节点上的 数据文件所在的目录(名字可以随便取,只要同一节点区分出来就行)。

组件名称 gaussdb1 gaussdb2 gaussdb3
数据分片1 dn_master dn_slave dn_dummy
数据分片2 dn_dummy dn_master dn_slave
数据分片3 dn_slave dn_dummy dn_master

如果仍然有点迷糊,通过在三个节点查看 DN 的 三个端口号,比如端口为 33100 的 DN,Primary DN 位于 gaussdb1,其他两个 Standby DN: dn_slave 位于 gaussdb2dn_dummy 位于 gaussdb3 上。

[omm@gaussdb1 data]$ for d in dn_master dn_slave dn_dummy; do
>   echo "=== $d ==="
>   grep -E '^port' /data/gaussdb/data/$d/gaussdb.conf 2>/dev/null | head -3
> done
=== dn_master ===
port = '33100'				# (change requires restart)
=== dn_slave ===
port = '33140'				# (change requires restart)
=== dn_dummy ===
port = '33120'				# (change requires restart)

[omm@gaussdb2 ~]$ for d in dn_master dn_slave dn_dummy; do
>   echo "=== $d ==="
>   grep -E '^port' /data/gaussdb/data/$d/gaussdb.conf 2>/dev/null | head -3
> done
=== dn_master ===
port = '33120'				# (change requires restart)
=== dn_slave ===
port = '33100'				# (change requires restart)
=== dn_dummy ===
port = '33140'				# (change requires restart)


[omm@gaussdb3 ~]$ for d in dn_master dn_slave dn_dummy; do
>   echo "=== $d ==="
>   grep -E '^port' /data/gaussdb/data/$d/gaussdb.conf 2>/dev/null | head -3
> done
=== dn_master ===
port = '33140'				# (change requires restart)
=== dn_slave ===
port = '33120'				# (change requires restart)
=== dn_dummy ===
port = '33100'				# (change requires restart)

总结成如下表格:

IP 主机名 DN 目录名称 端口号 角色
192.168.182.141 gaussdb1 dn_ master 33100
192.168.182.142 gaussdb2 dn_slave 33100
192.168.182.143 gaussdb3 dn_dummy 33100
192.168.182.142 gaussdb2 dn_ master 33120
192.168.182.143 gaussdb3 dn_slave 33120
192.168.182.141 gaussdb1 dn_dummy 33120
192.168.182.143 gaussdb3 dn_ master 33140
192.168.182.141 gaussdb1 dn_slave 33140
192.168.182.142 gaussdb2 dn_dummy 33140

1. 进程状态

在 《GaussDB 505.1 分布式集群纯命令部署》 中,我们提到了分别部署了 CNDNETCDGTMCM 等组件。以下是这些组件对应的进程:

[root@gaussdb2 ~]# ps -ef |grep -E 'cm_server|cm_agent|gtm|datanode|coordinator|etcd'
omm         4504       1  2 07:54 ?        00:00:18 /data/gaussdb/install/app/bin/gs_gtm -D /data/gaussdb/data/gtm -M pending
omm         4507       1 17 07:54 ?        00:02:42 /data/gaussdb/install/app/bin/gaussdb --coordinator -D /data/gaussdb/data/cn
omm         4514       1  4 07:54 ?        00:00:36 /data/gaussdb/install/app/bin/cm_server
omm         4576       1  9 07:54 ?        00:01:29 /data/gaussdb/install/app/bin/gaussdb --datanode -D /data/gaussdb/data/dn_slave -M pending
omm         4670       1 31 07:54 ?        00:04:45 /data/gaussdb/install/app/bin/gaussdb --datanode -D /data/gaussdb/data/dn_master -M pending
omm         4736       1 10 07:54 ?        00:01:31 /data/gaussdb/install/app/bin/gaussdb --datanode -D /data/gaussdb/data/dn_dummy -M pending
omm        10484    2235  8 07:56 ?        00:01:08 /data/gaussdb/install/app/bin/cm_agent

omm         3886       1  8 07:53 ?        00:01:14 /data/gaussdb/install/app/bin/etcd -name etcd_7002 --data-dir /data/gaussdb/data/etcd --client-cert-auth --trusted-ca-file /data/gaussdb/install/app/share/sslcert/etcd/etcdca.crt --cert-file /data/gaussdb/data/etcd/etcd.crt --key-file /data/gaussdb/data/etcd/etcd.key --peer-client-cert-auth --peer-trusted-ca-file /data/gaussdb/install/app/share/sslcert/etcd/etcdca.crt --peer-cert-file /data/gaussdb/data/etcd/etcd.crt --peer-key-file /data/gaussdb/data/etcd/etcd.key -initial-advertise-peer-urls https://192.168.182.142:39380 -listen-peer-urls https://192.168.182.142:39380 -listen-client-urls https://192.168.182.142:39379 -advertise-client-urls https://192.168.182.142:39379 --election-timeout 5000 --heartbeat-interval 1000 --log-outputs stdout --quota-backend-bytes 8589934592 --auto-compaction-mode periodic --auto-compaction-retention 1h -initial-cluster-token etcd-cluster-omm --enable-v2=false -initial-cluster etcd_7001=https://192.168.182.141:38380,etcd_7002=https://192.168.182.142:39380,etcd_7003=https://192.168.182.143:36380 -initial-cluster-state new

每个节点上都有以下 6 类进程:

  • GTM/data/gaussdb/install/app/bin/gs_gtm -D /data/gaussdb/data/gtm -M pending
  • CNdata/gaussdb/install/app/bin/gaussdb --coordinator -D /data/gaussdb/data/cn
  • DN: 总共有三个进程,dn_master 是规划的第一个分片组的主 DN,dn_slavedn_dummy 是规划的第二个和第三个分片组的从 DN,这两个分片组的主 DN 分别在 第二个节点 和第三个节点上。
      • /data/gaussdb/install/app/bin/gaussdb --datanode -D /data/gaussdb/data/dn_slave -M pending
    • /data/gaussdb/install/app/bin/gaussdb --datanode -D /data/gaussdb/data/dn_master -M pending
    • /data/gaussdb/install/app/bin/gaussdb --datanode -D /data/gaussdb/data/dn_dummy -M pending
  • CM:分别包含 cm_servercm_agentom_monitor
    • /data/gaussdb/install/app/bin/cm_server
    • /data/gaussdb/install/app/bin/cm_agent
  • OM/data/gaussdb/install/app/bin/om_monitor -L /data/gaussdb/log/omm/cm/om_monitor
  • ETCD/data/gaussdb/install/app/bin/etcd -name etcd_7002 --data-dir /data/gaussdb/data/etcd
    因此,可以看到所有软件二进制目录都在 /data/gaussdb/install/app/bin/ 下,数据目录都在 /data/gaussdb/data/ 下面,这是我们在使用 gs_preinstall 预安装时候就确定好了的。软件安装目录跟 PG 差不多,postmasterpostgres 的软连接,在这里 gaussmastergaussdb 进程的软连接,但是接收到连接请求后,gaussmaster 不会 fork 出连接进程,而是线程。
[omm@gaussdb1 bin]$ pwd
/data/gaussdb/install/app/bin

[omm@gaussdb1 bin]$ ll
total 272580
-r-x------  1 omm dbgrp  16136640 Apr 18  2024 cm_agent
-rw-------  1 omm dbgrp         0 Aug 21 08:48 cm_agent.lock
-r-x------  1 omm dbgrp  15740752 Apr 18  2024 cm_ctl
-r-x------  1 omm dbgrp  16615624 Apr 18  2024 cm_server
-r-x------  1 omm dbgrp       125 Apr 18  2024 commits.txt
-r-x------  1 omm dbgrp   1873704 Apr 18  2024 dcf_tool
drwx------  2 omm dbgrp       205 Apr 18  2024 dependences
-r-x------  1 omm dbgrp      1166 Apr 18  2024 drop_caches.sh
-r-x------  1 omm dbgrp    657498 Apr 18  2024 echarts.common.min.js
-r-x------  1 omm dbgrp   1024695 Apr 18  2024 echarts.min.js
-r-x------  1 omm dbgrp   2011272 Apr 18  2024 ecpg
-r-x------  1 omm dbgrp    107128 Apr 18  2024 encrypt
-r-x------  1 omm dbgrp  24538136 Apr 18  2024 etcd
-r-x------  1 omm dbgrp  18671960 Apr 18  2024 etcdctl
-r-x------  1 omm dbgrp   1907048 Apr 18  2024 fio
-r-x------  1 omm dbgrp 110999384 Apr 18  2024 gaussdb
-r-x------  1 omm dbgrp        52 Apr 18  2024 gaussdb.version
lrwxrwxrwx  1 omm dbgrp         7 Aug 18 10:57 gaussmaster -> gaussdb
-r-x------  1 omm dbgrp    233152 Apr 18  2024 gds
-r-x------  1 omm dbgrp    207648 Apr 18  2024 gs_cgroup
-r-x------  1 omm dbgrp    101864 Apr 18  2024 gs_clean
-r-x------  1 omm dbgrp     98624 Apr 18  2024 gs_controldata
-r-x------  1 omm dbgrp    472616 Apr 18  2024 gs_ctl
-r-x------  1 omm dbgrp    689800 Apr 18  2024 gs_dump
-r-x------  1 omm dbgrp    286296 Apr 18  2024 gs_dumpall
lrwxrwxrwx  1 omm dbgrp         7 Aug 18 10:57 gs_encrypt -> gaussdb
-r-x------  1 omm dbgrp  16069280 Apr 18  2024 gs_gtm
-r-x------  1 omm dbgrp    460296 Apr 18  2024 gs_guc
-r-x------  1 omm dbgrp     95912 Apr 18  2024 gs_initcm

2. 目录分析

2.1 DN 目录

查看 DN 数据文件目录:

[root@gaussdb2 data]# ll
total 16
drwxr-xr-x  4 omm dbgrp   65 Aug 21 08:34 cm
drwx------ 22 omm dbgrp 4096 Aug 21 08:34 cn
drwx------ 22 omm dbgrp 4096 Aug 21 08:36 dn_dummy
drwx------ 22 omm dbgrp 4096 Aug 21 08:35 dn_master
drwx------ 22 omm dbgrp 4096 Aug 21 08:34 dn_slave
drwxr-xr-x  3 omm dbgrp   96 Aug 21 07:53 etcd
drwx------  3 omm dbgrp  175 Aug 21 08:33 gtm
[root@gaussdb2 data]# du -sh dn_*
1.1G	dn_dummy
1.3G	dn_master
1.1G	dn_slave
[root@gaussdb2 data]# ll dn_master/
total 6040
-rw------- 1 omm dbgrp     198 Aug 18 11:05 backup_label.old
drwx------ 6 omm dbgrp      54 Aug 18 14:36 base
-rw------- 1 omm dbgrp   42077 Aug 18 11:05 gaussdb.conf
-rw------- 1 omm dbgrp    1024 Aug 18 10:58 gaussdb.conf.lock
-rw------- 1 omm dbgrp   42077 Aug 18 11:05 gaussdb.conf.wal.bak
-rw------- 1 omm dbgrp      72 Aug 21 07:55 gaussdb.state
drwx------ 3 omm dbgrp    4096 Aug 21 07:55 global
-rw------- 1 omm dbgrp       1 Aug 18 11:05 gs_build.pid
-rw------- 1 omm dbgrp     354 Aug 18 10:58 gs_gazelle.conf
-rw------- 1 omm dbgrp    5015 Aug 18 11:05 gs_hba.conf
-rw------- 1 omm dbgrp    5015 Aug 18 11:05 gs_hba.conf.bak
-rw------- 1 omm dbgrp    1024 Aug 18 11:05 gs_hba.conf.lock
-rw------- 1 omm dbgrp    1618 Aug 18 11:05 gs_ident.conf
-rw------- 1 omm dbgrp 1048577 Aug 21 07:55 gs_shared_mem_kpi.meta
-rw------- 1 omm dbgrp 4915200 Aug 18 11:05 gswlm_userinfo.cfg
drwx------ 2 omm dbgrp       6 Aug 18 11:05 hotpatch
-rw------- 1 omm dbgrp       4 Aug 21 07:55 logger_file
-rw------- 1 omm dbgrp      48 Aug 18 11:05 paxosinfo
-rw------- 1 omm dbgrp      48 Aug 18 11:05 paxosinfo.backup
drwx------ 2 omm dbgrp      26 Aug 18 11:05 pg_clog
drwx------ 2 omm dbgrp      26 Aug 18 11:05 pg_csnlog
-rw------- 1 omm dbgrp       0 Aug 21 07:55 pg_ctl.lock
drwx------ 2 omm dbgrp       6 Aug 18 11:05 pg_errorinfo
drwx------ 4 omm dbgrp      39 Aug 18 11:05 pg_llog
drwx------ 2 omm dbgrp       6 Aug 18 10:58 pg_location
drwx------ 2 omm dbgrp       6 Aug 18 11:05 pg_logical
drwx------ 4 omm dbgrp      36 Aug 18 11:05 pg_multixact
drwx------ 2 omm dbgrp      26 Aug 21 07:54 pg_notify
drwx------ 4 omm dbgrp      36 Aug 18 11:06 pg_replslot
drwx------ 2 omm dbgrp       6 Aug 18 11:05 pg_serial
drwx------ 2 omm dbgrp       6 Aug 18 11:05 pg_snapshots
drwx------ 2 omm dbgrp      25 Aug 21 08:36 pg_stat_tmp
drwx------ 2 omm dbgrp       6 Aug 18 11:05 pg_tblspc
drwx------ 2 omm dbgrp       6 Aug 18 11:05 pg_twophase
-rw------- 1 omm dbgrp       4 Aug 18 11:05 PG_VERSION
drwx------ 3 omm dbgrp    4096 Aug 21 08:07 pg_xlog
-rw------- 1 omm dbgrp     102 Aug 21 07:55 postmaster.opts
-rw------- 1 omm dbgrp     105 Aug 21 07:54 postmaster.pid
-rw------- 1 omm dbgrp       0 Aug 18 11:05 postmaster.pid.lock
-rw------- 1 omm dbgrp      10 Aug 18 11:04 rewind_lable
-rw------- 1 omm dbgrp    5712 Aug 18 11:02 server.crt
-rw------- 1 omm dbgrp    2654 Aug 18 11:02 server.key
-rw------- 1 omm dbgrp      56 Aug 18 11:02 server.key.cipher
-rw------- 1 omm dbgrp      24 Aug 18 11:02 server.key.rand
-rw------- 1 omm dbgrp       4 Aug 21 07:55 term_file
drwx------ 5 omm dbgrp      67 Aug 18 11:05 undo

进入 DN 目录查看,跟 PostgreSQL 目录很相似。同时又包含 GaussDB 自己扩展的配置、Paxos、WLM、性能等文件。列举一下几个重要的几类:

分类 文件/目录 主要作用
数据文件 base/ 数据库、表、索引等实际数据文件
系统目录 global/ 全局系统表、共享系统信息
配置文件 gaussdb.conf DN 核心数据库配置
gs_hba.conf 客户端认证与访问控制
运行状态 postmaster.pid 数据库实例 PID、端口等运行信息
postmaster.opts 数据库启动参数
gaussdb.state GaussDB 实例状态
term_file 实例终止/停止控制相关
pg_ctl.lock 实例管理锁
事务相关 pg_clog/ 事务提交状态等信息
pg_csnlog/ CSN(Commit Sequence Number)相关信息
pg_multixact/ MultiXact 相关数据
pg_serial/ Serializable 事务相关信息
pg_twophase/ 两阶段提交事务状态
WAL/日志 pg_xlog/ WAL 日志,记录数据库变更
复制相关 pg_replslot/ Replication Slot 信息
pg_logical/ 逻辑复制相关数据
paxosinfo Paxos/副本相关状态信息

查看文件夹大小

[root@gaussdb2 dn_master]# du -sh * 2>/dev/null | sort -hr
514M	global
433M	pg_xlog
232M	base
62M	undo
4.7M	gswlm_userinfo.cfg
1.1M	gs_shared_mem_kpi.meta
256K	pg_csnlog
256K	pg_clog
88K	pg_stat_tmp
44K	gaussdb.conf.wal.bak

global 目录存放的基本就是以 OID 命名的关系(relation)文件

[root@gaussdb2 global]# ll
total 525372
-rw------- 1 omm dbgrp         0 Aug 18 11:05 12322
-rw------- 1 omm dbgrp      8192 Aug 18 11:05 12323
-rw------- 1 omm dbgrp         0 Aug 18 11:05 12324
-rw------- 1 omm dbgrp      8192 Aug 18 11:05 12325
-rw------- 1 omm dbgrp         0 Aug 18 11:05 12328
-rw------- 1 omm dbgrp      8192 Aug 18 11:05 12329
-rw------- 1 omm dbgrp      8192 Aug 18 14:24 14291
-rw------- 1 omm dbgrp     24576 Aug 18 11:05 14291_fsm
-rw------- 1 omm dbgrp      8192 Aug 18 14:24 14291_vm
-rw------- 1 omm dbgrp     16384 Aug 18 11:05 14293
-rw------- 1 omm dbgrp     16384 Aug 18 11:05 14294

gaussdb=# SELECT oid, relname, relkind  FROM pg_class Where oid = 14293;
  oid  |         relname         | relkind 
-------+-------------------------+---------
 14293 | adm_subpart_key_columns | v
(1 row)

2.2 CN 目录

查看 CN 的目录,发现跟 DN 目录类似。

[omm@gaussdb1 app]$ cd /data/gaussdb/data/cn/
[omm@gaussdb1 cn]$ ll
total 6024
-rw------- 1 omm dbgrp     206 Aug 18 18:31 backup_label.old
drwx------ 6 omm dbgrp      54 Aug 18 18:31 base
-rw------- 1 omm dbgrp       0 Aug 18 18:31 build_completed.done
-rw------- 1 omm dbgrp    5690 Aug 18 11:02 cacert.pem
-rw------- 1 omm dbgrp       1 Aug 21 08:52 disc_readonly_test
-rw------- 1 omm dbgrp   41599 Aug 20 13:39 gaussdb.conf
-rw------- 1 omm dbgrp   41599 Aug 20 13:39 gaussdb.conf.bak
-rw------- 1 omm dbgrp    1024 Aug 18 10:58 gaussdb.conf.lock
-rw------- 1 omm dbgrp      72 Aug 21 07:54 gaussdb.state
drwx------ 3 omm dbgrp    4096 Aug 21 07:54 global
-rw------- 1 omm dbgrp       1 Aug 18 18:31 gs_build.pid
-rw------- 1 omm dbgrp     354 Aug 18 10:58 gs_gazelle.conf
-rw------- 1 omm dbgrp    5015 Aug 18 11:01 gs_hba.conf
-rw------- 1 omm dbgrp    5015 Aug 18 18:31 gs_hba.conf.bak
-rw------- 1 omm dbgrp    1024 Aug 18 18:31 gs_hba.conf.lock
-rw------- 1 omm dbgrp    1618 Aug 18 18:31 gs_ident.conf
-rw------- 1 omm dbgrp 1048577 Aug 21 07:54 gs_shared_mem_kpi.meta
-rw------- 1 omm dbgrp 4915200 Aug 18 18:31 gswlm_userinfo.cfg
drwx------ 2 omm dbgrp       6 Aug 18 18:31 hotpatch
-rw------- 1 omm dbgrp      48 Aug 18 18:31 paxosinfo
-rw------- 1 omm dbgrp      48 Aug 18 18:31 paxosinfo.backup
drwx------ 2 omm dbgrp      26 Aug 18 18:31 pg_clog
drwx------ 2 omm dbgrp      26 Aug 18 18:31 pg_csnlog
-rw------- 1 omm dbgrp       0 Aug 18 18:31 pg_ctl.lock
drwx------ 2 omm dbgrp       6 Aug 18 18:31 pg_errorinfo
drwx------ 4 omm dbgrp      39 Aug 18 18:31 pg_llog
drwx------ 2 omm dbgrp       6 Aug 18 10:58 pg_location
drwx------ 2 omm dbgrp       6 Aug 18 18:31 pg_logical
drwx------ 4 omm dbgrp      36 Aug 18 18:31 pg_multixact
drwx------ 2 omm dbgrp      26 Aug 21 07:54 pg_notify
drwx------ 2 omm dbgrp       6 Aug 18 10:58 pg_replslot
drwx------ 2 omm dbgrp       6 Aug 18 18:31 pg_serial
drwx------ 2 omm dbgrp       6 Aug 18 18:31 pg_snapshots
drwx------ 2 omm dbgrp      25 Aug 21 08:52 pg_stat_tmp
drwx------ 2 omm dbgrp       6 Aug 18 18:31 pg_tblspc
drwx------ 2 omm dbgrp       6 Aug 18 18:31 pg_twophase
-rw------- 1 omm dbgrp       4 Aug 18 18:31 PG_VERSION
drwx------ 3 omm dbgrp    4096 Aug 20 17:02 pg_xlog
-rw------- 1 omm dbgrp      83 Aug 21 07:54 postmaster.opts
-rw------- 1 omm dbgrp      97 Aug 21 07:54 postmaster.pid
-rw------- 1 omm dbgrp       0 Aug 18 18:31 postmaster.pid.lock
-rw------- 1 omm dbgrp      10 Aug 18 18:31 rewind_lable
-rw------- 1 omm dbgrp    5712 Aug 18 11:02 server.crt
-rw------- 1 omm dbgrp    2654 Aug 18 11:02 server.key
-rw------- 1 omm dbgrp      56 Aug 18 11:02 server.key.cipher
-rw------- 1 omm dbgrp      24 Aug 18 11:02 server.key.rand
drwx------ 5 omm dbgrp      67 Aug 18 18:31 undo

[omm@gaussdb1 cn]$ du -sh * 2>/dev/null | sort -hr
514M	global
225M	pg_xlog
116M	base
48M	undo
4.7M	gswlm_userinfo.cfg
1.1M	gs_shared_mem_kpi.meta
256K	pg_csnlog
256K	pg_clog
96K	pg_stat_tmp
44K	gaussdb.conf.bak
44K	gaussdb.conf

[omm@gaussdb1 global]$ ll
total 525396
-rw------- 1 omm dbgrp         0 Aug 18 18:31 12322
-rw------- 1 omm dbgrp      8192 Aug 18 18:31 12323
-rw------- 1 omm dbgrp         0 Aug 18 18:31 12324
-rw------- 1 omm dbgrp      8192 Aug 18 18:31 12325
-rw------- 1 omm dbgrp         0 Aug 18 18:31 12328
-rw------- 1 omm dbgrp      8192 Aug 18 18:31 12329
-rw------- 1 omm dbgrp      8192 Aug 18 18:31 14291
-rw------- 1 omm dbgrp     24576 Aug 18 18:31 14291_fsm
-rw------- 1 omm dbgrp      8192 Aug 18 18:31 14291_vm
-rw------- 1 omm dbgrp     16384 Aug 18 18:31 14293
-rw------- 1 omm dbgrp     16384 Aug 18 18:31 14294
-rw------- 1 omm dbgrp         0 Aug 18 18:31 14333
-rw------- 1 omm dbgrp      8192 Aug 18 18:31 14335

gaussdb=# SELECT
    c.oid,
    n.nspname AS schema_name,
    c.relname,
    c.relkind,
    c.relfilenode
FROM pg_class c
LEFT JOIN pg_namespace n
    ON c.relnamespace = n.oid
WHERE c.oid  = 14293;
  oid  | schema_name |         relname         | relkind | relfilenode 
-------+-------------+-------------------------+---------+-------------
 14293 | sys         | adm_subpart_key_columns | v       |       14293
(1 row)

CN 也有 base/global/pg_xlog/ 等数据库数据目录结构。所以不要简单理解成:

CN = 只有 SQL 转发,没有数据。

更准确地说:

CN 本身也是一个基于 gaussdb 内核运行的数据库实例,只是它在集群中的角色是 Coordinator,主要负责 SQL 接入、SQL 解析、计划生成、协调 DN 执行等。

CN 内部关键模块有:

  1. Catalog / 元数据缓存
    1. CN 本地存 pg_classpgxc_nodepg_attribute、分布列、分区信息。
    2. 多 CN 之间元数据通过对等同步(DDL 走 2PC + 广播),所以连 cn_5001 建表,cn_5002 也能看见。
    3. CN 不存业务表数据,只存 “表在哪些 DN、按什么分布” 的路由信息。
  2. Pooler( 8001 端口)
    1. 在 CN 进程内维护"到各 DN 的预连接池"
    2. (database, user, 选项) 分桶,同属性复用,不同属性不能混用
    3. worker 线程要连 DN → 找 pooler 拿空闲连接 → 用完归还
  3. 事务协调器
    1. GTM 交互:分布式事务走 2PC ,CN 是协调者,DN 是参与者;
    2. 开始事务 → 找 GTM 拿全局事务 ID + 快照;
    3. 提交时 → CN 先让各 DN prepare,再让各 DN commit,最后自己记一条 commit 日志;
    4. 跨 DN 一致性靠 GTM 的 CSN(全局提交序列号)
  4. 分布式优化器
    1. 比单机数据库多一层:DN 裁剪(Node Pruning)
    2. Stream 算子生成:DN 间建通信通道(libcomm),重分布中间结果;
    3. GTM 交互:优化阶段找 GTM 拿快照/时间戳,保证全局 MVCC 一致

2.3 GTM 目录

  与 CNDN 完整的数据库实例目录不同,GTM 本身并不直接存储业务表数据,因此 gtm 目录结构非常简单,主要包含 gtm.conf 配置文件、gtm.pid 进程信息、gtm.opts 启动参数以及 gtm.sequence 等状态文件。

[omm@gaussdb1 gtm]$ ll
total 32
-rw------- 1 omm dbgrp    1 Aug 21 09:58 disc_readonly_test
-rw------- 1 omm dbgrp 3626 Aug 18 11:01 gtm.conf
-rw------- 1 omm dbgrp 3626 Aug 18 11:01 gtm.conf.bak
-rw------- 1 omm dbgrp 1024 Aug 18 11:01 gtm.conf.lock
-rw------- 1 omm dbgrp   16 Aug 20 21:02 gtm.control
-rw------- 1 omm dbgrp   46 Aug 21 07:54 gtm.opts
-rw------- 1 omm dbgrp   48 Aug 21 07:54 gtm.pid
-rw------- 1 omm dbgrp    8 Aug 20 21:02 gtm.sequence
drwx------ 2 omm dbgrp    6 Aug 18 11:03 hotpatch

[omm@gaussdb1 gtm]$ grep -Ev '^[[:space:]]*#|^[[:space:]]*$' gtm.conf
nodename = 'gtm_1002'				# Specifies the node name.
listen_addresses = 'localhost,192.168.182.141'			# Listen addresses of this GTM.
port = 37200				# Port number of this GTM.
log_directory = '/data/gaussdb/log/omm/gs_log/gtm'		# directory where log files are written,
local_host = '192.168.182.141'			# Listen address of HA local host.
local_port =				37201
enable_alarm = on
enable_connect_control = true	# check ip.
alarm_component = '/opt/huawei/snas/bin/snas_cm_cmd'
gtm_num_threads = 1024
gtm_option = 1

2.4 CM 目录

   CM(Cluster Manager)是 GaussDB 分布式集群中的集群管理组件,主要负责集群状态监控、故障检测、主备状态管理以及故障场景下的自动处理。CM 由 CM Server 和 CM Agent 两部分组成:cm_server 负责集群级别的管理与决策,cm_agent 部署在各节点上,负责节点本地组件的状态监控和管理。从目录结构来看,cm/ 下主要包含 cm_server/cm_agent/ 两个目录,分别保存对应组件的配置文件、PID 文件及运行相关信息。其中 cm_server.confcm_agent.conf 是核心配置文件,cm_server.pidcm_agent.pid 用于记录进程运行信息。在 Linux 层面,分别对应 cm_servercm_agent 两个进程。

[omm@gaussdb1 cm]$ ll
total 4
drwx------ 2 omm dbgrp  78 Aug 21 10:02 cm_agent
drwx------ 3 omm dbgrp 118 Aug 21 10:05 cm_server
-rw------- 1 omm dbgrp   1 Aug 21 10:05 disc_readonly_test
[omm@gaussdb1 cm]$ ll cm_server/
total 24
-rw------- 1 omm dbgrp 4863 Aug 18 11:06 cm_server.conf
-rw------- 1 omm dbgrp 4863 Aug 18 11:06 cm_server.conf.bak
-rw------- 1 omm dbgrp 1024 Aug 18 11:03 cm_server.conf.lock
-rw------- 1 omm dbgrp   39 Aug 21 07:54 cm_server.pid
drwx------ 2 omm dbgrp    6 Aug 18 11:03 hotpatch
[omm@gaussdb1 cm]$ ll cm_agent/
total 16
-rw------- 1 omm dbgrp 4167 Aug 18 11:01 cm_agent.conf
-rw------- 1 omm dbgrp   40 Aug 21 10:02 cm_agent.pid
-rw------- 1 omm dbgrp 2366 Aug 21 10:02 cm_meta_cma_config.json

2.5 ETCD 目录

ETCD 目录结构相对简单,主要由安全证书和集群成员数据组成。etcd.crtetcd.keyetcd.key.cipheretcd.key.rand 用于 ETCD 节点之间的安全通信和身份认证;member/ 则是 ETCD 节点的核心数据目录,用于保存该节点的成员信息、Raft/WAL 日志以及集群状态等数据。

[omm@gaussdb1 etcd]$ ll
total 20
-rw------- 1 omm dbgrp 5797 Aug 18 10:58 etcd.crt
-rw------- 1 omm dbgrp 2654 Aug 18 10:58 etcd.key
-rw------- 1 omm dbgrp   56 Aug 18 10:57 etcd.key.cipher
-rw------- 1 omm dbgrp   24 Aug 18 10:57 etcd.key.rand
drwx------ 4 omm dbgrp   29 Aug 21 07:53 member
[omm@gaussdb1 etcd]$ 

3. 端口验证

文章开头,我们介绍了 DN 的端口,第一个 DN 分片组的三个 DN 端口都是 33100,第二个 DN 分片组的三个 DN 端口都是 331020,第三个 DN 分片组的三个 DN 端口都是 33140。 除了这些端口,还有对应的 33101、33121、33141 用作 DN 主内部通信。

观察 CN 的配置文件发现:CN 不光有 8000 对外服务的端口,还有个 8001 端口,也就是连接池端口,用于 CN 与 DN 节点的内部交互、连接池管理。

[omm@gaussdb3 data]$ grep -E '^(port|pooler_port|application_name|pgxc_node_name|data_directory)'  cn/gaussdb.conf dn_*/gaussdb.conf
cn/gaussdb.conf:port = '8000'				# (change requires restart)
cn/gaussdb.conf:pgxc_node_name = 'cn_5003'			# Coordinator or Datanode name
cn/gaussdb.conf:pooler_port = '8001'
dn_dummy/gaussdb.conf:port = '33100'				# (change requires restart)
dn_dummy/gaussdb.conf:pgxc_node_name = 'dn_6001_6002_6003'			# Coordinator or Datanode name
dn_dummy/gaussdb.conf:pooler_port = '33101'
dn_dummy/gaussdb.conf:application_name = 'dn_6003'
dn_master/gaussdb.conf:port = '33140'				# (change requires restart)
dn_master/gaussdb.conf:pgxc_node_name = 'dn_6007_6008_6009'			# Coordinator or Datanode name
dn_master/gaussdb.conf:pooler_port = '33141'
dn_master/gaussdb.conf:application_name = 'dn_6007'
dn_slave/gaussdb.conf:port = '33120'				# (change requires restart)
dn_slave/gaussdb.conf:pgxc_node_name = 'dn_6004_6005_6006'			# Coordinator or Datanode name
dn_slave/gaussdb.conf:pooler_port = '33121'
dn_slave/gaussdb.conf:application_name = 'dn_6005'

gaussdb3CNDN 端口总结成如下:

目录 DN/CN 角色 pgxc_node_name application_name port pooler_port
cn/ CN cn_5003 8000 8001
dn_dummy/ dn_ummy dn_6001_6002_6003 dn_6003 33100 33101
dn_slave/ dn_slave dn_6004_6005_6006 dn_6005 33120 33121
dn_master/ dn_master dn_6007_6008_6009 dn_6007 33140 33141

尝试连接这些端口,发现 DN 端口竟然可以连上!但是只能连 主 DN,也不能建表!

[omm@gaussdb3 data]$ gsql -d postgres -p 33100
gsql: ERROR:  dn_6001_6002_6003: can not accept connection in standby mode.
[omm@gaussdb3 data]$ gsql -d postgres -p 33120
gsql: ERROR:  dn_6004_6005_6006: can not accept connection in standby mode.
[omm@gaussdb3 data]$ gsql -d postgres -p 33140
gsql ((GaussDB Kernel 505.1.0 build da28c417) compiled at 2024-04-18 22:54:55 commit 8474 last mr 17213 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

gaussdb=# create table t2( id int);
ERROR:  dn_6007_6008_6009: cannot execute CREATE TABLE in a read-only transaction

那么直连 主DN 可以查询什么呢?

  1. 查询是否是主库
[omm@gaussdb3 data]$ gsql -d postgres -p 33140
gsql ((GaussDB Kernel 505.1.0 build da28c417) compiled at 2024-04-18 22:54:55 commit 8474 last mr 17213 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

gaussdb=# select pg_is_in_recovery();
 pg_is_in_recovery 
-------------------
 f
(1 row)

当前数据库实例不是 Recovery 状态,因此当前实例是 Primary(主库)。

  1. 查询同步状态
gaussdb=# SELECT application_name, client_addr, state, sender_sent_location, receiver_replay_location, sync_priority, sync_state FROM pg_stat_replication;
       application_name        |   client_addr   |   state   | sender_sent_location | receiver_replay_location | sync_priority | sync_stat
e 
-------------------------------+-----------------+-----------+----------------------+--------------------------+---------------+----------
--
 WalSender to Standby[dn_6008] | 192.168.182.141 | Streaming | 0/FEBC678            | 0/FEBBD08                |             1 | Quorum
 WalSender to Standby[dn_6009] | 192.168.182.142 | Streaming | 0/FEBC878            | 0/FEBBD08                |             1 | Quorum
(2 rows)

发现两个备库分别是 dn_6008dn_6009 ,当前处于流式复制状态,这两个备库都属于 Quorum 同步成员Quorum 代表多数派同步复制,客户端发起事务后,必须要等待对应的 WAL 日志复制到多个副本后,主库才会响应给客户端,少数节点的宕机不影响全局可用性,保证数据的一致性。

说明这套主从复制不存在异步备库,也不存在级联备库!! 让我们重温一下 PostgreSQL + Patroni + ETCD 的高可用架构里,不同的 synchronous_standby_names 代表不同的复制关系。

  • synchronous_standby_names = '' :纯异步,主提交不等多备,sync_statepg2pg3 都显示 async

  • synchronous_standby_names = 'pg2, pg3' – 等价于 FIRST 1 (pg2, pg3)优先级模式,pg2 是 sync ,pg3 是 potential 。提交必须等 pg2 的 WAL flush 确认;pg2 挂了 Patroni 自动把 pg3 提为 sync。

  • synchronous_standby_names = 'FIRST 2 (pg2, pg3)'双同步,强一致(最安全的模式)。提交必须等 pg2 和 pg3 都确认​ WAL flush 才返回。pg2 和 pg3 都是 sync 。 当 pg2 或 pg3 任何一个节点挂了,Primary 的同步提交事务将无法完成,会出现写入阻塞。

  • synchronous_standby_names = 'ANY 1 (pg2, pg3)'Quorum 同步,提交只要 pg2 或 pg3 任意 1 个确认即可。等价于此处的 GaussDB 同步模式。

# Quorum 等价写法
synchronous_standby_names = 'ANY 1 (dn_6008, dn_6009)'  
synchronous_commit = on
  1. 直连 DN 可以查询本地分片数据
testdb=# select * from orders;
 order_id | order_date | customer_id | amount 
----------+------------+-------------+--------
     1003 | 2025-06-18 |         103 | 300.00
     1009 | 2027-01-05 |         109 | 900.00
(2 rows)

testdb=# \q
[omm@gaussdb3 data]$ gsql -d postgres -p 8000
gsql ((GaussDB Kernel 505.1.0 build da28c417) compiled at 2024-04-18 22:54:55 commit 8474 last mr 17213 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

gaussdb=# \c testdb
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database "testdb" as user "omm".
testdb=# select * from orders;
 order_id | order_date | customer_id | amount  
----------+------------+-------------+---------
     1003 | 2025-06-18 |         103 |  300.00
     1009 | 2027-01-05 |         109 |  900.00
     1001 | 2025-01-15 |         101 |  100.00
     1004 | 2025-09-25 |         104 |  400.00
     1005 | 2026-01-10 |         105 |  500.00
     1006 | 2026-03-15 |         106 |  600.00
     1007 | 2026-06-20 |         107 |  700.00
     1011 | 2027-06-18 |         111 | 1100.00
     1002 | 2025-03-20 |         102 |  200.00
     1008 | 2026-09-28 |         108 |  800.00
     1010 | 2027-03-12 |         110 | 1000.00
     1012 | 2027-09-22 |         112 | 1200.00
(12 rows)

-- 本地分片确实只有 2 条数据
testdb=# select b.node_name,a.count from(select xc_node_id,count(*) from orders group by xc_node_id) a,pgxc_node b where a.xc_node_id=b.node_id;
     node_name     | count 
-------------------+-------
 dn_6001_6002_6003 |     6
 dn_6007_6008_6009 |     2
 dn_6004_6005_6006 |     4
(3 rows)

主 DN 可以通过 gsql 直接连,CN 的 pooler 连接池 8001 端口呢,也可以连!

omm@gaussdb3 data]$ gsql -d testdb -p 8001
gsql ((GaussDB Kernel 505.1.0 build da28c417) compiled at 2024-04-18 22:54:55 commit 8474 last mr 17213 release)
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.

testdb=# select b.node_name,a.count from(select xc_node_id,count(*) from orders group by xc_node_id) a,pgxc_node b where a.xc_node_id=b.node_id;
     node_name     | count 
-------------------+-------
 dn_6001_6002_6003 |     6
 dn_6007_6008_6009 |     2
 dn_6004_6005_6006 |     4
(3 rows)

但不建议把 8001 当成普通客户端连接端口使用。也可以发现 CN 单进程多线程的运行模式,8000 和 8001 只是 listener 绑的不同端口,背后是同一池子 worker 线程在干活。

4. 线程介绍

最后简单介绍一下 CN 和 DN 的线程,都还是 PostgreSQL 的那些进程名字。

# 查看 CN 的线程
[omm@gaussdb3 data]$ ps -To pid,lwp,nlwp,comm,etime -p $(pgrep -f "gaussdb --coordinator")
    PID     LWP NLWP COMMAND             ELAPSED
   5217    5217  117 gaussdb            03:18:19
   5217    5570  117 jemalloc_bg_thd    03:18:15
   5217    6341  117 gaussdb            03:17:40
   5217    6416  117 syslogger          03:17:37
   5217    6417  117 alarm              03:17:37
   5217    6418  117 reaper             03:17:37
   5217    6419  117 jemalloc_bg_thd    03:17:37
   5217    6420  117 jemalloc_bg_thd    03:17:37
   5217    6421  117 jemalloc_bg_thd    03:17:37
   5217    6441  117 TPLlistener        03:17:35  
   5217    6721  117 TPLworker          03:17:28
   5217    6722  117 TPLscheduler       03:17:28
   5217    6943  117 checkpointer       03:17:22
   5217    6944  117 Spbgwriter         03:17:22
   5217    6945  117 pagewriter         03:17:22
   5217    6946  117 pagewriter         03:17:22
   5217    6947  117 pagewriter         03:17:22
   5217    6948  117 pagewriter         03:17:22
   5217    6949  117 pagewriter         03:17:22
   5217    6950  117 WALwriter          03:17:22
   5217    6951  117 WALwriteraux       03:17:22
   5217    6952  117 AVClauncher        03:17:22
   5217  299796  117 worker                10:15
   5217  299913  117 worker                10:13
   5217  300142  117 worker                10:10
   5217  301543  117 worker                09:14
...

[omm@gaussdb3 data]$ 


# 查看 DN 的线程
[omm@gaussdb3 data]$ ps -To pid,lwp,nlwp,comm,etime -p $(pgrep -f "gaussdb --datanode -D /data/gaussdb/data/dn_master")
    PID     LWP NLWP COMMAND             ELAPSED
   5397    5397  120 gaussdb            03:22:23
   5397    5568  120 jemalloc_bg_thd    03:22:21
   5397    6752  120 gaussdb            03:21:32
   5397    6919  120 syslogger          03:21:29
   5397    6920  120 jemalloc_bg_thd    03:21:29
   5397    7032  120 COMMsendflow       03:21:24
   5397    7033  120 COMMrecvflow       03:21:24
   5397    7034  120 COMMaux            03:21:24
   5397    7035  120 COMMrecloop        03:21:24
   5397    7036  120 COMMrecloop        03:21:24
   5397    7037  120 jemalloc_bg_thd    03:21:24
   5397    7038  120 jemalloc_bg_thd    03:21:24
   5397    7039  120 COMMrecloop        03:21:24
   5397    7040  120 COMMrecloop        03:21:24
   5397    7044  120 alarm              03:21:23
   5397    7045  120 reaper             03:21:23
   5397    7158  120 TPLlistener        03:21:22
   5397    7159  120 TPLworker          03:21:22
   5397    7160  120 TPLworker          03:21:22
...

总结,本文通过对 GaussDB进程、目录、端口和线程的逐层分析,分别介绍了 CNDNGTMCMETCD 等多个组件的运行机制与内部结构,帮助大家从 Linux 操作系统层面建立对 GaussDB 的整体认识,更加直观地理解各组件之间的关系。

如果本文对你有所帮助,欢迎点赞、推荐和转发,也欢迎关注后续文章,一起学习 GaussDB 分布式数据库。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐