openGauss 常用运维指令手册

运维指令手册 43.1 KB 原文

openGauss 常用运维指令手册

适用版本:openGauss 5.0 / 6.0 / 7.0.0 LTS(当前推荐) 约定:# root 或 sudo,$ omm 用户,postgres=# gsql 提示符,<xxx> 为占位符。 差异标注:正文用 > **版本差异** 引用块标注跨版本不一致之处。 更新时间:2026-11


目录

  1. 版本与支持周期
  2. 架构与目录约定
  3. 下载与安装
  4. 集群部署(gs_preinstall / gs_install)
  5. 服务启停三层命令的分工
  6. gsql 客户端与连接认证
  7. 配置文件与参数
  8. 用户、角色与权限
  9. 库表对象与存储引擎
  10. 备份与恢复
  11. WAL、归档与 PITR
  12. 主备复制与 CM 集群管理
  13. 日志体系
  14. 性能诊断
  15. 空间、VACUUM 与膨胀
  16. 扩缩容、升级与迁移
  17. 高频故障速查
  18. 危险命令与避坑清单
  19. 附录:一键巡检脚本

1. 版本与支持周期

1.1 发布节奏

openGauss 由华为主导、开放原子开源基金会托管,采用「大版本 + 补丁」模式:每 2 年发一个大版本,社区提供 3 年维护支持,OGSP(openGauss 服务伙伴)可延长到 3 年以上。

版本 类型 维护截止 状态(2026-11)
3.0.0 LTS 2026-03 已到期,建议升级
3.1.1 维护版 — 停止维护
5.0.0 LTS 2027-03 维护中
6.0.0 LTS 2028-09 维护中(6.0.6 为最新补丁)
7.0.0 LTS 2029-09-30 当前推荐

与 PostgreSQL 的关系要说清楚:openGauss 早期基于 PostgreSQL 9.2 内核,但经过华为重写,不是 PG 的发行版。到了 5.0 之后,两者在存储引擎(UStore/AStore)、并发控制(CSN 事务)、执行器(向量化)、安全(全密态)上已经分道扬镳。 运维上的直接后果:不能用 PG 的 pg_ctl、psql、pg_dump 去操作 openGauss,工具名前缀全部是 gs_。

1.2 版本识别

# 二进制版本
gsql --version
gaussdb --version

# 集群版本(含补丁号)
gs_om -t status --detail
-- 数据库内版本
SELECT version();
SELECT * FROM pg_database_version();   -- 部分版本可用

-- 兼容模式(关键,决定 SQL 语法行为)
SHOW sql_compatibility;

1.3 四种兼容模式

sql_compatibility 在建库时指定,之后不能改:

取值 兼容 典型差异
A Oracle 空串等于 NULL、DUAL 表、NVL、序列 NEXTVAL、大小写敏感
B MySQL 反引号、LIMIT、AUTO_INCREMENT、IFNULL
C Teradata 特定分析函数语法
PG PostgreSQL 标准 PG 行为,information_schema 完整
-- 建库时指定(推荐 A 或 B,按源库来)
CREATE DATABASE app_db WITH ENCODING='UTF8' DBCOMPATIBILITY='A';

-- 查询现有库的兼容模式
SELECT datname, datcompatibility FROM pg_database;

这是 openGauss 迁移的第一道坎:库建好之后 DBCOMPATIBILITY 不可修改,选错了只能新建库重导。从 Oracle 迁就用 A,从 MySQL 迁就用 B,新建系统建议 PG。


2. 架构与目录约定

2.1 进程模型

openGauss 是多线程架构(PG 是多进程),主进程 gaussdb 内部派生线程:

# 查看线程(不是进程)
ps -eLf | grep gaussdb | head -20

# 关键线程
#   main           主线程
#   pagewriter     脏页刷盘
#   walwriter      WAL 写盘
#   checkpointer   检查点
#   bgworker       后台任务
#   gaussdb worker 并行执行

2.2 目录结构

路径 内容
/usr/local/opengauss($GAUSSHOME) 数据库二进制、工具、插件
/usr/local/opengauss/data($PGDATA) 数据目录、配置文件、WAL
$PGDATA/postgresql.conf 主配置
$PGDATA/pg_hba.conf 客户端认证
$PGDATA/pg_ident.conf 用户映射
$PGDATA/pg_xlog/ WAL 日志(注意仍叫 pg_xlog,不是 pg_wal)
$PGDATA/base/ 各数据库的物理文件
$PGDATA/pg_log/ 运行日志(部分版本在 /var/log/omm/)
/var/log/omm/ omm 用户的集群日志
# 确认环境变量(必须用 omm 用户)
su - omm
echo $GAUSSHOME
echo $PGDATA
echo $LD_LIBRARY_PATH   # 必须包含 $GAUSSHOME/lib

切换用户必须 su - omm,不能 su omm。后者不加载 profile,$GAUSSHOME/$LD_LIBRARY_PATH 为空,所有 gs_* 命令都会报「找不到命令」或「找不到动态库」。

2.3 默认端口

服务 默认端口 说明
数据库 15400 不是 PG 的 5432,安装时也可指定
CM(集群管理) 由 cm_agent.ini 配置 3.0+ 引入
备机只读 与主机同端口 通过 hot_standby=on 提供只读

3. 下载与安装

3.1 官方入口

用途 地址
官网 https://opengauss.org/zh/
下载中心 https://opengauss.org/zh/download/
文档中心 https://docs.opengauss.org/zh/
代码仓库 https://gitee.com/opengauss/openGauss-server
Docker 镜像 https://hub.docker.com/r/opengauss/opengauss
镜像站(下载加速) https://download-opengauss.osinfra.cn/

3.2 安装包类型

类型 适用 说明
企业版 生产集群 含 CM、OM、全套工具,需 gs_preinstall
极简版 单机测试 解压即用,无 CM
轻量版 容器/边缘 体积小,功能裁剪
企业版(noLSE) 无 LSE 指令的 ARM 鲲鹏早期芯片兼容
Docker 开发测试 opengauss/opengauss:7.0.0
# Docker 快速体验
docker pull opengauss/opengauss:7.0.0
docker run -d --name opengauss --privileged=true \
  -e GS_PASSWORD='Enmo@123' \
  -p 15400:5432 \
  -v /data/opengauss:/var/lib/opengauss \
  opengauss/opengauss:7.0.0

# 连接(容器内默认端口 5432,映射到宿主机 15400)
gsql -d postgres -h 127.0.0.1 -p 15400 -U gaussdb -W 'Enmo@123'

官方镜像里数据库端口是 5432,映射出来才看到 15400。别拿镜像的行为去推断裸机安装的端口。

3.3 环境准备

# 1) 创建用户组与用户
groupadd dbgrp
useradd -g dbgrp -m -d /home/omm omm
echo 'omm@123' | passwd --stdin omm

# 2) 目录与权限
mkdir -p /usr/local/opengauss /var/log/omm /opt/software/openGauss
chown -R omm:dbgrp /usr/local/opengauss /var/log/omm

# 3) 内核参数
cat >> /etc/sysctl.conf <<'EOF'
kernel.shmall = 4294967296
kernel.shmmax = 68719476736
kernel.shmmni = 4096
kernel.sem = 50100 64128000 50100 1280
fs.file-max = 7672460
net.ipv4.ip_local_port_range = 9000 65500
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 1048576
EOF
sysctl -p

# 4) 资源限制(omm 用户)
cat >> /etc/security/limits.conf <<'EOF'
omm soft nofile 1000000
omm hard nofile 1000000
omm soft nproc  1000000
omm hard nproc  1000000
omm soft stack  unlimited
omm hard stack  unlimited
omm soft memlock unlimited
omm hard memlock unlimited
EOF

# 5) 关闭 SELinux / 防火墙(或放行端口)
setenforce 0
systemctl stop firewalld

# 6) 关闭 swap(可选,但强烈建议)
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab

# 7) 时间同步
systemctl enable --now chronyd
chronyc sources

3.4 解压与预安装

# 解压安装包(root)
cd /opt/software/openGauss
tar xzf openGauss-7.0.0-openEuler-64bit-all.tar.gz
tar xzf openGauss-7.0.0-openEuler-64bit-om.tar.gz

# 预安装(root 执行,准备目录、权限、环境变量、SSH 互信)
cd /opt/software/openGauss/script
./gs_preinstall -U omm -G dbgrp -X /opt/software/openGauss/cluster_config.xml

# 预安装成功标志
# Successfully set finish flag.
# Preinstallation succeeded.

预安装会做这些事:建目录、改权限、写环境变量到 /etc/profile.d/、配置 omm 用户互信、检查依赖。预安装失败几乎都是权限或 SSH 互信问题。

# 手动配置互信(预安装失败时补救)
su - omm
gs_ssh -c "date"          # 能通说明互信 OK

4. 集群部署(gs_preinstall / gs_install)

4.1 集群配置文件

<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
  <CLUSTER>
    <PARAM name="clusterName" value="og_primary"/>
    <PARAM name="nodeNames" value="og-node1,og-node2"/>
    <PARAM name="gaussdbAppPath" value="/usr/local/opengauss/app"/>
    <PARAM name="gaussdbLogPath" value="/var/log/omm"/>
    <PARAM name="tmpMppdbPath" value="/opt/omm/tmp"/>
    <PARAM name="gaussdbToolPath" value="/usr/local/opengauss/tool"/>
    <PARAM name="corePath" value="/opt/omm/corefile"/>
    <PARAM name="backIp1s" value="10.0.0.11,10.0.0.12"/>
  </CLUSTER>

  <DEVICELIST>
    <DEVICE sn="og-node1">
      <PARAM name="name" value="og-node1"/>
      <PARAM name="azName" value="AZ1"/>
      <PARAM name="azPriority" value="1"/>
      <PARAM name="backIp1" value="10.0.0.11"/>
      <PARAM name="sshIp1" value="10.0.0.11"/>
      <PARAM name="dataNum" value="1"/>
      <PARAM name="dataPortBase" value="15400"/>
      <PARAM name="dataNode1" value="/usr/local/opengauss/data,og-node2,/usr/local/opengauss/data"/>
    </DEVICE>

    <DEVICE sn="og-node2">
      <PARAM name="name" value="og-node2"/>
      <PARAM name="azName" value="AZ1"/>
      <PARAM name="azPriority" value="1"/>
      <PARAM name="backIp1" value="10.0.0.12"/>
      <PARAM name="sshIp1" value="10.0.0.12"/>
    </DEVICE>
  </DEVICELIST>
</ROOT>
参数 说明
clusterName 集群名,会成为 systemd 服务名 opengauss-<clusterName>
dataPortBase 基础端口,主库 15400,备库自动 +1
dataNode1 数据目录与备机列表,格式 主机目录,备机1,备机1目录,...
backIp1s 所有节点业务 IP,逗号分隔

dataNode1 里主机目录在前,后面两两一组(备机名, 备机目录)。写错会导致备机数据目录冲突,安装直接失败。

4.2 安装

# 切到 omm 用户执行
su - omm
cd /opt/software/openGauss/script

gs_install -X /opt/software/openGauss/cluster_config.xml \
  --gsinit-parameter="--encoding=UTF8" \
  --dn-guc="max_connections=3000" \
  --dn-guc="shared_buffers=8GB" \
  --dn-guc="password_encryption_type=2"

# 安装过程会提示设置数据库初始密码(需满足复杂度:8位以上,含3类字符)
# 安装后检查
gs_om -t status --detail
gsql -d postgres -p 15400 -r

4.3 卸载

# 停止集群
gs_om -t stop

# 卸载(omm 用户)
gs_uninstall --delete-data

# 清理环境(root)
cd /opt/software/openGauss/script
./gs_postuninstall -U omm -G dbgrp -X cluster_config.xml

5. 服务启停三层命令的分工

openGauss 有三套启停命令,搞混是新手最大的痛点。记住分工:

命令 层级 适用场景
gs_om 集群级(OM 工具) 整套集群启停、状态查询、主备切换
cm_ctl 集群级(CM 组件) 3.0+ 装了 CM 后的标准方式,支持自动故障切换
gs_ctl 单实例级 单节点启停、备机重建、单点排查

5.1 gs_om(最常用)

# 状态
gs_om -t status
gs_om -t status --detail
gs_om -t status --all

# 启停(整个集群)
gs_om -t start
gs_om -t stop
gs_om -t restart

# 只启停某节点
gs_om -t start -h og-node2
gs_om -t stop -h og-node2

# 主备切换
gs_om -t switch --instance og-node1
gs_om -t switchover

# 备机升主(主机故障时)
gs_om -t failover

# 刷新 ETCD(CM 模式下改了配置后)
gs_om -t refreshconf

# 重建 CM 配置文件
gs_om -t generate-config

# 查看集群静态配置
gs_om -t view

5.2 cm_ctl(装了 CM 后)

# 状态
cm_ctl query -Cv
cm_ctl query -Cvd

# 启停
cm_ctl start
cm_ctl stop
cm_ctl stop -n 1 -D /usr/local/opengauss/data   # 停指定节点
cm_ctl start -n 2

# 主备切换
cm_ctl switchover -n 1 -D /usr/local/opengauss/data
cm_ctl switchover -a          # 自动选主

# 备机重建
cm_ctl build -n 2 -D /usr/local/opengauss/data -b full

# 查看 CM 集群状态
cm_ctl query -Cv -i all

CM 模式下不要用 gs_om -t stop。CM 会检测到实例退出并自动拉起,表现为「停了又起来」。要用 cm_ctl stop,它会同时停 CM 和实例。

5.3 gs_ctl(单实例)

# 启停
gs_ctl start -D $PGDATA
gs_ctl stop -D $PGDATA -m fast
gs_ctl restart -D $PGDATA
gs_ctl status -D $PGDATA

# 停止模式
#   smart  等所有连接断开(可能永远停不下来)
#   fast   断开连接、回滚事务(推荐)
#   immediate  立即退出,重启需要恢复(最后手段)

# 查询主备状态
gs_ctl query -D $PGDATA

# 备机重建(全量)
gs_ctl build -D $PGDATA -b full

# 备机重建(增量)
gs_ctl build -D $PGDATA -b incremental

# 备机升主
gs_ctl failover -D $PGDATA

# 主备切换
gs_ctl switchover -D $PGDATA

# 通知 CM 当前角色(CM 模式下改角色后必须执行)
gs_ctl notify -D $PGDATA -M primary
gs_ctl notify -D $PGDATA -M standby

# 重新加载配置
gs_ctl reload -D $PGDATA
# gs_ctl query 输出关键字段
#   db_state          Primary / Standby / Need repair
#   sender_sent_location     主机已发送位点
#   sender_replay_location   备机已接收位点
#   receiver_received_location  备机已接收
#   receiver_replayed_location  备机已回放
# 四个位点一致 = 无延迟

5.4 正确的停机顺序

# 集群停机(CM 模式)
cm_ctl stop

# 集群停机(非 CM 模式)
gs_om -t stop

# 单节点维护(先切主,再停)
gs_om -t switch --instance og-node1
gs_ctl stop -D $PGDATA -m fast

禁止直接 kill -9 gaussdb。会导致共享内存未释放、WAL 未刷盘,重启时要走崩溃恢复(可能几分钟到几十分钟)。


6. gsql 客户端与连接认证

6.1 连接

# 本机
gsql -d postgres -p 15400 -r

# 远程
gsql -h 10.0.0.11 -p 15400 -d postgres -U omm -W 'Password@123'

# 执行单条
gsql -d postgres -p 15400 -c "SELECT version();"

# 执行文件
gsql -d app_db -p 15400 -f /tmp/init.sql

# 指定输出格式
gsql -d app_db -p 15400 -A -F $'\t' -c "SELECT * FROM t1"   # 无对齐、Tab 分隔

6.2 常用元命令

\l                    -- 列出数据库
\c app_db             -- 切换数据库
\dn                   -- 列出 schema
\dt                   -- 列出表
\dt+ app_db.*         -- 带大小
\d+ orders            -- 表结构详情(含存储分布)
\di                   -- 索引
\dv                   -- 视图
\df                   -- 函数
\du                   -- 用户/角色
\dp                   -- 权限
\x                    -- 行转列显示(宽表必用)
\timing on            -- 显示执行时间
\encoding             -- 字符集
\pset pager off       -- 关闭分页
\o /tmp/out.txt       -- 输出重定向
\i /tmp/script.sql    -- 执行文件
\q                    -- 退出

6.3 认证配置

# pg_hba.conf 典型配置
# TYPE  DATABASE  USER  ADDRESS        METHOD
local   all       all                  trust
host    all       all   127.0.0.1/32   sha256
host    all       all   10.0.0.0/24    sha256
host    app_db    app   10.0.1.0/24    sha256
# 改完 reload
gs_ctl reload -D $PGDATA
# 或
gs_guc reload -N all -I all -c "listen_addresses='0.0.0.0'"
认证方式 说明
trust 免密(仅本机/测试)
sha256 openGauss 默认,推荐
md5 兼容旧客户端
sm3 国密,需开启
cert 证书认证
reject 拒绝

password_encryption_type 决定密码存储算法:1=md5,2=sha256(默认),3=sm3。改成 2 后旧 md5 密码用户需重置密码。这是从老版本升级后「密码突然不对」的原因。

6.4 连接数管理

-- 当前连接
SELECT datname, usename, client_addr, state, backend_start,
       now() - state_change AS duration
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY duration DESC;

-- 按用户统计
SELECT usename, COUNT(*) FROM pg_stat_activity GROUP BY usename ORDER BY 2 DESC;

-- 最大连接数
SHOW max_connections;
SHOW max_process_memory;

-- 断开会话
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid = 12345;

-- 批量断开某用户
SELECT pg_terminate_backend(pid) FROM pg_stat_activity
WHERE usename = 'app' AND state = 'idle' AND state_change < now() - interval '1 hour';

7. 配置文件与参数

7.1 修改方式

# 方式一:gs_guc(推荐,会做合法性校验)
gs_guc set    -N all -I all -c "max_connections=3000"
gs_guc reload -N all -I all -c "work_mem=64MB"
gs_guc check  -N all -I all -c "max_connections"

# 方式二:直接改 postgresql.conf(需 reload/restart)
vi $PGDATA/postgresql.conf
gs_ctl reload -D $PGDATA
参数 说明
-N all 所有节点(也可 -N og-node1)
-I all 该节点所有实例
-c 设置配置项
--values 值文件
set 需重启生效的参数
reload 可动态加载的参数

set 与 reload 用错会出问题:reload 对需要重启的参数只是写入文件但不生效,命令不报错,容易误判「改了没效果」。不确定就用 set(会重启实例,但一定生效)。

7.2 关键参数

参数 默认 建议 说明
max_connections 200 1000~3000 每连接约占用 work_mem 级别内存
shared_buffers 128MB 物理内存 25%~40% 共享缓冲池
work_mem 4MB 16~64MB 单算子排序/哈希内存
maintenance_work_mem 64MB 512MB~2GB VACUUM/CREATE INDEX 用
max_process_memory 12GB 物理内存 60%~70% openGauss 特有,进程总内存上限
cstore_buffers 32MB 512MB~4GB 列存缓冲
wal_level hot_standby logical(需逻辑复制) WAL 级别
max_wal_size 1GB 4~16GB 触发检查点的 WAL 量
checkpoint_timeout 15min 15~30min 检查点间隔
archive_mode off on 归档开关
archive_command — cp %p /archive/%f 归档命令
synchronous_commit on on(金融)/ off(可容忍丢数据) 同步提交
recovery_time_target 0 60~300 openGauss 特有,备机回放延迟目标(秒)
enable_thread_pool off on(高并发) 线程池模式,显著降内存
max_threads_per_session 8 8~16 线程池下每会话线程数
log_min_duration_statement -1 1000(ms) 慢 SQL 阈值
log_statement none ddl 记录 DDL
password_encryption_type 2 2 密码算法
-- 查看参数
SHOW shared_buffers;
SELECT name, setting, unit, context FROM pg_settings WHERE name IN
  ('max_connections','shared_buffers','work_mem','max_process_memory','enable_thread_pool');

-- 会话级临时改
SET work_mem = '128MB';
SET statement_timeout = '30s';

max_process_memory 是 openGauss 的「总闸」,超过会直接 OOM kill。它必须大于 shared_buffers + cstore_buffers + max_connections × (work_mem × 每查询算子数)。这是 openGauss 最常见的 OOM 根因,调参时优先算这个。

7.3 向量化与并行

-- 并行度
SHOW query_dop;                  -- 0 = 自适应
SET query_dop = 4;

-- 向量化执行(默认开启,不建议关)
SHOW enable_vectorized_engine;

8. 用户、角色与权限

8.1 用户与角色

-- 建用户(密码需满足复杂度:≥8位,含大写/小写/数字/特殊字符中至少3类)
CREATE USER app WITH PASSWORD 'App@12345';

-- 建角色
CREATE ROLE read_only WITH LOGIN PASSWORD 'Ro@123456';

-- 用户即角色(openGauss 中 USER 是带 LOGIN 的 ROLE)
CREATE ROLE dba_role;
GRANT dba_role TO app;

-- 改密(普通用户改自己)
ALTER USER app IDENTIFIED BY 'New@12345' REPLACE 'App@12345';

-- 管理员改他人密码
ALTER USER app IDENTIFIED BY 'New@12345';

-- 锁定/解锁
ALTER USER app ACCOUNT LOCK;
ALTER USER app ACCOUNT UNLOCK;

-- 有效期
ALTER USER app VALID BEGIN '2026-01-01' VALID UNTIL '2027-01-01';

-- 查看
SELECT usename, usesysid, usecreatedb, usesuper, userepl, valuntil
FROM pg_user;

-- 删除(有对象时需先转移或 CASCADE)
DROP USER app;
DROP USER app CASCADE;

8.2 权限模型

-- 库级
GRANT CONNECT ON DATABASE app_db TO app;
GRANT CREATE ON DATABASE app_db TO app;
REVOKE CONNECT ON DATABASE app_db FROM PUBLIC;

-- Schema 级(openGauss 必做,默认 public 权限收紧)
GRANT USAGE ON SCHEMA public TO app;
GRANT CREATE ON SCHEMA public TO app;

-- 表级
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app;
GRANT SELECT ON app_db.public.orders TO read_only;

-- 序列
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app;

-- 函数
GRANT EXECUTE ON FUNCTION fn_calc(int) TO app;

-- 默认权限(新建对象自动授权,非常重要)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO read_only;

-- 查看权限
\dp app_db.public.orders
SELECT * FROM information_schema.table_privileges WHERE grantee = 'app';

8.3 三权分立

openGauss 支持安全管理员、审计管理员、系统管理员三权分立(等保要求):

-- 开启三权分立(需重启)
gs_guc set -N all -I all -c "enableSeparationOfDuty=on"

-- 创建三类管理员
CREATE USER sysadmin WITH SYSADMIN PASSWORD 'Sys@12345';
CREATE USER secadmin WITH CREATEROLE PASSWORD 'Sec@12345' AUDITADMIN;
CREATE USER auditor  WITH AUDITADMIN PASSWORD 'Aud@12345';
角色 权限
SYSADMIN 系统管理,不能审计、不能建用户
CREATEROLE 建用户/角色,不能操作数据
AUDITADMIN 审计日志查看与策略管理
MONADMIN 监控视图访问
OPRADMIN 运维操作(需配合 enable_thread_pool)
POLADMIN 行级访问控制策略

8.4 行级安全与脱敏

-- 行级访问控制(RLS)
CREATE ROW LEVEL SECURITY POLICY pol_orders ON orders
  USING (user_id = current_user_id());

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- 数据脱敏策略
CREATE MASKING POLICY mask_phone AS (maskall(phone))
  APPLY TO app;

-- 查看
SELECT * FROM gs_my_policies;

行级安全与脱敏是 openGauss 相对 PG 的强项,也是等保/密评项目里的常见要求。策略创建后必须 ENABLE ROW LEVEL SECURITY 才生效,漏这一步是最常见的「配了没用」。


9. 库表对象与存储引擎

9.1 建库建表

CREATE DATABASE app_db
  WITH ENCODING='UTF8'
       DBCOMPATIBILITY='A'
       TEMPLATE=template0
       CONNECTION LIMIT=500;

\c app_db

-- 行存表(默认 AStore)
CREATE TABLE orders (
  id          BIGSERIAL PRIMARY KEY,
  order_no    VARCHAR(32) NOT NULL UNIQUE,
  user_id     BIGINT NOT NULL,
  amount      NUMERIC(18,2) NOT NULL,
  status      SMALLINT DEFAULT 0,
  created_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- UStore 表(回滚段独立,适合高并发更新)
CREATE TABLE sessions (
  id BIGSERIAL PRIMARY KEY,
  data TEXT,
  updated_at TIMESTAMP DEFAULT now()
) WITH (STORAGE_TYPE=USTORE);

-- 列存表(分析场景)
CREATE TABLE sales_fact (
  sale_date DATE,
  region    VARCHAR(32),
  amount    NUMERIC(18,2)
) WITH (ORIENTATION=COLUMN);

-- 分区表
CREATE TABLE logs (
  id BIGSERIAL,
  log_time TIMESTAMP NOT NULL,
  msg TEXT
) PARTITION BY RANGE (log_time);

CREATE TABLE logs_p202611 PARTITION OF logs
  FOR VALUES FROM ('2026-11-01') TO ('2026-12-01');
存储引擎 特点 适用
AStore 追加写,回滚段在表空间,垃圾回收靠 VACUUM OLTP 为主,默认
UStore 原地更新,回滚段独立(undo),空间膨胀小 高频 UPDATE,长事务
列存(COLUMN) 列式压缩,向量化扫描快 OLAP、宽表聚合
MOT 全内存,无锁并发 极高性能点查(需单独配置)

AStore vs UStore 的选择:业务以 INSERT + 查询为主,用 AStore;业务有大量 UPDATE 且表很宽,用 UStore(避免 AStore 的「更新即新版本」导致膨胀)。UStore 在 3.0 后趋于稳定,但不支持部分特性(如逻辑解码的部分场景),选型前要核对。

9.2 索引

CREATE INDEX idx_orders_user ON orders(user_id);
CREATE INDEX idx_orders_user_time ON orders(user_id, created_at DESC);
CREATE UNIQUE INDEX uk_order_no ON orders(order_no);

-- 部分索引
CREATE INDEX idx_orders_pending ON orders(created_at) WHERE status = 0;

-- 表达式索引
CREATE INDEX idx_orders_month ON orders(EXTRACT(MONTH FROM created_at));

-- 并行建索引
SET query_dop = 4;
CREATE INDEX CONCURRENTLY idx_big ON big_table(col);   -- 不锁表(部分版本支持)

-- 查看索引使用情况
SELECT indexrelname, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes WHERE relname = 'orders' ORDER BY idx_scan;

-- 找无用索引(idx_scan = 0 且运行时间够长)
SELECT indexrelname, pg_size_pretty(pg_relation_size(indexrelid))
FROM pg_stat_user_indexes WHERE idx_scan = 0
ORDER BY pg_relation_size(indexrelid) DESC;

-- 删除
DROP INDEX idx_orders_month;

9.3 序列与自增

-- openGauss 支持 SERIAL / BIGSERIAL,也支持 Oracle 风格 SEQUENCE
CREATE SEQUENCE seq_order START 1 INCREMENT 1 CACHE 20;

SELECT nextval('seq_order');
SELECT currval('seq_order');

-- 查看序列当前值
SELECT last_value, is_called FROM seq_order;

-- 重置
ALTER SEQUENCE seq_order RESTART WITH 100000;

9.4 物化视图

CREATE MATERIALIZED VIEW mv_daily_sales AS
SELECT date_trunc('day', created_at) d, SUM(amount) total
FROM orders GROUP BY 1;

-- 刷新(会锁表,用 CONCURRENTLY 需有唯一索引)
REFRESH MATERIALIZED VIEW mv_daily_sales;
REFRESH MATERIALIZED VIEW CONCURRENTLY mv_daily_sales;

10. 备份与恢复

10.1 方案选型

方案 类型 速度 一致性 适用
gs_dump 逻辑,单库 中 快照一致 单库迁移、小库
gs_dumpall 逻辑,全实例 慢 一般 全实例迁移
gs_basebackup 物理,全量 快 强一致 备机搭建、全量备份
gs_probackup 物理,全量+增量 快 强一致 生产首选
文件系统快照 物理 极快 需停库或冻结 大库、有存储快照能力

10.2 逻辑备份

# 单库,纯文本
gs_dump -U omm -W 'xxx' -p 15400 -f /backup/app_db_20261105.sql app_db

# 单库,自定义格式(支持选择性恢复)
gs_dump -U omm -W 'xxx' -p 15400 -Fc -f /backup/app_db.dmp app_db

# 只导结构
gs_dump -U omm -W 'xxx' -p 15400 -s -f /backup/app_db_schema.sql app_db

# 只导数据
gs_dump -U omm -W 'xxx' -p 15400 -a -f /backup/app_db_data.sql app_db

# 只导某张表
gs_dump -U omm -W 'xxx' -p 15400 -t public.orders -f /backup/orders.sql app_db

# 并行导出(大库提速)
gs_dump -U omm -W 'xxx' -p 15400 -Fd -j 8 -f /backup/app_db_dir app_db

# 全实例
gs_dumpall -U omm -W 'xxx' -p 15400 -f /backup/all_20261105.sql
参数 说明
-Fp 纯文本 SQL(默认)
-Fc 自定义格式,压缩,支持 gs_restore -l 选择性恢复
-Fd 目录格式,必须配合 -j 并行
-Ft tar 格式
-j N 并行度,仅 -Fd 有效
-s / -a 只结构 / 只数据
-t 指定表
-n 指定 schema
# 恢复
gs_restore -U omm -W 'xxx' -p 15400 -d app_db_new /backup/app_db.dmp

# 先看备份里有什么
gs_restore -l /backup/app_db.dmp

# 只恢复某张表
gs_restore -U omm -W 'xxx' -p 15400 -d app_db_new -t orders /backup/app_db.dmp

# 恢复到已有库(先删再建,-c 会 DROP)
gs_restore -U omm -W 'xxx' -p 15400 -d app_db -c /backup/app_db.dmp

# 并行恢复
gs_restore -U omm -W 'xxx' -p 15400 -d app_db_new -j 8 /backup/app_db_dir

10.3 物理备份(gs_basebackup)

# 全量物理备份(需有复制权限)
gs_basebackup -D /backup/base_20261105 -h 10.0.0.11 -p 15400 -U omm -W 'xxx' -Fp -Xs -P -R

# 参数说明
#   -D  目标目录
#   -Fp 普通文件格式(-Ft 为 tar)
#   -Xs 流式传输 WAL
#   -P  显示进度
#   -R  自动生成 recovery.conf(用于搭备机)

10.4 gs_probackup(生产推荐)

# 1) 初始化备份目录
gs_probackup init -B /backup/probackup

# 2) 添加实例
gs_probackup add-instance -B /backup/probackup -D $PGDATA --instance=og1

# 3) 配置(可选,写入 pg_probackup.conf)
gs_probackup set-config -B /backup/probackup --instance=og1 \
  --pgdata=$PGDATA \
  --remote-proto=ssh --remote-host=10.0.0.11 --remote-user=omm

# 4) 全量备份
gs_probackup backup -B /backup/probackup --instance=og1 -b full \
  --stream -j 8 --compress

# 5) 增量备份
gs_probackup backup -B /backup/probackup --instance=og1 -b incremental \
  --stream -j 8 --compress

# 6) 查看备份列表
gs_probackup show -B /backup/probackup --instance=og1

# 7) 校验备份
gs_probackup validate -B /backup/probackup --instance=og1

# 8) 恢复(需先停库)
gs_ctl stop -D $PGDATA -m fast
gs_probackup restore -B /backup/probackup --instance=og1 -i <backup-id> -D $PGDATA

# 9) 恢复到时间点
gs_probackup restore -B /backup/probackup --instance=og1 -i <backup-id> \
  -D $PGDATA --recovery-target-time='2026-11-05 09:30:00'

# 10) 清理旧备份(保留 7 天)
gs_probackup delete -B /backup/probackup --instance=og1 --retention-redundancy=7

gs_probackup 的增量备份依赖 WAL 归档。如果 archive_mode=off,增量备份会失败或退化为全量。生产必须先把归档配好。

10.5 备份策略

对象 频率 保留 说明
全量物理 每天 1 次 7 天 gs_probackup -b full
增量物理 每 6 小时 3 天 依赖 WAL 归档
逻辑备份 每周 1 次 30 天 跨版本迁移兜底
WAL 归档 持续 7 天 PITR 基础

11. WAL、归档与 PITR

11.1 开启归档

# 1) 建归档目录
mkdir -p /archive/og
chown -R omm:dbgrp /archive/og

# 2) 配置参数(主库)
gs_guc set -N all -I all -c "archive_mode=on"
gs_guc set -N all -I all -c "archive_command='cp %p /archive/og/%f'"
gs_guc set -N all -I all -c "wal_level=hot_standby"

# 3) 重启生效
gs_om -t restart

# 4) 验证(手动切一个 WAL)
gsql -d postgres -p 15400 -c "SELECT pg_switch_xlog();"
ls -lt /archive/og | head

openGauss 仍然用 pg_switch_xlog() / pg_xlogfile_name() 这套旧命名(PG 10 之后已改为 pg_switch_wal)。写脚本时不要照抄 PG 文档。

11.2 WAL 状态查询

-- 当前 WAL 位点
SELECT pg_current_xlog_location();
SELECT pg_current_xlog_insert_location();

-- 备机接收/回放位点
SELECT pg_last_xlog_receive_location();
SELECT pg_last_xlog_replay_location();

-- 延迟(字节)
SELECT pg_xlog_location_diff(pg_current_xlog_location(), pg_last_xlog_replay_location()) AS lag_bytes;

-- WAL 文件列表
SELECT * FROM pg_ls_dir('pg_xlog') WHERE pg_ls_dir ~ '^[0-9A-F]{24}$' ORDER BY 1 DESC LIMIT 10;

-- 归档状态
SELECT archived_count, failed_count, last_archived_wal, last_failed_wal
FROM pg_stat_archiver;

11.3 PITR 完整流程

# 1) 确认有基础备份 + 连续归档
gs_probackup show -B /backup/probackup --instance=og1
ls /archive/og | wc -l

# 2) 停止数据库
gs_om -t stop

# 3) 清空数据目录(先备份原目录!)
mv $PGDATA $PGDATA.bak_$(date +%F)
mkdir -p $PGDATA && chown omm:dbgrp $PGDATA && chmod 700 $PGDATA

# 4) 恢复基础备份
gs_probackup restore -B /backup/probackup --instance=og1 -i <backup-id> -D $PGDATA

# 5) 配恢复目标
cat >> $PGDATA/postgresql.conf <<'EOF'
restore_command = 'cp /archive/og/%f %p'
recovery_target_time = '2026-11-05 09:30:00'
recovery_target_action = 'promote'
EOF

# 6) 创建恢复标记
touch $PGDATA/recovery.signal

# 7) 启动(会自动回放 WAL 到目标时间后升主)
gs_ctl start -D $PGDATA

# 8) 验证
gsql -d postgres -p 15400 -c "SELECT now(), pg_is_in_recovery();"

recovery_target_action 三个取值:pause(回放到目标点暂停,可检查后再 promote)、promote(直接升主)、shutdown(回放完关机)。生产建议 pause,确认数据无误再 gs_ctl notify -M primary。

11.4 归档失败处理

-- 查看失败的 WAL
SELECT last_failed_wal, last_failed_time FROM pg_stat_archiver;

-- 常见原因
--   归档目录满 → df -h
--   权限不对 → ls -ld /archive/og
--   archive_command 路径写错 → 手动执行一次验证
# 手动补归档(把 pg_xlog 里未归档的文件拷过去)
for f in $(ls $PGDATA/pg_xlog | grep -E '^[0-9A-F]{24}$'); do
  [ -f /archive/og/$f ] || cp $PGDATA/pg_xlog/$f /archive/og/
done

归档断了会导致 PITR 出现断档,必须尽快补上。补完后 pg_stat_archiver 的 failed_count 不会归零(历史累计),要看 last_failed_wal 是否还在推进。


12. 主备复制与 CM 集群管理

12.1 复制状态

-- 主库看备机
SELECT client_addr, state, sync_state,
       sent_location, write_location, flush_location, replay_location,
       pg_xlog_location_diff(pg_current_xlog_location(), replay_location) AS lag_bytes
FROM pg_stat_replication;

-- sync_state: async / potential / sync / quorum
# gs_ctl 看(更直观)
gs_ctl query -D $PGDATA

12.2 主备切换

# 计划内切换(原主变备,原备变主)
gs_om -t switch --instance og-node2
# 或
cm_ctl switchover -n 2 -D /usr/local/opengauss/data

# 故障切换(原主已挂,强制备机升主)
gs_om -t failover
# 或
gs_ctl failover -D $PGDATA

# 切换后确认
gs_om -t status --detail
gs_ctl query -D $PGDATA

switchover 与 failover 的区别:

  • switchover:原主还活着,先追平再切,不丢数据,可回切;
  • failover:原主已不可用,强制升主,可能丢最后一段 WAL,原主恢复后需要重建。 生产能 switchover 就不要 failover。

12.3 备机重建

备机 db_state 变成 Need repair 时,必须重建:

# 1) 停备机
gs_ctl stop -D $PGDATA -m fast

# 2) 全量重建(推荐)
gs_ctl build -D $PGDATA -b full

# 3) 增量重建(数据量大时更快,但要求 WAL 完整)
gs_ctl build -D $PGDATA -b incremental

# 4) CM 模式
cm_ctl build -n 2 -D /usr/local/opengauss/data -b full

# 5) 验证
gs_ctl query -D $PGDATA
-- 判断是否需要重建
-- db_state = Need repair  → 必须重建
-- 四个位点差距持续增大    → 先查网络/磁盘,不一定要重建

12.4 同步复制配置

# 单备同步(一主一备强一致)
gs_guc set -N all -I all -c "synchronous_standby_names='ANY 1(og-node2)'"
gs_guc set -N all -I all -c "synchronous_commit=on"

# 两备中任一同步(一主两备,容忍一个备机故障)
gs_guc set -N all -I all -c "synchronous_standby_names='ANY 1(og-node2,og-node3)'"

# 全同步(两备都确认,性能最差)
gs_guc set -N all -I all -c "synchronous_standby_names='FIRST 2(og-node2,og-node3)'"

gs_om -t restart
配置 RPO 写入延迟 可用性
synchronous_commit=off 可能丢秒级 最低 最高
ANY 1(...) 0(至少一个备机确认) 中 高
FIRST 2(...) 0 最高 低(备机全挂则主库不可写)

12.5 CM(Cluster Manager)

CM 是 openGauss 3.0 引入的高可用组件,负责自动故障检测与切换,替代早期的 gs_om 手工切换。

# 查看 CM 状态
cm_ctl query -Cv

# 输出关键字段
#   cluster_state    Normal / Degraded
#   node_state       Primary / Standby / Down
#   cm_state         Normal / Down

# 启动/停止
cm_ctl start
cm_ctl stop

# 单节点
cm_ctl start -n 1 -D /usr/local/opengauss/data

# 查看 CM 日志
tail -f /var/log/omm/cm/cm_agent/cm_agent.log
tail -f /var/log/omm/cm/cm_server/cm_server.log
CM 进程 作用
cm_agent 每节点一个,监控本机实例,上报状态
cm_server 集群级,仲裁与决策(必须奇数个)
cm_ctl 客户端命令行

CM 与 gs_om 不要混用。装了 CM 后用 cm_ctl,gs_om -t start/stop 会被 CM 干扰(停了又自动拉起)。只有 CM 挂了才临时用 gs_ctl 手工操作,修好 CM 后要 gs_om -t refreshconf 同步状态。


13. 日志体系

13.1 日志类型

日志 路径 内容
运行日志 /var/log/omm/pg_log/ 或 $PGDATA/pg_log/ 启动、错误、慢 SQL
WAL $PGDATA/pg_xlog/ 事务日志
CM 日志 /var/log/omm/cm/ 集群管理
审计日志 $GAUSSHOME/bin/ 或独立目录 需开启审计
OM 日志 /var/log/omm/omm/ 安装、启停操作
core dump corePath 指定目录 崩溃分析
# 实时跟踪
tail -f /var/log/omm/pg_log/postgresql-*.log

# 找错误
grep -E 'ERROR|FATAL|PANIC' postgresql-*.log | tail -100

# 按时间段
awk '/2026-11-05 09:2[0-9]/,/2026-11-05 09:3[0-9]/' postgresql-*.log

# 统计错误类型
grep -oE 'ERROR:.*' postgresql-*.log | sort | uniq -c | sort -rn | head -20

13.2 日志参数

gs_guc reload -N all -I all -c "log_min_duration_statement=1000"   # 慢 SQL 1s
gs_guc reload -N all -I all -c "log_statement='ddl'"                # 记录 DDL
gs_guc reload -N all -I all -c "log_checkpoints=on"
gs_guc reload -N all -I all -c "log_connections=on"
gs_guc reload -N all -I all -c "log_disconnections=on"
gs_guc reload -N all -I all -c "log_line_prefix='%m %u %d %p %r '"  # 时间/用户/库/pid/客户端
gs_guc reload -N all -I all -c "log_rotation_age=1d"
gs_guc reload -N all -I all -c "log_rotation_size=100MB"

13.3 审计

-- 查看审计开关
SHOW audit_enabled;
SHOW audit_directory;

-- 开启审计(需重启)
gs_guc set -N all -I all -c "audit_enabled=on"

-- 审计用户操作
CREATE AUDIT POLICY audit_ddl
  ACCESS CREATE, ALTER, DROP;

AUDIT POLICY audit_ddl TO app;

-- 查看审计日志(需审计管理员权限)
SELECT * FROM pg_query_audit('2026-11-05 00:00:00', '2026-11-05 23:59:59')
WHERE type = 'ddl' LIMIT 50;

-- 审计策略
SELECT * FROM pg_audit_policy;

14. 性能诊断

14.1 执行计划

-- 基本计划
EXPLAIN SELECT * FROM orders WHERE user_id = 1001;

-- 实际执行(含耗时、行数、内存)
EXPLAIN (ANALYZE, BUFFERS, VERBOSE)
SELECT * FROM orders WHERE user_id = 1001;

-- 只看代价
EXPLAIN (COSTS true) SELECT ...;

执行计划危险信号:

现象 含义 处置
Seq Scan + 大表 全表扫描 补索引
rows= 估算与实际差 10 倍 统计信息过期 ANALYZE
Nested Loop 且外层行数大 JOIN 方式选错 收集统计信息 / 改写
Sort Method: external merge 排序落盘 调大 work_mem
Buffers: shared read= 很大 缓存命中率低 调大 shared_buffers
HashAggregate 溢出 哈希表过大 调大 work_mem

14.2 dbe_perf 性能视图

openGauss 用 dbe_perf schema 替代 PG 的 pg_stat_statements:

-- TOP SQL(按总耗时)
SELECT * FROM dbe_perf.statement
ORDER BY total_elapse_time DESC LIMIT 20;

-- 关键字段
SELECT unique_query_id, substr(query,1,80) sql,
       n_calls, total_elapse_time/1000 total_ms,
       (total_elapse_time/n_calls)/1000 avg_ms,
       n_returned_rows, n_tuples_fetched,
       n_blocks_fetched, n_blocks_hit
FROM dbe_perf.statement
ORDER BY total_elapse_time DESC LIMIT 20;

-- 历史语句(按时间段)
SELECT * FROM dbe_perf.statement_history
WHERE start_time > now() - interval '1 hour'
ORDER BY db_time DESC LIMIT 20;

-- 等待事件
SELECT * FROM dbe_perf.wait_events ORDER BY counts DESC LIMIT 20;

-- 当前活跃会话(ASP)
SELECT * FROM dbe_perf.local_active_session
WHERE sample_time > now() - interval '10 minutes';

-- 实例级统计
SELECT * FROM dbe_perf.global_instance_time;
视图 用途
dbe_perf.statement 归一化 SQL 统计(类似 pg_stat_statements)
dbe_perf.statement_history 历史 SQL,含执行计划
dbe_perf.wait_events 等待事件汇总
dbe_perf.local_active_session 采样活跃会话(ASP)
dbe_perf.os_runtime OS 指标
dbe_perf.memory_node_detail 内存节点详情

14.3 WDR 报告

WDR(Workload Diagnosis Report)是 openGauss 的性能快照对比工具,相当于 Oracle 的 AWR:

-- 1) 创建快照
SELECT create_wdr_snapshot();

-- 2) 查看快照
SELECT * FROM snapshot.snapshot ORDER BY start_ts DESC LIMIT 10;

-- 3) 生成报告(两个快照 ID)
SELECT generate_wdr_report(1, 2, 'all', 'node1', 'node2');

-- 4) 报告会写到 $GAUSSHOME/bin 或指定目录
# 也可以用 gs_wdr 工具(部分版本)
gs_wdr_report --begin-snap-id 1 --end-snap-id 2 --report-type all

WDR 的前提:enable_wdr_snapshot=on,且已有至少两个快照。默认每小时自动生成一个快照,保留 8 天。

14.4 锁与阻塞

-- 当前锁等待
SELECT
  w.pid AS waiting_pid,
  w.usename AS waiting_user,
  w.query AS waiting_query,
  b.pid AS blocking_pid,
  b.usename AS blocking_user,
  b.query AS blocking_query
FROM pg_stat_activity w
JOIN pg_locks l1 ON w.pid = l1.pid AND NOT l1.granted
JOIN pg_locks l2 ON l1.locktype = l2.locktype
  AND l1.database IS NOT DISTINCT FROM l2.database
  AND l1.relation IS NOT DISTINCT FROM l2.relation
  AND l2.granted
JOIN pg_stat_activity b ON b.pid = l2.pid;

-- 锁明细
SELECT * FROM pg_locks WHERE NOT granted;

-- 长事务
SELECT pid, usename, state, now() - xact_start AS xact_age, query
FROM pg_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY xact_age DESC LIMIT 10;

-- 杀会话
SELECT pg_terminate_backend(pid);

14.5 内存诊断

-- 各模块内存(openGauss 特有)
SELECT * FROM pv_session_memory_detail ORDER BY usedsize DESC LIMIT 20;
SELECT * FROM pv_total_memory_detail;

-- 会话级内存
SELECT * FROM pv_session_memory ORDER BY usedsize DESC LIMIT 20;

-- 共享内存
SELECT * FROM pg_shared_memory_detail ORDER BY size DESC LIMIT 20;
# OS 层面
free -g
ps -eLf | grep gaussdb | wc -l     # 线程数
top -H -p $(pgrep -f gaussdb | head -1)   # 线程级 CPU

15. 空间、VACUUM 与膨胀

15.1 空间统计

-- 库级
SELECT datname, pg_size_pretty(pg_database_size(datname)) size
FROM pg_database ORDER BY pg_database_size(datname) DESC;

-- 表级 Top20
SELECT schemaname, relname,
       pg_size_pretty(pg_total_relation_size(relid)) total,
       pg_size_pretty(pg_relation_size(relid)) table_size,
       pg_size_pretty(pg_indexes_size(relid)) index_size
FROM pg_stat_user_tables
ORDER BY pg_total_relation_size(relid) DESC LIMIT 20;

-- 单表详细
SELECT pg_size_pretty(pg_total_relation_size('orders')) AS total,
       pg_size_pretty(pg_relation_size('orders')) AS heap,
       pg_size_pretty(pg_indexes_size('orders')) AS indexes;

15.2 VACUUM

-- 普通 VACUUM(不锁表,回收空间给后续复用)
VACUUM orders;
VACUUM VERBOSE orders;

-- VACUUM FULL(锁表,真正还给操作系统)
VACUUM FULL orders;

-- 并行 VACUUM
SET query_dop = 4;
VACUUM FULL orders;

-- 分析统计信息
ANALYZE orders;
ANALYZE VERBOSE;

-- 查看死元组比例
SELECT relname, n_live_tup, n_dead_tup,
       ROUND(n_dead_tup::numeric / GREATEST(n_live_tup,1) * 100, 2) dead_pct,
       last_vacuum, last_autovacuum
FROM pg_stat_user_tables
WHERE n_dead_tup > 10000
ORDER BY n_dead_tup DESC;
操作 锁 空间回收 适用
VACUUM 无(4 级) 标记可复用,不还给 OS 日常
VACUUM FULL 排他(8 级) 真正还给 OS 严重膨胀
VACUUM ANALYZE 无 同时更新统计 日常推荐

UStore 表不需要 VACUUM FULL(原地更新,无版本膨胀),只有 AStore 表需要。对 UStore 表执行 VACUUM FULL 会重建整表,纯属浪费。

15.3 膨胀排查

-- 估算膨胀率(需安装 pgstattuple 扩展或使用 openGauss 内置函数)
SELECT * FROM pg_stat_all_tables WHERE relname = 'orders';

-- 精确统计(openGauss 的 pgstattuple)
CREATE EXTENSION IF NOT EXISTS pgstattuple;
SELECT * FROM pgstattuple('orders');
-- 关注 dead_tuple_percent 与 free_percent
-- 表膨胀 Top10(用统计信息估算)
SELECT schemaname, relname, n_live_tup, n_dead_tup,
       pg_size_pretty(pg_total_relation_size(relid)) size,
       ROUND(n_dead_tup::numeric / GREATEST(n_live_tup + n_dead_tup,1) * 100, 1) dead_pct
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY pg_total_relation_size(relid) DESC LIMIT 10;

15.4 WAL 空间

-- WAL 目录大小
SELECT pg_size_pretty(SUM(size)) FROM pg_ls_dir('pg_xlog') AS f, pg_stat_file('pg_xlog/'||f) AS s;

-- 复制槽持有的 WAL(常见堆积原因)
SELECT slot_name, plugin, active,
       pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(), restart_lsn)) AS retained
FROM pg_replication_slots;

-- 删除废弃复制槽
SELECT pg_drop_replication_slot('slot_name');

WAL 暴涨三大原因:① 归档失败(archive_command 卡住);② 复制槽无人消费(逻辑复制断开);③ 备机长时间失联。三者都会让 pg_xlog 无限增长直到磁盘满。


16. 扩缩容、升级与迁移

16.1 扩容(加备机)

# 1) 新节点做预安装(root)
./gs_preinstall -U omm -G dbgrp -X cluster_config.xml

# 2) 扩容(omm)
gs_expansion -U omm -G dbgrp -X cluster_config.xml -h og-node3

# 3) 验证
gs_om -t status --detail

16.2 缩容(减备机)

# 1) 确认要删的节点是备机
gs_om -t status --detail

# 2) 删除
gs_dropnode -U omm -G dbgrp -h og-node3

# 3) 验证
gs_om -t status --detail

只能删备机。删主机前必须先 switchover 把主角色移走。

16.3 升级

# 1) 停止业务,做全量备份
gs_probackup backup -B /backup/probackup --instance=og1 -b full

# 2) 解压新版本
tar xzf openGauss-7.0.0-*-all.tar.gz

# 3) 升级(omm)
gs_upgradectl -t upgrade --new-package /opt/software/openGauss_New

# 4) 查看升级状态
gs_upgradectl -t show

# 5) 提交(确认无误后,不可回滚)
gs_upgradectl -t commit

# 6) 回滚(提交前可用)
gs_upgradectl -t rollback
阶段 说明
upgrade 替换二进制,旧版本保留在 $GAUSHHOME/../upgrade
commit 删除旧版本,不可逆
rollback 回退到旧二进制(仅在 commit 前)

升级窗口内不要执行 DDL。升级过程中元数据格式可能变化,DDL 会导致回滚失败。

16.4 从 PostgreSQL 迁移

差异点 PG openGauss 迁移处置
工具名 psql/pg_dump gsql/gs_dump 换工具
端口 5432 15400 改连接串
WAL 命名 pg_wal(10+) pg_xlog 改脚本
复制槽 支持 支持(部分版本) 核对版本
扩展 pg_stat_statements dbe_perf.statement 改监控 SQL
存储引擎 仅 heap AStore/UStore/列存 按场景选
兼容模式 无 DBCOMPATIBILITY 建库时定
# 迁移步骤(小库)
# 源库(PG)
pg_dump -h pg-host -U postgres -Fc app_db > app_db.dmp

# 目标库(openGauss)
createdb -p 15400 app_db
gs_restore -p 15400 -d app_db app_db.dmp

直接用 pg_dump 的备份给 gs_restore 大部分情况可用,但涉及扩展、GENERATED 列、IDENTITY 列时可能失败。生产迁移建议用华为的 gs_migration 或第三方的 MTK(Migration Toolkit)。


17. 高频故障速查

17.1 起不来

现象 排查
could not create shared memory ① kernel.shmmax/shmall 太小 → ② shared_buffers/max_process_memory 超物理内存
could not bind 端口被占 → ss -lntp | grep 15400
permission denied 数据目录属主不是 omm → chown -R omm:dbgrp $PGDATA
database system was not properly shut down 上次是 kill -9,正在崩溃恢复,等它跑完
FATAL: the database system is starting up 恢复中,看日志进度
no space left on device 磁盘满,清 WAL 或归档
# 启动失败第一时间看这三处
tail -200 /var/log/omm/pg_log/postgresql-*.log
ls -ld $PGDATA
df -h

17.2 连不上

现象 处置
Connection refused gs_ctl status -D $PGDATA → 进程是否在 → 端口 → 防火墙
no pg_hba.conf entry 加 pg_hba.conf 一行,gs_ctl reload
password authentication failed ① 密码错 → ② password_encryption_type 变了 → ③ 用户被锁
too many clients already 调大 max_connections,或检查连接池泄漏
remaining connection slots are reserved 保留连接被占,用 sysadmin 登录杀会话
-- 保留连接(openGauss 特有,给管理员留的)
SHOW reserved_connections;
-- 管理员用户可占用保留连接

17.3 主备不同步

# 看状态
gs_ctl query -D $PGDATA

# 判断
# db_state = Need repair        → 必须 build
# 位点差距持续增大              → 查网络/IO
# 备机 CPU 100%                 → 回放跟不上,看 recovery_time_target
原因 判断 处置
网络抖动 ping/丢包率 修网络,短暂延迟会自愈
备机 IO 慢 iostat -x 1 看 %util 换盘
主库大事务 pg_stat_activity 有长事务 拆批
备机回放慢 recovery_time_target 太小 调大或设 0(不限速)
WAL 被删 备机报 requested WAL segment has already been removed 必须全量 build

17.4 磁盘满

# 1) 找占用
du -sh $PGDATA/* | sort -rh | head -10
du -sh /var/log/omm/* | sort -rh | head -10

# 2) 常见大头
#   pg_xlog     WAL 堆积(归档失败/复制槽)
#   base        数据文件
#   pg_log      日志未轮转
#   corefile    崩溃转储

# 3) 应急清理(按安全性排序)
find /var/log/omm/pg_log -name "*.log" -mtime +7 -delete    # 安全
rm -f /archive/og/0000000100000000000000*                    # 危险,先确认已备份

绝对不要直接删 pg_xlog 里的文件。删了会导致崩溃恢复失败、备机要求全量重建。正确做法是修归档、删复制槽、或调 max_wal_size。

17.5 OOM

-- openGauss 的 OOM 多半是 max_process_memory 超限
SHOW max_process_memory;
SHOW shared_buffers;
SHOW max_connections;
SHOW work_mem;

-- 内存分布
SELECT * FROM pv_total_memory_detail;
SELECT * FROM pv_session_memory_detail ORDER BY usedsize DESC LIMIT 10;
# OS 层 OOM 记录
dmesg -T | grep -i "out of memory"
grep -i "oom" /var/log/messages
原因 处置
max_process_memory 太小 调到物理内存 60~70%
连接数 × work_mem 超限 降 max_connections 或 work_mem,开线程池
大查询排序/哈希 限 statement_timeout,优化 SQL
列存缓冲过大 降 cstore_buffers

18. 危险命令与避坑清单

# 命令 风险 防护
1 rm -rf $PGDATA 数据全丢 先 gs_basebackup 或 gs_probackup
2 kill -9 gaussdb 崩溃恢复,可能几十分钟 用 gs_ctl stop -m fast
3 gs_uninstall --delete-data 删集群+数据 确认集群名,生产禁用
4 直接删 pg_xlog 文件 备机全量重建、PITR 断档 修归档 / 删复制槽
5 VACUUM FULL 大表 排他锁,业务全停 用 pg_repack 或低峰执行
6 DROP DATABASE 不可恢复 先 gs_dump;限制权限
7 UPDATE/DELETE 无 WHERE 全表修改 事务内先 SELECT COUNT(*);\set ON_ERROR_STOP on
8 gs_guc set 改 max_process_memory 调小 实例起不来 算好余量,改前备份 postgresql.conf
9 CM 模式下 gs_om -t stop 停了又被拉起,状态不一致 用 cm_ctl stop
10 failover 代替 switchover 丢 WAL,原主需重建 能用 switchover 就别 failover

变更前五步

  1. 备份:gs_probackup backup -b full,记录 backup-id;
  2. 确认角色:gs_om -t status --detail,别在备机上做写操作;
  3. 确认 CM 状态:cm_ctl query -Cv,CM 异常时先修 CM;
  4. 备份配置:cp postgresql.conf postgresql.conf.bak.$(date +%F);
  5. 留痕:记录变更前后 pg_stat_replication 与 pg_stat_activity 快照。

19. 附录:一键巡检脚本

#!/usr/bin/env bash
# og_health_check.sh —— 一分钟巡检
# 用法:su - omm 后执行 ./og_health_check.sh
set -uo pipefail

export GAUSSHOME=${GAUSSHOME:-/usr/local/opengauss}
export PGDATA=${PGDATA:-/usr/local/opengauss/data}
PORT=${PORT:-15400}

Q() { gsql -d postgres -p "$PORT" -A -F $'\t' -t -c "$1" 2>/dev/null; }

echo "==================== openGauss 巡检 $(date '+%F %T') ===================="

echo -e "\n--- 1. 版本 ---"
Q "SELECT version();"

echo -e "\n--- 2. 集群状态 ---"
gs_om -t status --detail 2>/dev/null | sed -n '1,25p'

echo -e "\n--- 3. 实例角色与复制延迟 ---"
Q "SELECT client_addr, state, sync_state,
          pg_xlog_location_diff(pg_current_xlog_location(), replay_location) AS lag_bytes
   FROM pg_stat_replication;"

echo -e "\n--- 4. 连接数 ---"
Q "SELECT 'total=' || COUNT(*) FROM pg_stat_activity;
   SELECT 'active=' || COUNT(*) FROM pg_stat_activity WHERE state = 'active';"

echo -e "\n--- 5. 长事务(>5min)---"
Q "SELECT pid, usename, ROUND(EXTRACT(EPOCH FROM (now()-xact_start))) AS sec,
          LEFT(query,80)
   FROM pg_stat_activity
   WHERE xact_start IS NOT NULL AND now()-xact_start > interval '5 min'
   ORDER BY sec DESC LIMIT 10;"

echo -e "\n--- 6. 慢 SQL TOP5 ---"
Q "SELECT ROUND(total_elapse_time/1000,2) AS total_ms,
          n_calls, LEFT(query,80)
   FROM dbe_perf.statement
   ORDER BY total_elapse_time DESC LIMIT 5;"

echo -e "\n--- 7. 死元组比例(>20% 关注)---"
Q "SELECT relname, n_live_tup, n_dead_tup,
          ROUND(n_dead_tup::numeric/GREATEST(n_live_tup,1)*100,1) AS dead_pct
   FROM pg_stat_user_tables
   WHERE n_dead_tup > 10000 ORDER BY dead_pct DESC LIMIT 10;"

echo -e "\n--- 8. 归档状态 ---"
Q "SELECT archived_count, failed_count, last_archived_wal, last_failed_wal
   FROM pg_stat_archiver;"

echo -e "\n--- 9. 复制槽持有 WAL ---"
Q "SELECT slot_name, active,
          pg_size_pretty(pg_xlog_location_diff(pg_current_xlog_location(), restart_lsn)) AS retained
   FROM pg_replication_slots;"

echo -e "\n--- 10. 磁盘水位 ---"
df -h "$PGDATA" /archive 2>/dev/null | awk 'NR==1 || /[0-9]%/{print "  "$0}'

echo -e "\n--- 11. WAL 目录大小 ---"
du -sh "$PGDATA/pg_xlog" 2>/dev/null | awk '{print "  "$0}'

echo -e "\n--- 12. 日志 ERROR 计数(近 500 行)---"
for f in /var/log/omm/pg_log/postgresql-*.log; do
  [ -f "$f" ] && printf "  %-60s %s\n" "$f" "$(tail -500 "$f" | grep -c 'ERROR')"
done

echo -e "\n==================== 巡检结束 ===================="

速查表

需求 命令
集群状态 gs_om -t status --detail
CM 状态 cm_ctl query -Cv
单实例状态 gs_ctl query -D $PGDATA
启停 gs_om -t start/stop 或 cm_ctl start/stop
切主 gs_om -t switch --instance <node>
备机重建 gs_ctl build -D $PGDATA -b full
改参数 gs_guc reload -N all -I all -c "k=v"
逻辑备份 gs_dump -Fc -f out.dmp db
物理备份 gs_probackup backup -b full
慢 SQL dbe_perf.statement
WDR generate_wdr_report(1,2,'all')
扩容 gs_expansion -h <new-node>
升级 gs_upgradectl -t upgrade

最后一句:openGauss 的坑集中在三处——端口不是 5432、WAL 还叫 pg_xlog、gs_om/cm_ctl/gs_ctl 三层别混用。把这三条记住,剩下的都是标准关系库运维。