oGRAC 双节点共享集群部署与多写验证实践
oGRAC 是 openGauss 的多主集群形态:多个数据库实例共享同一份存储,由集群管理服务(CM)统一管控,任一节点都可读写全部数据,向应用提供全局实时一致的服务。本文以 dcs72、dcs82 两台服务器为对象,完整记录 oGRAC 双节点集群从环境准备、安装部署,到实例启停、状态查询、数据一致性、负载扩展等运行验证的整个过程。文中命令均按本环境实际参数编写,并与 openGauss 官方 oGRAC 文档逐条核对,可依照章节顺序逐步执行,并对照"预期结果"确认每一步是否正确。

说明:本文只涉及 dcs72、dcs82 两台服务器及其共享存储。服务器的接入方式由环境提供方开通,本文不展开。
1 概述
1.1 文档说明
本文面向 oGRAC 集群的部署与验证人员,可作为双节点环境从零搭建到可运行的完整操作参考,主要内容如下:
- 部署部分:环境初始化、共享存储准备、安装介质处理、双节点安装、实例启停与集群状态查询;
- 功能验证部分:跨节点对象定义(DDL)与数据变更(DML)的全局同步,以及并发更新同一行时的行级锁行为;
- 负载验证部分:基于 TPC-C 基准对比单节点、双节点接入下的吞吐(tpmC),评估线性扩展能力,并说明 rbps 恢复加速服务的可选启用方式(供故障恢复场景使用)。
命令的语义以 openGauss 官方 oGRAC 文档为准;涉及本环境特有取值(IP 地址、盘符、WWN、目录路径)的,以本文第 2 章、第 4 章的标注为准。文中需实测后回填的数值(tpmC、起止时间等)以 ____ 标出,执行后在对应表格中填写即可。
1.2 文档约定
[Node0]、[Node1]表示命令应在哪个节点执行;不带标注的命令表示两节点均需执行。Node0 对应 dcs72,Node1 对应 dcs82。- 命令块中出现
su -s /bin/bash ograc的,表示其后的命令需先切换至数据库用户执行;系统初始化类命令(关闭防火墙、共享盘授权、解包、执行安装脚本等)在 root 用户下执行。用户分工见 2.4。 - 以
#开头的行为命令注释,说明命令作用或预期输出。 - 口令类内容统一以
<口令>表示,由操作者自行设定,不在文中出现明文;同一口令在多处使用时需保持一致(见 2.4)。
2 测试环境
2.1 节点与网络
| 节点 | 主机名 | IP 地址 | 网卡 | 子网 | CPU 架构 |
|---|---|---|---|---|---|
| Node0 | dcs72 | 。。*。/24 | enp4s0 | 192.168.3.0/24 | aarch64 |
| Node1 | dcs82 | 192.168.3.82/24 | enp4s0 | 192.168.3.0/24 | aarch64 |


两节点处于同一网段,业务访问、节点间互联与 CM 心跳均通过 enp4s0。安装前先确认两节点网络互通:
# dcs72 上执行 ping -c 3 *.*.*.82

# dcs82 上执行 ping -c 3 *.*.*.72

2.2 软件与运行配置
| 项目 | 取值 |
|---|---|
| 操作系统 | Linux(aarch64) |
| 安装包 | /data/oGRAC-1.0.0.B001-openEuler22.03-aarch64.tgz |
| 数据库服务端口(ograc_port) | 1611 |
| 节点互联端口(interconnect_port) | 1601、1602 |
| DSS 端口(dss_port) | 1811 |
| CMS 端口(cms_port) | 14587 |
| 安装目录(ograc_home) | /opt/ograc |
| 数据目录(data_root) | /mnt/dbdata |
| 数据库日志目录 | /opt/ograc/log/ograc |
| HBA 白名单文件 | /mnt/dbdata/local/ograc/tmp/data/cfg/oghba.conf |
| 数据库用户 | ograc(安装过程自动创建,见 2.4) |
2.3 共享存储规划
存储阵列向两台服务器映射了 4 块共享 LUN,容量组合为 4T、2T、2T、5G,与官方两节点部署指南推荐规划一致。角色划分如下:
| LUN | 建议大小 | WWN 短标识 | 角色 | 软链接 | DSS 卷组 |
|---|---|---|---|---|---|
| LUN1 | 4T | ...01eb | Redo 盘 | /dev/dss-disk2 | vg2 |
| LUN2 | 2T | ...01ec | 数据盘 | /dev/dss-disk1 | vg1 |
| LUN3 | 2T | ...01ed | 归档盘 | /dev/dss-disk3 | vg3 |
| LUN4 | 5G | ...01ee | CM 仲裁盘 | /dev/gcc-disk | --- |
其中 CM 仲裁盘(gcc-disk)不归 DSS 卷组管理。各 LUN 在两节点所见盘符、WWN 与序列号的实测对照,以及软链接、授权的具体操作,见 4.2。
2.4 用户分工与口令约定
| 用户 | 使用阶段 | 用途 |
|---|---|---|
| root | 安装部署 | 系统初始化、依赖安装、共享盘授权、解包、执行安装脚本 |
| ograc | 运行验证 | ogsql、cms 等数据库相关命令 |
需要注意以下两点:
- ograc 用户由
appctl.sh install依据配置文件中的module_config.user自动创建(包含环境变量与权限设置),安装前不要手工useradd。安装完成后执行su -s /bin/bash ograc切换。 - 数据库命令必须在 ograc 用户下执行,root 下执行会因权限或环境变量问题失败;安装脚本必须在 root 用户下执行。
本环境涉及两类口令:安装时设置的数据库 sys 用户口令(见 4.5),以及 TPC-C 业务用户口令及其连接配置(见 6.1、6.3)。各自在使用处保持一致即可。
3 整体流程
整体实施分为六个阶段,按先后顺序推进,前一阶段通过后再进入下一阶段:
| 阶段 | 内容 | 章节 | 完成标志 |
|---|---|---|---|
| 一 | 系统配置、依赖软件、时间同步 | 4.1 | 两节点时间一致,依赖就绪 |
| 二 | 共享存储软链接与授权、安装介质解包、参数配置 | 4.2 ~ 4.4 | 软链接建立且授权完成,配置就绪 |
| 三 | 双节点安装 | 4.5 | 两节点输出 start success |
| 四 | 启停验证、跨节点读写、状态查询 | 4.6 ~ 4.7 | 启停顺序正确,cms stat 显示 ONLINE |
| 五 | 数据一致性验证(DDL/DML/行锁) | 5 | 三组验证结果与预期一致 |
| 六 | 负载与线性扩展验证(TPC-C,rbps 按需启用) | 6 | 单/双节点 tpmC 实测并完成效率计算 |
4 集群安装部署与基本运维
本章按部署顺序覆盖环境初始化、共享存储准备、介质解包与参数配置、预安装与安装、启动与读写验证、集群状态查询六个阶段。每步标注执行节点与用户,命令附注释与预期结果。
4.1 环境初始化
4.1.1 硬件资源确认
在两节点确认操作系统、网络、资源与安装包就绪:
# 两节点均执行 hostname # 预期输出:dcs72 / dcs82 ip a # 关注 enp4s0:192.168.3.72/24、192.168.3.82/24 ls -lrt /data/ # 确认安装包已就位 cat /etc/os-release # 预期输出:Linux(aarch64) free -h # 内存建议不低于 16 GB lscpu # 核数建议不少于 8 核
4.1.2 关闭 SELinux 与防火墙
oGRAC 安装与运行依赖节点间通信,需关闭 SELinux 与 firewalld。该操作适用于测试环境;生产环境请结合本单位安全策略,由运维人员确认后执行。
# 两节点均执行 setenforce 0 # 临时关闭 SELinux sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config # 永久关闭 systemctl stop firewalld systemctl disable firewalld # 验证 getenforce # 预期输出:Disabled systemctl status firewalld | grep Active # 预期输出:inactive (dead)

4.1.3 依赖软件确认
官方要求安装 wget、git、chrony、python3、python3-devel、iputils、iproute、patchelf、lz4(不低于 1.8.3)。本环境两节点均已安装;ntpdate 未安装,时间同步使用 chrony(见 4.1.4),不依赖它。安装脚本运行时会调用 numactl 配置 CPU/内存亲和,若该软件缺失,安装过程会出现 NUMA 相关警告,本节一并检查。
# 两节点均执行;输出与上述列表一致即通过 rpm -q wget git chrony python3 python3-devel iputils iproute patchelf lz4 # numactl 缺失时安装会出现 NUMA 警告:查询未安装则补装(已安装时本命令不触发安装) rpm -q numactl || dnf install -y numactl
说明:patchelf 的
rpm -q版本(0.16.0)与patchelf --version显示(0.15.0)不一致属正常,不影响使用;当前系统软件源已自带该包,更早版本需按官方文档手动编译安装。

4.1.4 时间同步
集群对节点间时间一致性敏感,时间跳变会导致 redo、归档与心跳异常。先核对两节点当前时间:
# 两节点均执行;输出应精确到秒且一致,偏差超过 1 秒需做同步 date
本环境为虚拟机,需先关闭与宿主机的时间同步策略,防止运行期时间反复跳变。两节点无外部时间源,由 Node0 作时间服务器、Node1 向 Node0 同步(chrony 已在上节确认安装)。
Node0(dcs72)执行:
# 备份并重写配置:允许客户端同步、启用本地时钟源 cp -p /etc/chrony.conf /etc/chrony.conf_bak cat > /etc/chrony.conf << 'EOF' local stratum 10 allow *.*.*.0/24 driftfile /var/lib/chrony/drift makestep 1.0 3 rtcsync logdir /var/log/chrony EOF systemctl enable --now chronyd systemctl restart chronyd # 验证:监听 UDP 123,自身作为时间源工作 ss -ulnp | grep chrony chronyc tracking # 预期:Reference ID = 7F7F0101 (LOCAL),Stratum 10

Node1(dcs82)执行:
# 备份并重写配置:指定 Node0(192.168.3.72)为时间源 cp -p /etc/chrony.conf /etc/chrony.conf_bak cat > /etc/chrony.conf << 'EOF' server *.*.*.72 iburst driftfile /var/lib/chrony/drift makestep 1.0 3 rtcsync logdir /var/log/chrony EOF systemctl enable --now chronyd systemctl restart chronyd chronyc sources -v # 预期:^* *.*.*.72(已选为最佳源) chronyc makestep # 时间偏差大时强制立即同步 chronyc tracking # 预期:Reference ID = *.*.*.72,Stratum 11

说明:firewalld 已在 4.1.2 停用,chronyd 的 UDP 123 无需放行;若未停用防火墙,需先执行
firewall-cmd --add-service=ntp --permanent并firewall-cmd --reload。
同步完成后,在两节点再次执行 date,时间差应不超过 1 秒。
4.2 共享存储准备
oGRAC 双节点共享同一份数据,依赖 4 块共享 LUN。本节先验证这些 LUN 在两节点可见且身份一致,确认共享后再完成命名与授权。
4.2.1 共享盘识别与共享验证
判断共享的依据是设备身份:WWN 与 Unit serial number 由存储阵列分配、全球唯一,两节点读取一致即访问同一块 LUN。在两节点执行下列命令,与下表核对:
# 两节点均执行:查看块设备、容量与 WWN 稳定标识 lsblk ll /dev/disk/by-id | grep wwn
实测结果如下表:
Node0(dcs72)结果:

Node1(dcs82)结果:

| LUN | WWN 短标识 | 大小 | 角色 | dcs72 盘符 | dcs82 盘符 | Unit serial number | 是否共享 |
|---|---|---|---|---|---|---|---|
| LUN1 | ...01eb | 4T | Redo 盘(dss-disk2 / vg2) | sda | sda | ...20491(两节点一致) | 是 |
| LUN2 | ...01ec | 2T | 数据盘(dss-disk1 / vg1) | sdb | sde | ...20492(dcs72 实测,dcs82 由 WWN 佐证) | 是 |
| LUN3 | ...01ed | 2T | 归档盘(dss-disk3 / vg3) | sdc | sdc | ...20493(两节点一致) | 是 |
| LUN4 | ...01ee | 5G | CM 仲裁盘(gcc-disk) | sdd | sdb | ...20494(两节点一致) | 是 |
| /data | ...01ef / ...01f0 | 500G | 各自本机盘(仅放置安装包) | sde | sdd | 两节点不同 | 否 |
再在本机做一次现场复核,确认实际设备与上表一致(以两节点盘符均为 sda 的 4T 盘为例,其余盘按上表各自盘符执行):
两节点均执行:复核 WWN 与物理序列号。
Node0(dcs72)执行:
# 两节点均执行:复核 WWN 与物理序列号 lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS /dev/sda /dev/sdb /dev/sdc /dev/sdd for disk in sda sdb sdc sdd; do echo "===== /dev/$disk =====" udevadm info --query=property --name=/dev/$disk | grep -E 'ID_SERIAL=|ID_WWN=' done

Node1(dcs82)执行:
# 两节点均执行:复核 WWN 与物理序列号 lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS /dev/sda /dev/sdb /dev/sdc /dev/sde for disk in sda sdb sdc sde; do echo "===== /dev/$disk =====" udevadm info --query=property --name=/dev/$disk | grep -E 'ID_SERIAL=|ID_WWN=' done
复核通过的标准:两节点输出逐字一致,且与上表吻合。核对后得出以下结论:
- 4T、2T、5G 盘两节点 WWN 与 serial 一致,为同一批共享 LUN;500G /data 为各自本机盘,仅放安装包。
- 同一 LUN 在两节点盘符可能不同(如 5G 盘 dcs72 为 sdd、dcs82 为 sdb),软链接必须基于 by-id 的 WWN 建立,不能基于盘符。
- 两节点系统盘 vda 的 LVM UUID 相同系镜像克隆所致,不代表 vda 共享(其 virtio ID 不同可佐证)。
4.2.2 建立软链接
首先各自进入两台服务器 /dev/disk/by-id 目录,使用 ll /dev/disk/by-id 命令获取相应获取以 scsi 或 wwn 开头的设备编号
Node0(dcs72)结果:

Node1(dcs82)结果:

然后将四块盘共享盘链接到如下目录,以下命令在两节点分别执行,整段复制执行:
# 两节点均执行,映射关系与 4.2.1 一致 ln -s /dev/disk/by-id/scsi-36382028100ed96acaff27890000001ec /dev/dss-disk1 # 数据盘(2T)→ vg1 ln -s /dev/disk/by-id/scsi-36382028100ed96acaff27890000001eb /dev/dss-disk2 # Redo 盘(4T)→ vg2 ln -s /dev/disk/by-id/scsi-36382028100ed96acaff27890000001ed /dev/dss-disk3 # 归档盘(2T)→ vg3 ln -s /dev/disk/by-id/scsi-36382028100ed96acaff27890000001ee /dev/gcc-disk # CM 仲裁盘(5G) # 验证:软链接应指向 by-id 的 wwn 文件 ls -l /dev/dss-disk1 /dev/dss-disk2 /dev/dss-disk3 /dev/gcc-disk
注意:软链接必须指向
/dev/disk/by-id/wwn-*文件。若查不到对应 wwn,先执行udevadm trigger --action=change后重查;仍查不到,说明共享 LUN 未映射到本机,需联系存储提供方确认。说明:官方文档对数据盘与 Redo 盘的大小关系有两种表述,本文按推荐规划执行(4T 做 Redo、2T 做数据盘),容量均远大于实际需求,不影响安装。若安装中 DSS 报卷组相关错误,可将 dss-disk1 与 dss-disk2 的 WWN 对调后重新执行 4.5。
Node0(dcs72)执行:

Node1(dcs82)执行:

4.2.3 块设备授权
安装脚本由 ograc 进程直接访问裸设备,需对两节点各自的底层块设备授权。注意授权对象是软链接最终指向的 /dev/sdX,且两节点盘符不同。
# Node0(dcs72)节点:sda=4T、sdb=2T、sdc=2T、sdd=5G chmod 777 /dev/sda chmod 777 /dev/sdb chmod 777 /dev/sdc chmod 777 /dev/sdd # Node1(dcs82)节点:sda=4T、sde=2T、sdc=2T、sdb=5G chmod 777 /dev/sda chmod 777 /dev/sdb chmod 777 /dev/sdc chmod 777 /dev/sde
验证权限(权限位应含 rw-rw-rw-):
# dcs72 上执行 ls -l /dev/sda /dev/sdb /dev/sdc /dev/sdd # dcs82 上执行(盘符与 dcs72 不同) ls -l /dev/sda /dev/sde /dev/sdc /dev/sdb
重启后盘符可能变化,若变化需重新授权。


4.3 解包安装介质
在两节点(root)将安装包解包到 /data:
# 两节点均执行 cd /data tar -zxvf oGRAC-1.0.0.B001-openEuler22.03-aarch64.tgz # 解包生成 ograc_connector/ 目录 chmod -R 777 ograc_connector chown -R root:root ograc_connector cd ograc_connector/action ls # 应看到:appctl.sh config_params_lun.json
说明:本环境解包后脚本目录为 /data/ograc_connector/action(官方最新文档默认层级不同,见 8.1),以目录中存在 appctl.sh 与 config_params_lun.json 为准。

4.4 集群参数配置
配置文件为 /data/ograc_connector/action/config_params_lun.json,两节点仅 node_id 不同,其余字段完全一致。
4.4.1 参数说明
| 字段 | 含义与填写要求 | 本环境取值 |
|---|---|---|
| deploy_mode | 部署模式,当前使用 dss(共享存储)模式 | "dss" |
| node_id | 节点序号,从 0 开始 | Node0 为 "0",Node1 为 "1" |
| cms_ip | 业务与心跳网络未分离时,填两节点 IP,分号分隔 | "192.168.3.72;192.168.3.82" |
| db_type | 数据库标识,不建议修改 | "1" |
| mes_ssl_switch | MES 通信 SSL 开关 | false |
| MAX_ARCH_FILES_SIZE | 单个归档文件大小上限,不超过归档盘容量 | "300G" |
| redo_num / redo_size | Redo 文件个数与大小,首次起库会覆盖 Redo 盘,不宜过大 | "6" / "5G" |
| auto_tune | 参数自适应开关,小规格机器建议开启 | "1" |
| dss_vg_list | 数据、Redo、归档盘对应的软链接 | vg1=/dev/dss-disk1、vg2=/dev/dss-disk2、vg3=/dev/dss-disk3 |
| gcc_home | CM 仲裁盘盘符,两节点必须指向同一 LUN | "/dev/gcc-disk" |
| cms_port / dss_port / ograc_port | 各组件端口,可自定义 | "14587" / "1811" / "1611" |
| interconnect_port | 节点间互联端口,逗号分隔 | "1601,1602" |
| _SHM_KEY | 共享内存 key,同机多实例时才需修改 | 17 |
| module_config | 安装与运行配置:ograc_home 安装目录、data_root 数据目录、user 运行用户 | "/opt/ograc"、"/mnt/dbdata"、"ograc" |
4.4.2 配置示例
Node0(dcs72)编辑配置文件:
vi /data/ograc_connector/action/config_params_lun.json
{ "deploy_mode": "dss", "node_id": "0", "cms_ip": "*.*.*.72;*.*.*.82", "db_type": "1", "mes_ssl_switch": false, "MAX_ARCH_FILES_SIZE": "300G", "redo_num": "6", "redo_size": "5G", "auto_tune": "1", "dss_vg_list": { "vg1": "/dev/dss-disk1", "vg2": "/dev/dss-disk2", "vg3": "/dev/dss-disk3" }, "gcc_home": "/dev/gcc-disk", "cms_port": "14587", "dss_port": "1811", "ograc_port": "1611", "interconnect_port": "1601,1602", "_SHM_KEY": 17, "module_config": { "ograc_home": "/opt/ograc", "data_root": "/mnt/dbdata", "user": "ograc" } }
Node1(dcs82)按同一文件修改,仅将 node_id 改为 "1"。
{ "deploy_mode": "dss", "node_id": "1", "cms_ip": "*.*.*.72;*.*.*.82", "db_type": "1", "mes_ssl_switch": false, "MAX_ARCH_FILES_SIZE": "300G", "redo_num": "6", "redo_size": "5G", "auto_tune": "1", "dss_vg_list": { "vg1": "/dev/dss-disk1", "vg2": "/dev/dss-disk2", "vg3": "/dev/dss-disk3" }, "gcc_home": "/dev/gcc-disk", "cms_port": "14587", "dss_port": "1811", "ograc_port": "1611", "interconnect_port": "1601,1602", "_SHM_KEY": 17, "module_config": { "ograc_home": "/opt/ograc", "data_root": "/mnt/dbdata", "user": "ograc" } }
建议使用 vim 编辑文件后,执行 dos2unix config_params_lun.json
4.4.3 配置要点
- node_id 在两节点必须分别为 0 和 1。
- dss_vg_list 与 gcc_home 必须与 4.2.2 建立的软链接一致,两节点 gcc_home 指向同一 LUN。
- redo_num × redo_size × 2 需小于 Redo 盘容量,本配置为 60G,远小于 4T。
- 小规格机器保持 auto_tune 置 1,避免按大规格计算的参数耗尽内存。
4.5 预安装与安装
以下操作均在 root 用户下执行。
4.5.1 预安装
# 两节点均执行 cd /data/ograc_connector/action sh appctl.sh pre_install config_params_lun.json # 预期:各项检查结果依次输出并正常结束;如有 ERROR 按第 8.2 节排查
Node0(dcs72)预执行结果:

Node1(dcs82)预执行结果:

4.5.2 安装节点
两节点依次安装,官方建议等待 Node0 安装完成后再安装 Node1。
Node0(dcs72)执行:
cd /data/ograc_connector/action grep node_id config_params_lun.json # 确认是 "0" sh appctl.sh install config_params_lun.json # 交互提示 please enter ograc password:,输入 ograc 口令(字母、数字、特殊符号组合,不强制大写)并记录备用,如 Huawei@123 # 安装过程:写入 /opt/ograc → 初始化 /mnt/dbdata → 共享 LUN 上创建 vg1/vg2/vg3 → 初始化 gcc # 仲裁盘 → 启动 cms server → 注册并首次启动 dss、db 资源(Node0 首次启动建 Redo 与数据文件,耗时较长) # 预期最终输出:start success

ograc 安装过程会提示 please enter ograc password:,密码可通过 here-doc、expect 或第三方脚本自动输入;本文档示例以交互输入演示。
Node1(dcs82)待 Node0 安装成功后执行:
cd /data/ograc_connector/action grep node_id config_params_lun.json # 确认是 "1" sh appctl.sh install config_params_lun.json # 输入与 Node0 相同的 sys 口令;预期最终输出:start success

4.5.3 启动节点
建议先启动节点 Node0 ,再启动节点 Node1,并在两个节点上依次执行:
Node0(dcs72)执行:
cd /data/ograc_connector/action sh appctl.sh start
其中,节点 Node0 首次 start 会创建 Redo 和数据文件,耗时较长,请耐心等待;节点 Node1 首次 start 不涉及该过程,耗时相对较短。

Node1(dcs82)待 Node0 安装成功后执行:
cd /data/ograc_connector/action sh appctl.sh start

# 两个节点安装完成后,执行如下命令 ps -ef | grep -E 'cms server|dssserver|ogracd' | grep -v grep # 预期:能看到 cms server、dssserver、ogracd 三类进程

4.6 启动验证与跨节点读写
4.6.1 实例启停
DB 的数据文件与归档文件存放在 DSS 卷组上,DSS 是 DB 的存储底座,故启动顺序为 dss → db,停止顺序相反。
# 切换到数据库用户 su -s /bin/bash ograc # 启动:先 DSS 后 DB cms res -start dss # 预期输出:start resource succeed. cms res -start db # 停止:先 DB 后 DSS cms res -stop db # 预期输出:stop resource succeed. cms res -stop dss

其他常用形式:
# 启动或停止指定节点(NODE_ID 为 0 或 1) cms res -start db -node 0 cms res -start dss -node 1 cms res -stop db -node 0 # 指定等待超时(毫秒),默认超时 600 秒 cms res -start db 120000 # 启动 DB 前确认 dssserver 进程存活(CMS Server 存活时会被自动拉起) ps ux | grep dssserver | grep -v grep

4.6.2 连接数据库执行 SQL
数据库相关操作均在 ograc 用户下执行。以 SYSDBA 身份本地连接并验证:
su -s /bin/bash ograc ogsql / as sysdba -q -- 验证 SQL,应返回 1 select 1; -- 退出 quit;

4.6.3 跨节点读写验证
官方部署指南的验证方式:在一个节点建表写入数据,在另一节点直接查询,能读到刚提交的数据即说明集群与共享存储正常。
Node0 窗口:
su -s /bin/bash ograc ogsql / as sysdba -q create table test(a int); insert into test values(123); commit; select * from test; -- 返回 123 quit;

Node1 窗口(直接查询,不重新建表):
su -s /bin/bash ograc ogsql / as sysdba -q select * from test; -- 应返回 123,即 Node0 刚提交的数据 quit;

4.7 集群状态查询
# 切换到数据库用户 su -s /bin/bash ograc cms stat # 查看集群整体状态(节点 × 资源矩阵) cms stat -res db # 查看 db 资源 cms stat -res dss # 查看 dss 资源 cms stat -node # 查看节点角色(server / agent) cms stat -server # 查看 CMS 自身状态

结果判断:
- STAT:ONLINE 在线、OFFLINE 离线、UNKNOWN 未知。两节点 db 与 dss 均为 ONLINE,即集群正常。
- ROLE:一类资源在集群中有且仅有一个 REFORMER(上例为节点 0)。
- WORK_STAT:1 表示已加入集群(RC_JOINED)。
cms stat -node的 ROLE 为节点类型:server 为 CMS Master(负责脑裂仲裁等流程),agent 为非 Master。cms stat -server关注 SRV_READY(TRUE 为正常)与 TIME_GAP(本节点与其他节点 CMS 时间跳变的最大值,越小越好)。LAST_CHECK 与 HB_TIME 持续更新且接近,说明 CMS 心跳正常。
4.8 部署结果核对
| 类别 | 检查项 | 结果 |
|---|---|---|
| 环境 | SELinux 关闭、firewalld 停用;依赖就绪(lz4 ≥ 1.8.3);时间同步完成;enp4s0 互通 | □ |
| 存储 | 共享 LUN 的 WWN/serial 两节点一致;软链接 dss-disk1/2/3、gcc-disk 建立并授权 777 | □ |
| 配置 | node_id 分别为 0/1,其余字段两节点一致 | □ |
| 安装 | pre_install 与 install 均成功,两节点输出 start success | □ |
| 验证 | ogsql 可执行 SQL;Node0 插入 123 后 Node1 立即读到 | □ |
| 状态 | cms stat 两节点 db/dss 均为 ONLINE | □ |
5 数据一致性验证
本章在已部署的双节点集群上,验证多主架构下数据定义与数据变更的全局可见性,以及并发更新同一行时的行级锁行为。三个场景共用测试表 test_mulNode(c1 int, c2 varchar(32), c3 int)。
准备:在 Node0 与 Node1 各打开一个 ogsql 会话(以下称 Node0 会话、Node1 会话):
# 两节点均执行 su -s /bin/bash ograc ogsql / as sysdba -q
说明:
set autocommit只对当前 ogsql 会话生效,会话退出后重新连接需再次设置。
5.1 对象定义同步(DDL)
验证点:在 Node0 创建表后,Node1 创建同名表应报对象已存在;Node0 删除表后,Node1 可重新创建。
两个会话先开启自动提交:
set autocommit=on; show autocommit; -- 预期输出:on
Node0 会话:建表。
DROP TABLE IF EXISTS test_mulNode; CREATE TABLE test_mulNode(c1 int, c2 varchar(32), c3 int);
Node1 会话:重复创建同名表,预期报对象已存在错误:
CREATE TABLE test_mulNode(c1 int, c2 varchar(32), c3 int);

Node0 会话:删除表。
DROP TABLE IF EXISTS test_mulNode;
Node1 会话:重新建表、插入并查询,预期成功:
CREATE TABLE test_mulNode(c1 int, c2 varchar(32), c3 int); INSERT INTO test_mulNode VALUES(1,'abc',11); SELECT * FROM test_mulNode; -- 返回 (1, 'abc', 11)

结果:对象定义操作全局同步。Node0 建表后,Node1 无法再建同名表;Node0 删表后,Node1 可以重新创建。
执行回显按下列表格记录(作为验证留存的证据,运行后填写):
| 证据项 | 预期 |
|---|---|
| Node1 重复建表的回显 | 报对象已存在类错误,错误码形如 OG-01301,提示 already exists(具体以实际回显为准) |
| Node0 删除后,Node1 重建的回显 | 建表成功;INSERT 返回 1 行 |
| Node1 查询结果 | SELECT * FROM test_mulNode; 返回 (1, abc, 11) |
5.2 数据变更同步(DML)
验证点:任一节点提交的数据变更,在另一节点立即可见。
两个会话开启自动提交:
set autocommit=on;
Node0 会话:建表并插入三条数据。
DROP TABLE IF EXISTS test_mulNode; CREATE TABLE test_mulNode(c1 int, c2 varchar(32), c3 int); INSERT INTO test_mulNode VALUES(1,'aaa',11),(2,'bbb',22),(3,'ccc',33); SELECT * FROM test_mulNode WHERE c1=1; -- 返回 (1, 'aaa', 11)
Node1 会话:修改 Node0 刚插入的数据。
UPDATE test_mulNode SET c3=77 WHERE c1=1;
Node0 会话:再次查询同一行。
SELECT * FROM test_mulNode WHERE c1=1; -- 返回 (1, 'aaa', 77)

结果:两节点均可读写。Node1 提交的修改在 Node0 立即可见,数据全局一致。
5.3 行级锁与事务隔离
验证点:两节点并发更新同一行时,后到的事务被阻塞,待持有锁的事务提交后才继续执行,确认行级锁与事务隔离生效。
两个会话先关闭自动提交:
set autocommit=off; show autocommit; -- 预期输出:off
以下步骤按顺序执行,前一步完成后再进入下一步。
Node0 会话:建表、插入数据并提交。
DROP TABLE IF EXISTS test_mulNode; CREATE TABLE test_mulNode(c1 int, c2 varchar(32), c3 int); INSERT INTO test_mulNode VALUES(2,'bbb',22),(3,'ccc',33),(4,'ddd',44); COMMIT;
Node0 会话:更新 c1=4 所在行,成功持有该行的行级锁,暂不提交。
UPDATE test_mulNode SET c3=55 WHERE c1=4; -- 预期输出:1 row affected
Node1 会话:更新同一行。该语句会一直等待,这是行级锁生效的正常行为。
UPDATE test_mulNode SET c3=66 WHERE c1=4; -- 阻塞等待,不返回
Node0 会话:提交,释放行锁。
COMMIT;
Node1 会话:此时上一条 UPDATE 获得锁并完成,提交使结果永久生效。
COMMIT;
Node0 会话:查询最终结果。
SELECT * FROM test_mulNode WHERE c1=4; -- 返回 (4, 'ddd', 66)

结果:并发更新同一行时,事务被行级锁串行化,最终值为后提交事务的结果 (4, 'ddd', 66),事务的隔离性与一致性得到保证。若 Node1 的 UPDATE 未被阻塞而立即返回,说明行锁未生效,需停止验证并检查集群状态。
阻塞时长是行锁生效的量化证据,建议记录。方法:在 Node1 上另开一个终端,Node1 会话发起 UPDATE 前记录一次时间 T1,待 Node0 提交、该 UPDATE 返回后再记录 T2,阻塞时长即为两者之差:
# 在 Node1 的另一个终端执行(两次) date '+%F %T'
按下列表格回填:
| 证据项 | 预期 |
|---|---|
| 阻塞开始时间 T1(Node1 发起 UPDATE 前) | --- |
| 阻塞结束时间 T2(Node1 UPDATE 返回后) | --- |
| 阻塞时长(T2 − T1) | Node0 提交前持续等待,提交后立即返回 |
| Node1 UPDATE 返回回显 | 1 row updated(或 1 rows affected) |
| 最终一致性 | Node0 查询返回 (4, ddd, 66) |
5.4 验证结果核对
- DDL:Node0 建表后 Node1 建同名表失败;Node0 删表后 Node1 重建并写入成功
- DML:Node1 将 c3 改为 77 后,Node0 查询立即读到 77
- 行锁:Node1 的 UPDATE 在 Node0 提交前保持等待;最终结果为 (4, 'ddd', 66)
- 行锁阻塞时长已记录(T1 / T2 / 阻塞秒数)
- DDL 冲突错误码、DML 与行锁回显已留存(5.1/5.3 记录表)
- 实际输出与预期结果一致,执行回显已留存
6 负载与线性扩展能力验证
本章通过 TPC-C 基准评估集群负载能力与扩展性:分别以"应用只访问 Node0"与"应用由 JDBC 驱动轮询访问两个节点"两种方式加压,对比 tpmC。BenchMarkSQL 运行在独立的压测客户端上,不占用集群节点资源;压测客户端需能连通集群 1611 端口。
6.1 集群参数准备
在 Node0、Node1 两个 ogsql 会话中分别执行以下语句(每条单独执行)。用户等对象随集群全局同步,同一语句在第二个节点重复执行时,若提示对象已存在等错误,说明已由另一节点创建生效,可忽略,以第一次成功为准:
-- 在 Node0 的 ogsql 中执行 -- 1. 创建 TPCC 用户(口令自定义并记录,6.3 的 props 文件需保持一致) create user TPCC identified by 'Tpcc@123'; -- 2. 授权 grant create session to TPCC; grant create table to TPCC; grant dba to TPCC; grant inherit privileges on user SYS to TPCC; -- 3. 放开远程 SYSDBA / SYS 登录(两个参数各设置一次即可) alter system set ENABLE_SYSDBA_REMOTE_LOGIN = TRUE; alter system set ENABLE_SYS_REMOTE_LOGIN = TRUE; -- 4. 放通 HBA,允许远端访问 alter system add hba entry 'host * 0.0.0.0/0'; alter system reload hba config; -- 5. 退出 quit; -- 在 Node1 的 ogsql 中执行 ALTER SYSTEM SET ENABLE_SYS_REMOTE_LOGIN = TRUE; ALTER SYSTEM SET ENABLE_SYSDBA_REMOTE_LOGIN = TRUE; ALTER SYSTEM ADD HBA ENTRY 'host * 0.0.0.0/0'; ALTER SYSTEM RELOAD HBA CONFIG; # 上述部分命令如果不在 Node1 的 ogsql 中执行,在双节点压测的时候会报:org.opengauss.core.v3.ConnectionFactoryImpl createConnection SEVERE: SQLException occur, connect to host xxx.xxx.xxx.82:1611 failed. org.opengauss.util.PSQLException: login database failed.


上述参数在集群重启后生效(见 6.2)。
6.2 集群重启使参数生效
6.1 设置的参数在集群重启后生效。在 Node0 执行,先按依赖反序停止,再按依赖正序启动:
# 切换到数据库用户 su -s /bin/bash ograc # 停止:先 DB 后 DSS cms res -stop db cms res -stop dss # 启动:先 DSS 后 DB cms res -start dss cms res -start db

6.3 基准数据装载
在压测客户端上进入 BenchMarkSQL 运行目录(本环境为 /home/workshop/benchmarksql/run,其他环境按实际部署目录调整),新建配置文件 props_tpcc.og:
cd /home/workshop/benchmarksql/run # 将如下内容写入到props_tpcc.og文件中
内容如下。conn 中的 IP 需替换为实际 Node0 地址,password 填写 6.1 步骤 1 设置的口令:
cat > props_tpcc.og << EOF db=postgres driver=org.opengauss.Driver conn=jdbc:oGRAC://*.*.*.72:1611 user=TPCC password=Tpcc@123 warehouses=200 loadWorkers=100 terminals=50 runTxnsPerTerminal=0 runMins=5 limitTxnsPerMin=0 terminalWarehouseFixed=true newOrderWeight=45 paymentWeight=43 orderStatusWeight=4 deliveryWeight=4 stockLevelWeight=4 EOF

执行数据装载:
./runDatabaseBuild.sh props_tpcc.og


装载 200 个 warehouse,过程无 ERROR / FATAL 即通过。装载耗时较长,请耐心等待,期间不要中断或操作集群。
装载完成后记录:
| 项目 | 记录值 |
|---|---|
| 装载起始 / 结束时间 | ____ |
| 装载总耗时 | ____ |
| 输出中是否有 ERROR / FATAL | ____(应为无) |
| run 目录下生成的结果目录名(以 results_ 开头) | ____ |
说明:装载结果目录与后续 6.4/6.5 压测结果目录不同,分别留存,避免混淆。
6.4 单节点加压
将 props 中连接串改为单节点IP,再执行压测:
cat > props_tpcc.og << EOF db=postgres driver=org.opengauss.Driver conn=jdbc:oGRAC://*.*.*.72:1611 user=TPCC password=Tpcc@123 warehouses=200 loadWorkers=100 terminals=50 runTxnsPerTerminal=0 runMins=15 limitTxnsPerMin=0 terminalWarehouseFixed=true newOrderWeight=45 paymentWeight=43 orderStatusWeight=4 deliveryWeight=4 stockLevelWeight=4 EOF

压测期间资源观测(建议执行,两组加压共用)
仅记录 tpmC 即可完成本项对比;若希望结果可解释、可复核,建议在加压期间同步采集两节点的资源使用与共享盘 I/O。采集对象为 dcs72 与 dcs82 两个数据库节点,重点观察数据盘(dss-disk1)的利用率与队列深度;若压测客户端与集群同机部署,客户端也一并采集,用于确认客户端不是瓶颈。
先在两节点分别确认数据盘对应的实际设备名(两节点盘符可能不同,且重启后可能变化,以命令输出为准):
# dcs72 与 dcs82 分别执行 readlink -f /dev/dss-disk1 # dcs72 预期形如 /dev/sdb;dcs82 预期形如 /dev/sde(以实际输出为准)
在两节点各开一个终端,启动三项采集(设备名按上面输出替换):
# dcs72:DATA_DEV=sdb;dcs82:DATA_DEV=sde(按 readlink 实际输出填写) DATA_DEV=sdb # 每 5 秒采样一次,带时间戳写入日志 vmstat -t 5 > /tmp/vmstat_node.log 2>&1 & iostat -x -t 5 "$DATA_DEV" > /tmp/iostat_node.log 2>&1 & mpstat -P ALL -t 5 > /tmp/mpstat_node.log 2>&1 &
每次压测(6.4 单节点、6.5 双节点)开始前与结束后,在任意节点执行一次时间标记,用于把采集日志与压测窗口对齐:
date '+%F %T'
全部加压结束后,在两节点停止采集并留存日志:
# dcs72 与 dcs82 分别执行;-x 为精确匹配进程名,不会误杀其他进程 pkill -x vmstat; pkill -x iostat; pkill -x mpstat
说明:
vmstat -t输出的 CPU 列含 us/sy/id/wa(wa 即 I/O 等待);iostat -x输出中数据盘一行的%util为利用率、avgqu-sz为平均队列长度(列名以实际表头为准)。两节点同一 LUN 对应各自的%util都要看:单节点加压时业务 I/O 集中在被访问节点,双节点加压时会分散到两端。
保持 props 中连接串仅指向 Node0(conn=jdbc:oGRAC://*.*.*.72:1611),执行压测:
./runBenchmark.sh props_tpcc.og 2>&1 | tee tpcc_test_single.log

注意:压测入口是 runBenchmark.sh,与 6.3 数据装载使用的 runDatabaseBuild.sh 用途不同,不要混用。装载脚本用于建表并写入数据,若在压测阶段重复执行,可能因对象已存在失败或干扰已有测试数据。
压测约持续 15 分钟,结束后记录输出中的 tpmC 与起止时间。输出中的 rollback 计数是 BenchmarkSQL 按 TPC-C 规范产生的预期回滚(New-Order 流程会触发),只要 error 字段合计为 0 即无真实错误,两者不要混同:
| 项目 | 记录值 |
|---|---|
| Measured tpmC | ____ |
| Measured tpmTOTAL | ____ |
| Transaction Count(事务总数) | ____ |
| rollback / error | ____ / ____(error 应为 0) |
| 起止时间 | ____ |
| 压测结果目录名 | ____ |
6.5 双节点加压
将 props 中连接串改为双节点轮询分发,再执行压测:
# 修改为两个节点IP conn=jdbc:oGRAC://*.*.*.72:1611,*.*.*.82:1611?autoBalance=roundrobin # 使用如下命令修改 props_tpcc.og cat > props_tpcc.og << 'EOF' db=postgres driver=org.opengauss.Driver conn=jdbc:oGRAC://*.*.*.72:1611,*.*.*.82:1611?autoBalance=roundrobin user=TPCC password=Tpcc@123 warehouses=200 loadWorkers=100 terminals=50 runTxnsPerTerminal=0 runMins=15 limitTxnsPerMin=0 terminalWarehouseFixed=true newOrderWeight=45 paymentWeight=43 orderStatusWeight=4 deliveryWeight=4 stockLevelWeight=4 EOF

执行双节点压测,如下所示:
cd /home/workshop/benchmarksql/run ./runBenchmark.sh props_tpcc.og 2>&1 | tee tpcc_test_rac.log


autoBalance=roundrobin 作用于 JDBC 连接选择:驱动将新建连接轮询分发到两个节点,压测终端随之分散到两个实例(并非逐事务路由)。加压开始前、结束后按 6.4 的方法做时间标记;资源采集若仍在运行可继续使用,无需重启。记录结果:
| 项目 | 记录值 |
|---|---|
| Measured tpmC | ____ |
| Measured tpmTOTAL | ____ |
| Transaction Count(事务总数) | ____ |
| rollback / error | ____ / ____(error 应为 0) |
| 起止时间 | ____ |
| 压测结果目录名 | ____ |
两轮压测除连接串外,props 其余参数保持一致,便于横向对比。
6.6 结果对比与扩展效率
结果按下列表格汇总(数值回填自 6.4/6.5):
| 指标 | 单节点 (Node0: 72) | 双节点 (RAC: 72+82) | 倍数 (双/单) |
|---|---|---|---|
| tpmC (NewOrders) | 104,437.58 | 175,532.38 | 1.68x |
| tpmTOTAL | 232,123.53 | 390,208.62 | 1.68x |
| 并发数 (terminals) | 50 | 50 | - |
| 仓库数 (warehouses) | 200 | 200 | - |
| 压测时长 (runMins) | 15 min | 15 min | - |
线性扩展效率按以下公式计算:
线性扩展效率 = 双节点 tpmC ÷(单节点 tpmC × 2)
线性扩展效率 = 175,532.38 ÷ (104,437.58 × 2) ≈ 84.0%
效率大于 0.85 视为满足线性扩展预期。同规格环境的参考值约为单节点 11.2 万 tpmC、双节点 20.2 万 tpmC(对应效率约 0.90),实际以本次实测数据为准。
数值取自 6.4 采集日志中压测时间窗内的平均值:%util 与 avgqu-sz 看 iostat 日志中数据盘一行,CPU %wa 看 vmstat 日志 CPU 列的 wa。
结果解读要点
- 多主对等架构下,JDBC 驱动将连接轮询分发到两个计算节点,节点间通过共享存储与消息通道同步事务与锁状态。与理想两倍吞吐的差值来自跨节点协调、锁同步与网络开销,实测受机器性能波动影响,可能存在约 ±10% 的偏差。
- 若效率明显高于 1(接近或超过 100%),先结合资源观测解释,不必怀疑脚本或数据:单节点加压时业务 I/O 全部落在被访问节点,数据盘可能已接近饱和(%util 接近 100%、avgqu-sz 偏大);双节点加压时 I/O 分散到两端,第二个节点同时带来额外的 CPU 与主机侧 I/O 路径,吞吐因而可能超过单节点的两倍模型。这属于存储瓶颈被分摊后的系统级表现,并不代表单节点计算能力翻倍。
- 若双节点加压时数据盘 %util 已接近 100% 且 avgqu-sz 显著增大,说明当前并发已接近环境上限,继续增加终端对吞吐提升有限,甚至可能下降。
本文 tpmC 为同一环境内的相对对比,用于评估扩展趋势,并非经 TPC 审计的公开成绩。
7 验证结果汇总
| 阶段 | 关键验证点 |
|---|---|
| 部署 | 两节点安装输出 start success;启停顺序正确;cms stat 两节点 db/dss 均为 ONLINE |
| 数据一致性 | DDL/DML 跨节点同步;并发更新同一行被行锁串行化 |
| 负载扩展 | 集群参数生效;单节点、双节点 tpmC 已实测;线性扩展效率大于 0.85;rbps(如启用)状态 ONLINE |
建议保留各步命令回显作为记录,便于后续核对与问题回溯。
8 版本差异与常见问题
8.1 与官方文档的版本差异
本环境使用的 B001 安装包与官方文档站点当前 RELEASE 版本存在少量默认值差异,如下表所示:
| 项 | 本环境(B001) | 官方最新文档 |
|---|---|---|
| 解包目录 | /data/ograc_connector | /data/ograc/ograc_connector |
| ograc_home | /opt/ograc | /data/ograc_install/ograc |
| data_root | /mnt/dbdata | /data/ograc_install/dbdata |
| 安装包命名 | oGRAC-1.0.0.B001-...-aarch64.tgz | openGauss-oGRAC-...-RELEASE.tgz |
8.2 常见问题排查
| 现象 | 排查方向 |
|---|---|
| pre_install / install 失败 | 查看 /opt/ograc/log/cms/ 与 /opt/ograc/log/ograc/ 日志;核对共享 LUN 是否可见、CM 投票盘在两节点是否指向同一 LUN |
| cms res -start db 失败 | 检查 dssserver 进程是否存活(ps ux | grep dssserver)、DSS 卷组状态、共享存储链路 |
| ogsql 连接失败 | 检查 1611 端口监听(ss -tlnp | grep 1611);核对 HBA 白名单 oghba.conf |
| 数据一致性验证结果不符 | 确认两节点 cms stat 均 ONLINE;ogsql 重连后重新设置 autocommit |
| TPCC 找不到驱动 | 核对 props 中 driver=org.opengauss.Driver 与 JDBC 驱动 jar 的加载路径 |
| tpmC 明显偏低 | 核对压测机资源与终端数/装载并发是否受机器能力限制 |
| rbps 启动失败 | 核对数据库侧 RBP 配置是否启用,日志见 /opt/ograc/log/rbps/ |
日志位置速查:/opt/ograc/log/cms/cms_server.log、/opt/ograc/log/dss/run/instance.log、/opt/ograc/log/ograc/ogracd.rlog、rbps 相关日志在 /opt/ograc/log/rbps/。定位问题应优先查看日志,再判断是配置问题还是环境问题。
9 参考资料
文中命令与参数依据 openGauss 官方 oGRAC 文档编写,并结合本环境(oGRAC-1.0.0.B001、aarch64 架构 Linux)的目录与取值做了适配。