《GaussDB 内部探秘:进程、目录、端口与线程》
《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_master 、dn_slave 、dn_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 位于 gaussdb2,dn_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 分布式集群纯命令部署》 中,我们提到了分别部署了 CN 、DN、ETCD、GTM、CM 等组件。以下是这些组件对应的进程:
[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 pendingCN:data/gaussdb/install/app/bin/gaussdb --coordinator -D /data/gaussdb/data/cnDN: 总共有三个进程,dn_master是规划的第一个分片组的主 DN,dn_slave和dn_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_server和cm_agent和om_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_monitorETCD:/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差不多,postmaster是postgres的软连接,在这里gaussmaster是gaussdb进程的软连接,但是接收到连接请求后,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 内部关键模块有:
- Catalog / 元数据缓存
- CN 本地存
pg_class、pgxc_node、pg_attribute、分布列、分区信息。 - 多 CN 之间元数据通过对等同步(DDL 走 2PC + 广播),所以连
cn_5001建表,cn_5002也能看见。 - CN 不存业务表数据,只存 “表在哪些 DN、按什么分布” 的路由信息。
- CN 本地存
- Pooler( 8001 端口)
- 在 CN 进程内维护"到各 DN 的预连接池"
- 按
(database, user, 选项)分桶,同属性复用,不同属性不能混用 - worker 线程要连 DN → 找 pooler 拿空闲连接 → 用完归还
- 事务协调器
- GTM 交互:分布式事务走 2PC ,CN 是协调者,DN 是参与者;
- 开始事务 → 找 GTM 拿全局事务 ID + 快照;
- 提交时 → CN 先让各 DN prepare,再让各 DN commit,最后自己记一条 commit 日志;
- 跨 DN 一致性靠 GTM 的 CSN(全局提交序列号)
- 分布式优化器
- 比单机数据库多一层:DN 裁剪(Node Pruning);
- Stream 算子生成:DN 间建通信通道(libcomm),重分布中间结果;
- GTM 交互:优化阶段找 GTM 拿快照/时间戳,保证全局 MVCC 一致
2.3 GTM 目录
与 CN、DN 完整的数据库实例目录不同,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.conf 和 cm_agent.conf 是核心配置文件,cm_server.pid、cm_agent.pid 用于记录进程运行信息。在 Linux 层面,分别对应 cm_server 和 cm_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.crt、etcd.key、etcd.key.cipher、etcd.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'
gaussdb3 上 CN 和 DN 端口总结成如下:
| 目录 | 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 可以查询什么呢?
- 查询是否是主库
[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(主库)。
- 查询同步状态
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_6008 和 dn_6009 ,当前处于流式复制状态,这两个备库都属于 Quorum 同步成员。Quorum 代表多数派同步复制,客户端发起事务后,必须要等待对应的 WAL 日志复制到多个副本后,主库才会响应给客户端,少数节点的宕机不影响全局可用性,保证数据的一致性。
说明这套主从复制不存在异步备库,也不存在级联备库!! 让我们重温一下 PostgreSQL + Patroni + ETCD 的高可用架构里,不同的 synchronous_standby_names 代表不同的复制关系。
-
synchronous_standby_names = '':纯异步,主提交不等多备,sync_state:pg2和pg3都显示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
- 直连 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 的进程、目录、端口和线程的逐层分析,分别介绍了 CN、DN、GTM、CM、ETCD 等多个组件的运行机制与内部结构,帮助大家从 Linux 操作系统层面建立对 GaussDB 的整体认识,更加直观地理解各组件之间的关系。
如果本文对你有所帮助,欢迎点赞、推荐和转发,也欢迎关注后续文章,一起学习 GaussDB 分布式数据库。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)