人大金仓 KingbaseES 常用运维指令手册
人大金仓 KingbaseES 常用运维指令手册
适用版本:KingbaseES V9(V9R1 / V9R2,最新 V009R002C016) 约定:
#root,$kingbase 用户,test=#ksql 提示符,<xxx>为占位符。 差异标注:正文用> **版本差异**引用块标注跨版本不一致之处。 更新时间:2026-11
目录
- 版本与支持周期
- 架构、目录与命名规则
- 下载与安装
- 初始化与兼容模式
- 服务启停
- ksql 客户端
- 配置文件与参数
- 用户、角色与权限
- 库表对象与多模能力
- 备份与恢复
- WAL、归档与 PITR
- 主备复制与读写分离集群
- KES RAC 共享存储集群
- 日志与审计
- 性能诊断
- VACUUM、事务号与膨胀
- 空间与容量管理
- 升级与迁移
- 高频故障速查
- 危险命令与避坑清单
- 附录:一键巡检脚本
1. 版本与支持周期
1.1 版本体系
KingbaseES 的完整版本号是 V009R002C016,读作 V9R2C16:
| 段 | 含义 |
|---|---|
V009 |
大版本(V9) |
R002 |
发行版(Release 2) |
C016 |
补丁号 |
| 版本 | 发布日期 | 说明 |
|---|---|---|
| V009R002C010 | 2025-03-31 | — |
| V009R002C012 | 2025-07-18 | — |
| V009R002C013 | 2025-09-10 | — |
| V009R002C014 | 2026-03-16 | — |
| V009R002C016 | 2026-08-28 | 当前最新 |
网上有资料写 V9R2C16 发布于 2026-09-08,官方文档中心的版本汇总页写的是 2026-08-28。以文档中心为准,媒体稿常有转载延迟。
1.2 V9 的三个关键变化
V9 不是 V8 的简单升级,有三件事直接影响运维:
① 融合多模(V9 最大架构变化)
V9 在同一个内核里支持关系、文档、图、时序、向量五类数据模型,统一存储、联合索引、跨模查询。这不是外挂插件,是内核层集成。运维含义:一套实例可能同时承载多种负载,容量规划和慢 SQL 分析不能再按「纯 OLTP」的思路做。
② 事务号从 32 位扩到 64 位(V9R2C016)
这是最容易被低估、但对长期运行最关键的一条。
32 位事务号上限 ≈ 42.9 亿
高并发系统每天 500 万事务 → 约 2.4 年耗尽
耗尽前必须做 freeze,跟不上就性能陡降甚至停写
V9R2C016 把事务 ID 扩到 64 位,等于拆掉了这颗定时炸弹。同时把两项 autovacuum 参数的默认值提升了 50 倍,对长事务的容忍度大幅放宽。
这条对存量系统的意义:V8 时代那些「跑了三年突然变慢」「freeze 追不上」的疑难问题,在 V9 上从根上消失了。但升级到 V9R2C016 之后,不能再回退到 V8(事务号格式变了),升级前必须做完整备份。
③ 单机在线转读写分离集群(V9R2C016)
过去信创一期先上单机、业务涨了扛不住,只能停机做架构迁移。V9R2C016 支持不停机把单机平滑转成读写分离集群,还支持坏块修复。这对已经上线的项目价值很大。
1.3 版本识别
# 二进制版本
ksql --version
kingbase --version
sys_ctl --version
-- 数据库内版本
SELECT version();
-- 详细版本号
SHOW server_version;
SHOW server_version_num;
-- 兼容模式
SHOW database_mode;
SELECT * FROM sys_settings WHERE name = 'database_mode';
# 集群版本与补丁
sys_ctl -V
1.4 五种兼容模式
KES 可以在初始化时指定兼容形态,之后不能改:
| 模式 | 兼容 | 典型场景 |
|---|---|---|
oracle |
Oracle | 核心交易系统替换 Oracle |
mysql |
MySQL | 互联网化业务替换 MySQL |
sqlserver |
SQL Server | 特定行业系统 |
db2 |
DB2 | 大型机迁移 |
pg |
PostgreSQL | 新建系统、PG 原生应用 |
-- 查看
SHOW database_mode;
-- 注意:不能 ALTER,只能重新 initdb
兼容模式是 initdb 时定死的,和 openGauss 的
DBCOMPATIBILITY、达梦的COMPATIBLE_MODE(可改但需重启)不同——KES 的database_mode完全不可变更。选错只能重建库。这是金仓迁移项目里最贵的一个错误。
2. 架构、目录与命名规则
2.1 命名规则:sys_ 前缀
金仓基于 PostgreSQL,但把几乎所有 pg_ 前缀改成了 sys_。这是运维时最大的心智切换:
| PostgreSQL | KingbaseES |
|---|---|
psql |
ksql |
pg_ctl |
sys_ctl |
pg_dump |
sys_dump |
pg_dumpall |
sys_dumpall |
pg_restore |
sys_restore |
pg_basebackup |
sys_basebackup |
pg_waldump |
sys_waldump |
pg_wal/ |
sys_wal/ |
pg_stat_activity |
sys_stat_activity |
pg_settings |
sys_settings |
pg_locks |
sys_locks |
pg_database |
sys_database |
pg_tables |
sys_tables |
pg_current_wal_lsn() |
sys_current_wal_lsn() |
pg_switch_wal() |
sys_switch_wal() |
pg_stat_replication |
sys_stat_replication |
但也有例外:
pg_catalog这个 schema 名保留未改,部分系统函数(如pg_sleep、pg_terminate_backend)在部分版本仍保留pg_前缀。写脚本时先用\df或\d确认,不要盲目全局替换。
2.2 目录结构
| 路径 | 内容 |
|---|---|
/opt/Kingbase/ES/V9($KINGBASE_HOME) |
安装根目录 |
$KINGBASE_HOME/Server/bin |
ksql、sys_ctl、sys_dump、initdb、sys_rman |
$KINGBASE_HOME/Server/lib |
动态库、扩展 |
$KINGBASE_HOME/Server/share |
共享文件、时区、字符集 |
/opt/Kingbase/ES/V9/data($KINGBASE_DATA) |
数据目录 |
$KINGBASE_DATA/kingbase.conf |
主配置 |
$KINGBASE_DATA/sys_hba.conf |
客户端认证 |
$KINGBASE_DATA/sys_wal/ |
WAL 日志 |
$KINGBASE_HOME/Server/log 或 $KINGBASE_DATA/sys_log |
运行日志 |
/opt/Kingbase/ES/V9/ClientTools |
客户端工具(可单独安装) |
# 环境变量(kingbase 用户)
export KINGBASE_HOME=/opt/Kingbase/ES/V9
export KINGBASE_DATA=/opt/Kingbase/ES/V9/data
export PATH=$KINGBASE_HOME/Server/bin:$PATH
export LD_LIBRARY_PATH=$KINGBASE_HOME/Server/lib:$LD_LIBRARY_PATH
2.3 默认端口与账号
| 项 | 默认值 | 说明 |
|---|---|---|
| 端口 | 54321 | 不是 PG 的 5432,也不是 openGauss 的 15400 |
| 超级用户 | system |
初始化时创建 |
| 默认数据库 | test |
— |
| 三权分立账号 | sao / sso / audo |
系统管理员 / 安全管理员 / 审计管理员 |
54321 是金仓最显著的身份标识。看到一个 54321 端口,基本可以断定是 KingbaseES。这也意味着同一台机器上跑 PG(5432)、openGauss(15400)、KES(54321)三者不冲突。
3. 下载与安装
3.1 官方入口
| 用途 | 地址 |
|---|---|
| 官网 | https://www.kingbase.com.cn/ |
| 下载中心 | https://www.kingbase.com.cn/xzzx/ |
| 文档中心 | https://docs.kingbase.com.cn/ |
| 技术社区 | https://bbs.kingbase.com.cn/ |
| 试用授权 | 官网申请,开发版 365 天免费 |
金仓提供开发版 365 天免费试用授权,是验证 Oracle 兼容性的零成本入口。下载需要注册企业信息。
3.2 环境准备
# 1) 创建用户(不建议用 root 跑数据库)
groupadd kingbase
useradd -g kingbase -m -d /home/kingbase -s /bin/bash kingbase
echo 'Kingbase@123' | passwd --stdin kingbase
# 2) 目录
mkdir -p /opt/Kingbase/ES/V9
chown -R kingbase:kingbase /opt/Kingbase
chmod 755 /opt/Kingbase
# 3) 资源限制
cat >> /etc/security/limits.conf <<'EOF'
kingbase soft nofile 65536
kingbase hard nofile 65536
kingbase soft nproc 65536
kingbase hard nproc 65536
kingbase soft stack unlimited
kingbase hard stack unlimited
EOF
# 4) 内核参数
cat >> /etc/sysctl.conf <<'EOF'
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
kernel.sem = 50100 64128000 50100 1280
fs.file-max = 6815744
vm.swappiness = 10
vm.overcommit_memory = 2
vm.overcommit_ratio = 90
net.core.somaxconn = 4096
EOF
sysctl -p
# 5) 关闭 SELinux / 防火墙
setenforce 0
systemctl stop firewalld
# 6) 时间同步
systemctl enable --now chronyd
3.3 安装
# 挂载 ISO
mount -o loop KingbaseES_V009R002C016_Lin64_install.iso /mnt/kb
# 控制台安装(无图形界面)
su - kingbase
cd /mnt/kb
./setup.sh -i console
# 或用安装配置文件静默安装
./setup.sh -i silent -f /tmp/install.ini
# /tmp/install.ini 关键项
INSTALL_PATH=/opt/Kingbase/ES/V9
USERNAME=kingbase
COMPONENT=server,client
LICENSE_PATH=/mnt/kb/license.dat
# 图形化安装(有桌面时)
./setup.sh -i gui
# 安装后验证
ls -l $KINGBASE_HOME/Server/bin/ksql
$KINGBASE_HOME/Server/bin/ksql --version
3.4 License
# 授权文件位置
ls -l $KINGBASE_HOME/Server/license.dat
-- 查看授权
SELECT * FROM sys_license;
-- 关注:授权类型(单机/集群)、有效期、CPU 核数限制
V9 的集群能力(读写分离、KES RAC)需要对应授权。用单机 License 配 RAC 会在启动时报「超出授权范围」,且日志信息不直观,容易误判为配置错误。
4. 初始化与兼容模式
4.1 initdb
# 基础初始化
su - kingbase
initdb -D $KINGBASE_DATA -U system -W -E UTF8 --locale=C
# 指定兼容模式(关键)
initdb -D $KINGBASE_DATA -U system -W -E UTF8 --locale=C -m oracle
# oracle 模式 + 大小写不敏感 + 兼容 MySQL 的部分函数
initdb -D $KINGBASE_DATA -U system -W -E UTF8 --locale=C \
-m oracle \
--case-insensitive
| 参数 | 说明 |
|---|---|
-D |
数据目录 |
-U |
超级用户名,默认 system |
-W |
初始化时提示输入密码 |
-E |
编码,生产固定 UTF8 |
--locale |
区域设置,C 最稳定 |
-m |
兼容模式:oracle / mysql / sqlserver / db2 / pg |
--case-insensitive |
大小写不敏感(Oracle 迁移常用) |
--data-checksums |
开启数据页校验(强烈建议) |
initdb --help在不同补丁版本上参数名可能略有差异(有的版本是--db-mode)。以现场initdb --help为准,不要照抄博客。
4.2 初始化后的关键配置
# 1) 监听地址
sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" $KINGBASE_DATA/kingbase.conf
sed -i "s/#port = 54321/port = 54321/" $KINGBASE_DATA/kingbase.conf
# 2) 认证(允许网段)
cat >> $KINGBASE_DATA/sys_hba.conf <<'EOF'
host all all 10.0.0.0/24 scram-sha-256
host all all 0.0.0.0/0 scram-sha-256
EOF
# 3) 启动
sys_ctl start -D $KINGBASE_DATA -l $KINGBASE_DATA/sys_log/startup.log
-- 4) 验证
SELECT version();
SHOW database_mode;
SHOW port;
4.3 注册系统服务
# 用 root 注册
/opt/Kingbase/ES/V9/install/script/root.sh
# 或
$KINGBASE_HOME/Server/bin/sys_ctl register -N kingbase -D $KINGBASE_DATA
systemctl start kingbase
systemctl enable kingbase
systemctl status kingbase
5. 服务启停
5.1 sys_ctl
# 启动
sys_ctl start -D $KINGBASE_DATA
sys_ctl start -D $KINGBASE_DATA -l /opt/Kingbase/ES/V9/data/sys_log/start.log
# 停止(smart / fast / immediate)
sys_ctl stop -D $KINGBASE_DATA -m fast
# 重启
sys_ctl restart -D $KINGBASE_DATA -m fast
# 状态
sys_ctl status -D $KINGBASE_DATA
# 重载配置(不重启)
sys_ctl reload -D $KINGBASE_DATA
# 提升为主库(备库用)
sys_ctl promote -D $KINGBASE_DATA
# 注册/注销服务
sys_ctl register -N kingbase -D $KINGBASE_DATA
sys_ctl unregister -N kingbase
| 停止模式 | 行为 | 适用 |
|---|---|---|
smart |
等所有连接断开(可能永远停不下来) | 不推荐 |
fast |
断开连接、回滚未提交事务、写检查点 | 推荐 |
immediate |
立即退出,重启需崩溃恢复 | 最后手段 |
不要
kill -9 kingbase。会导致共享内存未释放、需要崩溃恢复。如果已经kill -9,重启前确认没有残留的kingbase进程和共享内存段。
5.2 集群启停脚本
# 读写分离集群的启停脚本(在 Server/bin 下)
./sys_monitor.sh start
./sys_monitor.sh stop
./sys_monitor.sh status
./sys_monitor.sh restart
5.3 正确的停机顺序
# 单机
sys_ctl stop -D $KINGBASE_DATA -m fast
# 读写分离集群:先停备机,再停主机
# 主机
sys_ctl stop -D $KINGBASE_DATA -m fast
# 备机
sys_ctl stop -D $KINGBASE_DATA -m fast
# KES RAC:按集群工具指引停,不要单节点直接 stop
6. ksql 客户端
6.1 连接
# 本机
ksql -U system -d test -p 54321
# 远程
ksql -h 10.0.0.11 -p 54321 -U system -d test -W
# 执行单条
ksql -h 10.0.0.11 -p 54321 -U system -d test -c "SELECT version();"
# 执行文件
ksql -h 10.0.0.11 -p 54321 -U system -d test -f /tmp/init.sql
# 无对齐输出(脚本处理)
ksql -h 10.0.0.11 -p 54321 -U system -d test -A -F $'\t' -t -c "SELECT * FROM t1"
6.2 常用元命令
\l -- 列出数据库
\l+ -- 带大小
\c test -- 切换数据库
\dn -- 列出 schema
\dn+ -- 带权限
\dt -- 列出表
\dt+ -- 带大小
\d+ orders -- 表结构详情
\di -- 索引
\dv -- 视图
\dm -- 物化视图
\df -- 函数
\du -- 用户/角色
\dp -- 权限
\x -- 行转列
\timing on -- 计时
\encoding -- 编码
\pset pager off -- 关分页
\o /tmp/out.txt -- 输出重定向
\i /tmp/a.sql -- 执行文件
\e -- 打开编辑器
\q -- 退出
6.3 会话管理
-- 当前连接
SELECT datname, usename, client_addr, state,
now() - state_change AS duration, left(query, 80)
FROM sys_stat_activity
WHERE state <> 'idle'
ORDER BY duration DESC;
-- 按用户汇总
SELECT usename, COUNT(*) FROM sys_stat_activity GROUP BY usename ORDER BY 2 DESC;
-- 最大连接数
SHOW max_connections;
-- 断开会话
SELECT sys_terminate_backend(pid);
-- 批量断开空闲超过 1 小时的连接
SELECT sys_terminate_backend(pid) FROM sys_stat_activity
WHERE state = 'idle' AND state_change < now() - interval '1 hour';
部分版本的函数仍叫
pg_terminate_backend。如果sys_terminate_backend报「函数不存在」,试pg_terminate_backend。
7. 配置文件与参数
7.1 修改方式
# 方式一:直接改配置 + reload
vi $KINGBASE_DATA/kingbase.conf
sys_ctl reload -D $KINGBASE_DATA
# 方式二:SQL 方式(部分参数支持)
-- 全局(写配置文件)
ALTER SYSTEM SET shared_buffers = '4GB';
SELECT sys_reload_conf();
-- 会话级
SET work_mem = '64MB';
SET statement_timeout = '30s';
-- 数据库级
ALTER DATABASE test SET work_mem = '32MB';
-- 用户级
ALTER ROLE app SET statement_timeout = '10s';
| 方式 | 生效范围 | 持久化 |
|---|---|---|
ALTER SYSTEM |
全局 | 写入 kingbase.conf |
ALTER DATABASE |
指定库 | 写入 sys_db 目录 |
ALTER ROLE |
指定用户 | 写入 sys_authid |
SET |
当前会话 | 否 |
7.2 关键参数
| 参数 | 默认 | 建议 | 说明 |
|---|---|---|---|
max_connections |
100 | 1000~3000 | 每连接约 5~10 MB |
shared_buffers |
128MB | 物理内存 25% | 共享缓冲 |
work_mem |
4MB | 16~64MB | 单算子内存 |
maintenance_work_mem |
64MB | 512MB~2GB | VACUUM/建索引 |
effective_cache_size |
4GB | 物理内存 50%~75% | 优化器估算用 |
wal_level |
replica | replica / logical |
WAL 级别 |
max_wal_size |
1GB | 4~16GB | 检查点间隔 |
checkpoint_timeout |
5min | 15~30min | 检查点周期 |
archive_mode |
off | on | 归档开关 |
synchronous_commit |
on | on | 同步提交 |
synchronous_standby_names |
'' | ANY 1(standby1) |
同步备机 |
log_min_duration_statement |
-1 | 1000 | 慢 SQL 阈值(ms) |
log_statement |
none | ddl |
记录 DDL |
autovacuum |
on | on | 绝不能关 |
autovacuum_naptime |
1min | 30s | 检查间隔 |
autovacuum_max_workers |
3 | 4~8 | 并发 worker |
autovacuum_freeze_max_age |
2 亿 | 按版本 | 强制 freeze 阈值 |
password_encryption |
scram-sha-256 | scram-sha-256 | 密码算法 |
V9R2C016 把两项 autovacuum 参数默认值提升了 50 倍。升级后如果沿用旧的
kingbase.conf(里面显式写了旧值),这些新默认值不会生效,需要手工核对。这是升级时容易漏的一项。
-- 查看参数
SHOW shared_buffers;
SELECT name, setting, unit, context FROM sys_settings
WHERE name IN ('max_connections','shared_buffers','work_mem','autovacuum_freeze_max_age');
7.3 参数生效级别
| 级别 | 是否需要重启 |
|---|---|
postmaster |
需要重启 |
sighup |
sys_ctl reload |
user |
新会话生效 |
superuser |
会话内 SET |
-- 查看某个参数的生效级别
SELECT name, context FROM sys_settings WHERE name = 'shared_buffers';
-- postmaster = 需重启;sighup = reload;user = 会话
8. 用户、角色与权限
8.1 用户
-- 建用户
CREATE USER app WITH PASSWORD 'App@12345';
-- 带属性
CREATE USER app WITH PASSWORD 'App@12345'
CREATEDB
VALID UNTIL '2027-12-31'
CONNECTION LIMIT 200;
-- 改密
ALTER USER app WITH PASSWORD 'New@12345';
-- 锁定/解锁
ALTER USER app ACCOUNT LOCK;
ALTER USER app ACCOUNT UNLOCK;
-- 有效期
ALTER USER app VALID UNTIL '2027-01-01';
-- 查看
SELECT usename, usesysid, usecreatedb, usesuper, valuntil FROM sys_user;
-- 删除
DROP USER app;
密码复杂度由
password_policy相关参数控制,等保场景通常要求 8 位以上、含 3 类字符、90 天更换。建用户时密码不合规会直接报错,且错误信息会明确说「不满足口令策略」。
8.2 角色与权限
-- 建角色
CREATE ROLE read_only;
GRANT CONNECT ON DATABASE test TO read_only;
GRANT USAGE ON SCHEMA public TO read_only;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only;
-- 默认权限(新建表自动授权)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO read_only;
-- 角色给用户
GRANT read_only TO app;
-- 表级
GRANT SELECT, INSERT, UPDATE, DELETE ON orders TO app;
GRANT ALL PRIVILEGES ON orders TO dba_user;
-- 序列
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app;
-- 查看
\dp orders
SELECT * FROM information_schema.table_privileges WHERE grantee = 'app';
-- 回收
REVOKE DELETE ON orders FROM app;
8.3 三权分立
KES 支持 sao(系统管理员)、sso(安全管理员)、audo(审计管理员)三权分立,满足等保三级要求。
-- 查看三权分立状态
SHOW separation_of_duty;
-- 开启(需重启)
ALTER SYSTEM SET separation_of_duty = on;
| 账号 | 职责 | 限制 |
|---|---|---|
sao |
系统管理(建库、备份、参数) | 不能管用户、不能看审计 |
sso |
安全管理员(建用户、授权、口令策略) | 不能操作数据 |
audo |
审计管理员(审计策略、日志) | 不能改数据 |
开启三权分立后,
system超级用户的权限会被拆分,日常运维账号需要重新规划。这是合规项目的必选项,但会显著改变运维流程,实施前必须和客户确认。
8.4 强制访问控制与脱敏
-- 行级安全(RLS)
CREATE POLICY pol_orders ON orders
USING (user_id = current_user_id());
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
-- 数据脱敏(需安装扩展)
CREATE EXTENSION IF NOT EXISTS sys_anon;
-- 透明加密(TDE,需授权)
-- 由 kingbase.conf 的 tde_* 参数控制,密钥由外部 KMS 管理
9. 库表对象与多模能力
9.1 建库建表
CREATE DATABASE app_db WITH ENCODING='UTF8' TEMPLATE=template0 CONNECTION LIMIT=500;
\c app_db
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 now()
);
-- 索引
CREATE INDEX idx_orders_user ON orders(user_id);
CREATE INDEX idx_orders_user_time ON orders(user_id, created_at DESC);
CREATE INDEX idx_orders_pending ON orders(created_at) WHERE status = 0;
-- 分区表(声明式)
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');
-- 查看分区
\d+ logs
SELECT * FROM sys_partitioned_table WHERE partrelid = 'logs'::regclass;
9.2 多模能力(V9)
V9 的融合多模是它相对 V8 最大的卖点。运维上需要知道的是:不同模型的数据在同一个实例里,共享同一套备份、权限、监控。
| 模型 | 使用方式 | 运维关注 |
|---|---|---|
| 关系 | 标准 SQL 表 | 常规 |
| 文档 | JSONB 类型 + GIN 索引 |
JSON 字段膨胀、索引体积 |
| 图 | 图对象(V9 新增) | 图查询的路径规划,内存占用高 |
| 时序 | 时序表(V9 新增) | 按时间分区,压缩率高 |
| 向量 | 向量类型 + 相似度检索 | 索引构建耗时,内存占用大 |
-- 文档模型(JSONB,PG 系通用)
CREATE TABLE docs (
id BIGSERIAL PRIMARY KEY,
payload JSONB
);
CREATE INDEX idx_docs_gin ON docs USING gin(payload);
SELECT payload->>'name' FROM docs WHERE payload @> '{"type":"order"}';
图、时序、向量的具体 DDL 语法在 V9 不同补丁间仍在演进,且官方文档更新滞后于版本发布。生产使用前请以现场版本的
\h帮助和对应版本文档为准,不要照搬博客示例。
9.3 统计信息
-- 收集
ANALYZE orders;
ANALYZE VERBOSE orders;
-- 查看
SELECT relname, n_live_tup, n_dead_tup, last_analyze, last_autoanalyze
FROM sys_stat_user_tables WHERE relname = 'orders';
-- 查看列统计
SELECT * FROM sys_stats WHERE tablename = 'orders';
10. 备份与恢复
10.1 方案选型
| 方案 | 类型 | 速度 | 一致性 | 适用 |
|---|---|---|---|---|
sys_dump |
逻辑,单库 | 中 | 快照一致 | 单库迁移、小库 |
sys_dumpall |
逻辑,全实例 | 慢 | 一般 | 全实例迁移 |
sys_basebackup |
物理,全量 | 快 | 强一致 | 搭备机、全量备份 |
sys_rman |
物理,全量+增量 | 快 | 强一致 | 生产首选 |
| 存储快照 | 物理 | 极快 | 需冻结 | 有存储能力时 |
10.2 逻辑备份
# 单库,纯文本
sys_dump -U system -p 54321 -f /backup/app_db_20261105.sql app_db
# 自定义格式(推荐,支持选择性恢复)
sys_dump -U system -p 54321 -Fc -f /backup/app_db.dmp app_db
# 只导结构
sys_dump -U system -p 54321 -s -f /backup/schema.sql app_db
# 只导数据
sys_dump -U system -p 54321 -a -f /backup/data.sql app_db
# 只导某表
sys_dump -U system -p 54321 -t public.orders -f /backup/orders.sql app_db
# 并行导出(目录格式)
sys_dump -U system -p 54321 -Fd -j 8 -f /backup/app_db_dir app_db
# 全实例(含角色、表空间)
sys_dumpall -U system -p 54321 -f /backup/all_20261105.sql
# 只导角色
sys_dumpall -U system -p 54321 -r -f /backup/roles.sql
| 参数 | 说明 |
|---|---|
-Fp |
纯文本(默认) |
-Fc |
自定义格式,压缩,支持 sys_restore -l |
-Fd |
目录格式,必须配 -j |
-Ft |
tar 格式 |
-j N |
并行度,仅 -Fd |
-s / -a |
只结构 / 只数据 |
-t / -n |
指定表 / schema |
-Z N |
压缩级别 0~9 |
# 恢复
sys_restore -U system -p 54321 -d app_db_new /backup/app_db.dmp
# 先看备份内容
sys_restore -l /backup/app_db.dmp
# 只恢复某表
sys_restore -U system -p 54321 -d app_db_new -t orders /backup/app_db.dmp
# 恢复到已有库(-c 先 DROP)
sys_restore -U system -p 54321 -d app_db -c /backup/app_db.dmp
# 并行恢复
sys_restore -U system -p 54321 -d app_db_new -j 8 /backup/app_db_dir
10.3 物理备份(sys_basebackup)
# 全量物理备份
sys_basebackup -D /backup/base_20261105 \
-h 10.0.0.11 -p 54321 -U system \
-Fp -Xs -P -R
# 参数
# -D 目标目录
# -Fp 普通文件(-Ft 为 tar)
# -Xs 流式传输 WAL
# -P 显示进度
# -R 生成备机配置
10.4 sys_rman(生产推荐)
sys_rman 是金仓的物理备份工具,支持全量、增量、差异、块增量四种模式(V9R2C016 起明确提供)。
# 1) 初始化备份目录
sys_rman init -B /backup/kbrman
# 2) 配置(sys_rman.conf)
cat > /backup/kbrman/sys_rman.conf <<'EOF'
[kb1]
kb_path = /opt/Kingbase/ES/V9
backup_path = /backup/kbrman
startup_fast = true
compress_type = lz4
compress_level = 1
retention_redundancy = 7
retention_full = 7
log_level_console = info
log_level_file = debug
EOF
# 3) 全量备份
sys_rman --config=/backup/kbrman/sys_rman.conf \
--type=full --instance=kb1 backup
# 4) 增量备份
sys_rman --config=/backup/kbrman/sys_rman.conf \
--type=incr --instance=kb1 backup
# 5) 差异备份
sys_rman --config=/backup/kbrman/sys_rman.conf \
--type=diff --instance=kb1 backup
# 6) 查看备份
sys_rman --config=/backup/kbrman/sys_rman.conf --instance=kb1 info
# 7) 校验
sys_rman --config=/backup/kbrman/sys_rman.conf --instance=kb1 verify
# 8) 恢复(需先停库)
sys_ctl stop -D $KINGBASE_DATA -m fast
sys_rman --config=/backup/kbrman/sys_rman.conf --instance=kb1 \
--type=full restore
# 9) 恢复到时间点
sys_rman --config=/backup/kbrman/sys_rman.conf --instance=kb1 \
--type=time --target='2026-11-05 09:30:00' restore
# 10) 清理过期
sys_rman --config=/backup/kbrman/sys_rman.conf --instance=kb1 expire
# 也可以用封装脚本
sys_backup.sh init # 初始化
sys_backup.sh start # 启动备份
sys_backup.sh stop
sys_backup.sh full # 全量
sys_backup.sh incr # 增量
sys_backup.sh check # 检查
sys_rman的增量备份依赖 WAL 归档。archive_mode=off时增量会失败或退化为全量。生产必须先配好归档(见第 11 章)。
10.5 备份策略
| 对象 | 频率 | 保留 | 说明 |
|---|---|---|---|
| 全量物理 | 每天 1 次 | 7 天 | sys_rman --type=full |
| 增量物理 | 每 6 小时 | 3 天 | 依赖 WAL 归档 |
| 逻辑备份 | 每周 1 次 | 30 天 | 跨版本/跨库迁移兜底 |
| WAL 归档 | 持续 | 7 天 | PITR 基础 |
11. WAL、归档与 PITR
11.1 开启归档
# 1) 归档目录
mkdir -p /archive/kb
chown -R kingbase:kingbase /archive/kb
# 2) 配置
cat >> $KINGBASE_DATA/kingbase.conf <<'EOF'
archive_mode = on
archive_command = 'test ! -f /archive/kb/%f && cp %p /archive/kb/%f'
archive_timeout = 300
EOF
# 3) 重启(archive_mode 是 postmaster 级参数)
sys_ctl restart -D $KINGBASE_DATA -m fast
# 4) 验证(手动切 WAL)
SELECT sys_switch_wal();
ls -lt /archive/kb | head
archive_command里加了test ! -f是为了幂等:归档重试时不会重复覆盖。不加的话,重复归档同名文件在某些文件系统上会报错,导致归档卡住。
11.2 WAL 状态
-- 当前 WAL 位点
SELECT sys_current_wal_lsn();
SELECT sys_current_wal_insert_lsn();
-- 备机接收/回放
SELECT sys_last_wal_receive_lsn();
SELECT sys_last_wal_replay_lsn();
-- 延迟(字节)
SELECT sys_wal_lsn_diff(sys_current_wal_lsn(), sys_last_wal_replay_lsn()) AS lag_bytes;
-- 归档统计
SELECT archived_count, failed_count, last_archived_wal, last_failed_wal
FROM sys_stat_archiver;
-- 复制槽持有量(WAL 堆积常见原因)
SELECT slot_name, active,
sys_size_pretty(sys_wal_lsn_diff(sys_current_wal_lsn(), restart_lsn)) AS retained
FROM sys_replication_slots;
11.3 PITR 流程
# 1) 确认备份 + 归档连续
sys_rman --config=/backup/kbrman/sys_rman.conf --instance=kb1 info
ls /archive/kb | wc -l
# 2) 停库
sys_ctl stop -D $KINGBASE_DATA -m fast
# 3) 保护原目录
mv $KINGBASE_DATA $KINGBASE_DATA.bak_$(date +%F)
# 4) 恢复基础备份
sys_rman --config=/backup/kbrman/sys_rman.conf --instance=kb1 \
--type=full restore
# 5) 配恢复目标
cat >> $KINGBASE_DATA/kingbase.conf <<'EOF'
restore_command = 'cp /archive/kb/%f %p'
recovery_target_time = '2026-11-05 09:30:00'
recovery_target_action = 'pause'
EOF
# 6) 恢复标记
touch $KINGBASE_DATA/recovery.signal
# 7) 启动(回放到目标点后暂停)
sys_ctl start -D $KINGBASE_DATA
# 8) 检查数据无误后升主
sys_ctl promote -D $KINGBASE_DATA
-- 验证
SELECT now(), sys_is_in_recovery();
recovery_target_action |
行为 |
|---|---|
pause |
回放到目标点暂停,可检查(生产推荐) |
promote |
回放完直接升主 |
shutdown |
回放完关机 |
恢复前一定
mv原数据目录,不要rm。恢复到错误时间点是常见事故,保留原目录才有第二次机会。
12. 主备复制与读写分离集群
12.1 复制状态
-- 主库看备机
SELECT client_addr, state, sync_state,
sent_lsn, write_lsn, flush_lsn, replay_lsn,
sys_wal_lsn_diff(sys_current_wal_lsn(), replay_lsn) AS lag_bytes
FROM sys_stat_replication;
-- sync_state: async / potential / sync / quorum
12.2 搭建备机
# 方式一:sys_basebackup(简单)
sys_basebackup -D $KINGBASE_DATA -h 10.0.0.11 -p 54321 -U system -Fp -Xs -P -R
# 方式二:repmgr(推荐,支持自动故障转移)
repmgr -h 10.0.0.11 -U repmgr -d repmgr -f /etc/repmgr.conf standby clone
repmgr -f /etc/repmgr.conf standby register
# /etc/repmgr.conf
node_id=2
node_name=kb-standby1
conninfo='host=10.0.0.12 port=54321 user=repmgr dbname=repmgr'
data_directory='/opt/Kingbase/ES/V9/data'
failover=automatic
promote_command='sys_ctl promote -D /opt/Kingbase/ES/V9/data'
follow_command='repmgr standby follow -f /etc/repmgr.conf --upstream-node-id=%n'
# 启动 repmgrd(守护进程,自动故障转移)
repmgrd -f /etc/repmgr.conf -d
12.3 主备切换
# 计划内切换(不丢数据)
repmgr -f /etc/repmgr.conf standby switchover
# 或手工
sys_ctl promote -D $KINGBASE_DATA
# 故障切换(原主不可用)
repmgr -f /etc/repmgr.conf standby promote
# 查看集群
repmgr -f /etc/repmgr.conf cluster show
repmgr -f /etc/repmgr.conf node status
# 金仓自带的集群管理脚本
./sys_monitor.sh status
./sys_monitor.sh switchover
./sys_monitor.sh promote
| 操作 | 原主状态 | 丢数据 | 可回切 |
|---|---|---|---|
switchover |
存活 | 否 | 是 |
promote(故障) |
不可用 | 可能 | 否,原主需重建 |
12.4 同步复制
# 一主一备强同步
ALTER SYSTEM SET synchronous_standby_names = 'ANY 1(kb-standby1)';
ALTER SYSTEM SET synchronous_commit = on;
# 一主两备,任一确认
ALTER SYSTEM SET synchronous_standby_names = 'ANY 1(kb-standby1,kb-standby2)';
# 两备都确认(性能最差)
ALTER SYSTEM SET synchronous_standby_names = 'FIRST 2(kb-standby1,kb-standby2)';
SELECT sys_reload_conf();
| 配置 | RPO | 延迟 | 可用性 |
|---|---|---|---|
synchronous_commit=off |
秒级丢失 | 最低 | 最高 |
ANY 1(...) |
0 | 中 | 高 |
FIRST 2(...) |
0 | 最高 | 低 |
12.5 读写分离集群
金仓的读写分离集群在备机提供只读服务,通过 VIP 或中间件路由:
| 组件 | 作用 |
|---|---|
| 主机 | 读写 |
| 备机(1~N) | 只读(hot_standby=on) |
| VIP | 主备切换时漂移,应用无感 |
sys_monitor.sh |
集群状态与切换 |
-- 确认备机可读
SHOW hot_standby;
SELECT sys_is_in_recovery(); -- t = 备机
读写分离最大的坑是「读延迟」。备机回放有延迟,刚写入的数据立刻读备机会读不到(缓存不一致)。业务侧要么强制走主库,要么接受最终一致。这是架构问题,调参解决不了。
12.6 V9R2C016:单机在线转集群
# 不停机把单机转成读写分离集群(V9R2C016 新能力)
# 具体命令由部署工具引导,核心流程:
# 1) 新增备机节点并 sys_basebackup 克隆
# 2) 配置 repmgr + VIP
# 3) 在线切换读流量到备机
# 4) 主机保持读写,完成转换
这条对存量项目价值最大——过去「单机扛不住」意味着停机重构,现在可以在线扩。但必须确认 License 支持集群形态,否则配置到一半会卡在授权校验。
13. KES RAC 共享存储集群
13.1 架构
共享存储(SAN / 分布式块存储)
│
┌──────────┼──────────┐
│ │ │
节点1 节点2 节点3
kingbase kingbase kingbase
│ │ │
└──── 集群服务(CFS/HA)─┘
│
VIP / 负载均衡
| 特性 | 说明 |
|---|---|
| 多节点同时读写 | 共享同一份数据文件 |
| 对标 | Oracle RAC |
| 前提 | 共享存储、集群版 License、心跳网络 |
| 缓存一致性 | 靠全局缓存融合(Cache Fusion)机制 |
13.2 运维要点
| 项 | 要求 |
|---|---|
| 共享存储 | 必须支持并发写,不能用 NFS |
| 心跳网络 | 独立网卡,万兆优先 |
| 时钟同步 | 偏差 < 1 秒,否则节点被驱逐 |
| 仲裁 | 必须有仲裁机制防脑裂 |
| 启停 | 按集群工具指引,不要单节点直接 sys_ctl stop |
# 集群状态(命令随部署方式差异较大,以现场部署文档为准)
cfs_cli -S # 集群文件系统状态
sys_ctl status -D $KINGBASE_DATA
KES RAC 的管理命令在不同部署工具(图形化部署 / 手工部署 / 一体机)下差异很大,没有一套通用的命令集。本手册不给具体命令,避免误导——现场必须以交付文档为准。
14. 日志与审计
14.1 日志
| 日志 | 路径 | 内容 |
|---|---|---|
| 运行日志 | $KINGBASE_DATA/sys_log/ |
启动、错误、慢 SQL |
| WAL | $KINGBASE_DATA/sys_wal/ |
事务日志 |
| 归档 | /archive/kb/ |
归档文件 |
| 审计日志 | $KINGBASE_DATA/sys_aud/ |
需开启审计 |
| 备份日志 | sys_rman 输出 |
备份记录 |
# 实时跟踪
tail -f $KINGBASE_DATA/sys_log/kingbase-*.log
# 找错误
grep -E 'ERROR|FATAL|PANIC' kingbase-*.log | tail -100
# 按时间段
awk '/2026-11-05 09:2/,/2026-11-05 09:3/' kingbase-*.log
# 统计错误类型
grep -oE 'ERROR:.*' kingbase-*.log | sort | uniq -c | sort -rn | head -20
14.2 日志参数
ALTER SYSTEM SET log_min_duration_statement = 1000; -- 慢 SQL 1s
ALTER SYSTEM SET log_statement = 'ddl';
ALTER SYSTEM SET log_checkpoints = on;
ALTER SYSTEM SET log_connections = on;
ALTER SYSTEM SET log_disconnections = on;
ALTER SYSTEM SET log_line_prefix = '%m [%p] %u@%d %r ';
ALTER SYSTEM SET log_rotation_age = '1d';
ALTER SYSTEM SET log_rotation_size = '100MB';
SELECT sys_reload_conf();
14.3 审计
-- 查看审计开关
SHOW audit_enabled;
-- 开启(需重启)
ALTER SYSTEM SET audit_enabled = on;
-- 审计用户
CREATE AUDIT USER app;
-- 审计语句
AUDIT SELECT, INSERT, UPDATE, DELETE ON orders BY app;
-- 查看审计记录(需 audo 权限)
SELECT * FROM sys_audit_records
WHERE audit_time > now() - interval '1 day'
ORDER BY audit_time DESC LIMIT 50;
-- 审计策略
SELECT * FROM sys_audit_policy;
金仓的审计是内核级的(不是扩展),开启后对性能有 3%~8% 影响。生产环境建议只审计 DDL 和敏感表的 DML,不要
AUDIT ALL。
15. 性能诊断
15.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 |
15.2 性能视图
-- 活跃会话
SELECT pid, usename, datname, state,
now() - query_start AS duration, left(query, 100)
FROM sys_stat_activity
WHERE state = 'active' AND now() - query_start > interval '5 seconds'
ORDER BY duration DESC;
-- 表访问统计
SELECT relname, seq_scan, idx_scan, n_tup_ins, n_tup_upd, n_tup_del
FROM sys_stat_user_tables
ORDER BY seq_scan DESC LIMIT 20;
-- 索引使用
SELECT relname, indexrelname, idx_scan, idx_tup_read
FROM sys_stat_user_indexes
ORDER BY idx_scan ASC LIMIT 20; -- idx_scan=0 可能是无用索引
-- 等待事件(需开启)
SELECT wait_event_type, wait_event, COUNT(*)
FROM sys_stat_activity
WHERE wait_event IS NOT NULL
GROUP BY 1,2 ORDER BY 3 DESC;
-- 数据库级统计
SELECT * FROM sys_stat_database WHERE datname = 'app_db';
-- 后台写
SELECT * FROM sys_stat_bgwriter;
15.3 慢 SQL 采集
-- 需安装扩展(部分版本内置)
CREATE EXTENSION IF NOT EXISTS sys_stat_statements;
SELECT query, calls, total_exec_time/1000 AS total_ms,
mean_exec_time/1000 AS mean_ms, rows
FROM sys_stat_statements
ORDER BY total_exec_time DESC LIMIT 20;
如果
sys_stat_statements不存在,试pg_stat_statements(部分版本保留 PG 原名)。金仓的扩展命名不完全统一,\dx看一下已安装列表最稳。
15.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 sys_stat_activity w
JOIN sys_locks l1 ON w.pid = l1.pid AND NOT l1.granted
JOIN sys_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 sys_stat_activity b ON b.pid = l2.pid;
-- 长事务
SELECT pid, usename, state, now() - xact_start AS xact_age, left(query, 80)
FROM sys_stat_activity
WHERE xact_start IS NOT NULL
ORDER BY xact_age DESC LIMIT 10;
-- 杀会话
SELECT sys_terminate_backend(pid);
长事务是金仓最大的隐形杀手。它同时导致:① 锁等待;② VACUUM 无法回收(膨胀);③ 事务号冻结跟不上。发现超过 1 小时的空闲事务,直接杀,不要犹豫。
15.5 内存诊断
-- 会话内存(部分版本可用)
SELECT * FROM sys_stat_activity WHERE state = 'active';
-- 共享内存
SHOW shared_buffers;
SHOW work_mem;
SHOW maintenance_work_mem;
# OS 层
free -g
ps -ef | grep kingbase | grep -v grep | wc -l
iostat -x 1 3
16. VACUUM、事务号与膨胀
16.1 VACUUM
-- 普通 VACUUM(不锁表)
VACUUM orders;
VACUUM VERBOSE orders;
-- VACUUM FULL(锁表,真正归还 OS)
VACUUM FULL orders;
-- 分析
ANALYZE orders;
-- 组合
VACUUM ANALYZE orders;
-- 查看死元组
SELECT relname, n_live_tup, n_dead_tup,
ROUND(n_dead_tup::numeric / GREATEST(n_live_tup,1) * 100, 2) AS dead_pct,
last_vacuum, last_autovacuum
FROM sys_stat_user_tables
WHERE n_dead_tup > 10000
ORDER BY n_dead_tup DESC;
| 操作 | 锁 | 空间回收 | 适用 |
|---|---|---|---|
VACUUM |
无 | 标记可复用 | 日常 |
VACUUM FULL |
排他 | 真正归还 | 严重膨胀 |
VACUUM ANALYZE |
无 | 同时更新统计 | 日常推荐 |
VACUUM FREEZE |
无 | 冻结事务号 | 防回卷 |
16.2 事务号:V9 的关键改进
这是本手册最需要展开的一节,因为它解释了「为什么有些库跑了三年突然变慢」。
32 位事务号的困境:
事务号空间 ≈ 42.9 亿
每 100 万事务消耗 1 个「百万单位」
达到 autovacuum_freeze_max_age(默认 2 亿)时强制 freeze
freeze 追不上 → 数据库拒绝写入("database is not accepting commands")
V9R2C016 把事务号扩到 64 位,从根上解决了这个问题。同时把两项 autovacuum 参数默认值提升 50 倍:
| 参数 | V8 默认 | V9R2C016 默认 | 影响 |
|---|---|---|---|
autovacuum_freeze_max_age |
2 亿 | 提升 50 倍 | freeze 触发更晚,长事务容忍度更高 |
autovacuum_multixact_freeze_max_age |
4 亿 | 提升 50 倍 | 同上(多事务) |
升级到 V9R2C016 后的两个注意点:
- 如果
kingbase.conf里显式写了旧值,新默认值不会生效,需要手工改成新值或删掉这两行;- 升级后不能回退到 V8(事务号格式变了),升级前必须做完整备份并验证恢复。
-- 查看当前事务号使用情况
SELECT datname, age(datfrozenxid) AS xid_age,
2147483647 - age(datfrozenxid) AS remaining
FROM sys_database
ORDER BY age(datfrozenxid) DESC;
-- 使用率超过 50% 要关注,超过 80% 必须处理
SELECT datname,
ROUND(age(datfrozenxid)::numeric / 2147483647 * 100, 2) AS used_pct
FROM sys_database
ORDER BY used_pct DESC;
-- 手工 freeze(在低峰执行)
VACUUM FREEZE app_db.public.big_table;
-- 查看表级事务号年龄
SELECT relname, age(relfrozenxid) AS xid_age
FROM sys_class c JOIN sys_namespace n ON c.relnamespace = n.oid
WHERE n.nspname = 'public' AND c.relkind = 'r'
ORDER BY age(relfrozenxid) DESC LIMIT 20;
# 用工具检查(部分版本提供)
sys_waldump -p $KINGBASE_DATA/sys_wal | tail -20
16.3 膨胀排查
-- 估算膨胀(需要统计信息较新)
SELECT schemaname, relname, n_live_tup, n_dead_tup,
sys_size_pretty(sys_total_relation_size(relid)) AS size,
ROUND(n_dead_tup::numeric / GREATEST(n_live_tup + n_dead_tup,1) * 100, 1) AS dead_pct
FROM sys_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY sys_total_relation_size(relid) DESC LIMIT 20;
-- 精确检查(需扩展)
CREATE EXTENSION IF NOT EXISTS sysstattuple;
SELECT * FROM sysstattuple('orders');
-- 关注 dead_tuple_percent 与 free_percent
16.4 autovacuum 调优
-- 全局
ALTER SYSTEM SET autovacuum = on;
ALTER SYSTEM SET autovacuum_naptime = '30s';
ALTER SYSTEM SET autovacuum_max_workers = 6;
ALTER SYSTEM SET autovacuum_vacuum_scale_factor = 0.05;
-- 单表(大表必做,全局阈值对大表太迟钝)
ALTER TABLE orders SET (autovacuum_vacuum_scale_factor = 0.01);
ALTER TABLE orders SET (autovacuum_vacuum_threshold = 10000);
ALTER TABLE orders SET (autovacuum_analyze_scale_factor = 0.005);
大表一定要单独设
scale_factor。默认 0.2 意味着 1 亿行的表要死 2000 万行才触发 vacuum,那时膨胀已经不可收拾。经验值:大表设 0.01,超大表设 0.005。
17. 空间与容量管理
17.1 空间统计
-- 库级
SELECT datname, sys_size_pretty(sys_database_size(datname)) size
FROM sys_database ORDER BY sys_database_size(datname) DESC;
-- 表级 Top20
SELECT schemaname, relname,
sys_size_pretty(sys_total_relation_size(relid)) total,
sys_size_pretty(sys_relation_size(relid)) heap,
sys_size_pretty(sys_indexes_size(relid)) idx
FROM sys_stat_user_tables
ORDER BY sys_total_relation_size(relid) DESC LIMIT 20;
-- 单表
SELECT sys_size_pretty(sys_total_relation_size('orders')) AS total,
sys_size_pretty(sys_relation_size('orders')) AS heap,
sys_size_pretty(sys_indexes_size('orders')) AS indexes;
17.2 回收
-- 1) 删数据(分批)
DELETE FROM logs WHERE created_at < '2026-01-01' LIMIT 10000;
-- 循环到 0 行
-- 2) 删分区(大表首选)
DROP TABLE logs_p202601;
-- 3) 回收
VACUUM logs;
-- 4) 极端情况:重建表
BEGIN;
CREATE TABLE logs_new (LIKE logs INCLUDING ALL);
INSERT INTO logs_new SELECT * FROM logs;
DROP TABLE logs;
ALTER TABLE logs_new RENAME TO logs;
COMMIT;
17.3 WAL 空间
-- WAL 目录大小
SELECT sys_size_pretty(SUM(size))
FROM sys_ls_dir('sys_wal') AS f,
sys_stat_file('sys_wal/'||f) AS s;
-- 复制槽(堆积头号原因)
SELECT slot_name, active,
sys_size_pretty(sys_wal_lsn_diff(sys_current_wal_lsn(), restart_lsn)) AS retained
FROM sys_replication_slots;
-- 删除废弃槽
SELECT sys_drop_replication_slot('slot_name');
WAL 暴涨三大原因:① 归档失败;② 复制槽无人消费;③ 备机长期失联。三者都会让
sys_wal无限增长直到磁盘满。
18. 升级与迁移
18.1 小版本升级
# 1) 备份
sys_rman --config=/backup/kbrman/sys_rman.conf --instance=kb1 --type=full backup
# 2) 停库
sys_ctl stop -D $KINGBASE_DATA -m fast
# 3) 安装新版本到新目录
./setup.sh -i console # 安装路径选 /opt/Kingbase/ES/V9R2C16
# 4) 用新二进制启动旧数据目录
/opt/Kingbase/ES/V9R2C16/Server/bin/sys_ctl start -D $KINGBASE_DATA
# 5) 验证后切换 PATH 和服务指向
金仓的小版本升级兼容旧数据目录(同大版本内)。跨大版本(V8 → V9)必须用
sys_upgrade或逻辑迁移。
18.2 V8 → V9 升级
# 方式一:sys_upgrade(原地升级,需停机)
/opt/Kingbase/ES/V9/Server/bin/sys_upgrade \
--old-bindir=/opt/Kingbase/ES/V8/Server/bin \
--new-bindir=/opt/Kingbase/ES/V9/Server/bin \
--old-datadir=/opt/Kingbase/ES/V8/data \
--new-datadir=/opt/Kingbase/ES/V9/data
# 方式二:逻辑迁移(跨兼容模式或跨平台时)
sys_dumpall -p 54321 -f /backup/all.sql
# 新库 initdb + 导入
V8 → V9 是不小的跨越(多模架构、事务号、并行能力都变了),生产升级建议走「逻辑迁移 + 双跑比对」而不是原地
sys_upgrade。原地升级风险在于扩展兼容性和事务号格式。
18.3 从 Oracle 迁移
| 差异 | Oracle | KES(oracle 模式) | 处置 |
|---|---|---|---|
| 数据字典 | ALL_TABLES |
sys_tables / 兼容视图 |
部分可用 |
ROWNUM |
支持 | 支持 | — |
DUAL |
有 | 有 | — |
NVL |
支持 | 支持 | — |
| PL/SQL | 支持 | 兼容率 > 95% | 大部分直接迁 |
ROWID |
支持 | 支持但语义不同 | 不建议依赖 |
| 空串 vs NULL | 空串 = NULL | 同(oracle 模式) | — |
| 分区自动新增 | INTERVAL |
不支持 | 需定时任务 |
# 金仓迁移工具链
# KDMS 迁移评估(出改造量报告)
# KDTS 数据迁移(支持正反向)
# KFS 异构同步(基于日志解析)
官方口径 Oracle 常用语法支持度 98.7%、PL/SQL 兼容率 >95%。剩下那 1%~2% 往往集中在系统包(
DBMS_LOB、UTL_FILE、DBMS_SCHEDULER)和高级分区上,迁移评估阶段必须逐项确认。
18.4 从 MySQL 迁移
| 差异 | MySQL | KES(mysql 模式) | 处置 |
|---|---|---|---|
| 反引号 | 支持 | 支持 | — |
LIMIT |
支持 | 支持 | — |
AUTO_INCREMENT |
支持 | SERIAL / 序列 |
建表改造 |
| 存储引擎 | InnoDB | 无此概念 | 去掉 ENGINE= |
| 字符集 | utf8mb4 |
UTF8 | 建库时定 |
ON UPDATE CURRENT_TIMESTAMP |
支持 | 需触发器 | 改造 |
19. 高频故障速查
19.1 起不来
| 报错 | 原因 | 处置 |
|---|---|---|
could not create shared memory |
kernel.shmmax 太小 |
调 /etc/sysctl.conf |
could not bind |
54321 被占 | ss -lntp | grep 54321 |
permission denied |
数据目录属主错 | chown -R kingbase:kingbase $KINGBASE_DATA |
database system was not properly shut down |
上次异常退出 | 正在崩溃恢复,等 |
no space left on device |
磁盘满 | 清 WAL / 归档 |
database is not accepting commands |
事务号回卷保护 | 立即 VACUUM FREEZE,见 16.2 |
19.2 连不上
| 现象 | 处置 |
|---|---|
Connection refused |
进程 → 端口 → 防火墙 |
no sys_hba.conf entry |
加认证行 + sys_ctl reload |
password authentication failed |
密码错 / 加密方式变了 / 账号锁定 |
too many clients already |
调 max_connections 或查连接池泄漏 |
FATAL: the database system is in recovery mode |
恢复中,等 |
# 快速定位
sys_ctl status -D $KINGBASE_DATA
ss -lntp | grep 54321
tail -100 $KINGBASE_DATA/sys_log/kingbase-*.log
19.3 主备不同步
# 状态
repmgr -f /etc/repmgr.conf cluster show
# 延迟(ksql 内执行)
ksql -U system -d test -p 54321 -c \
"SELECT client_addr, sync_state, sys_wal_lsn_diff(sys_current_wal_lsn(), replay_lsn) AS lag_bytes FROM sys_stat_replication;"
| 原因 | 判断 | 处置 |
|---|---|---|
| 网络抖动 | 延迟波动后自愈 | 修网络 |
| 备机 IO 慢 | iostat %util 高 |
换盘 |
| 主库大事务 | sys_stat_activity 有长事务 |
拆批 |
| WAL 被删 | 备机报 requested WAL segment has already been removed |
全量重建备机 |
| 复制槽堆积 | sys_replication_slots 有 inactive 槽 |
删除废弃槽 |
19.4 膨胀与变慢
① 死元组比例? sys_stat_user_tables.n_dead_tup
② 事务号年龄? age(datfrozenxid)
③ 长事务? sys_stat_activity.xact_start
④ 统计信息过期? last_analyze
⑤ 无用索引? idx_scan = 0
⑥ autovacuum 在跑? sys_stat_activity query like '%autovacuum%'
19.5 事务号告警
-- 一出现这个查询结果就要处理
SELECT datname, age(datfrozenxid),
ROUND(age(datfrozenxid)::numeric/2147483647*100, 1) AS pct
FROM sys_database ORDER BY age(datfrozenxid) DESC;
| 使用率 | 状态 | 处置 |
|---|---|---|
| < 50% | 正常 | — |
| 50~80% | 关注 | 检查 autovacuum 是否在跑、有无长事务 |
| 80~95% | 严重 | 手工 VACUUM FREEZE 大表 |
| > 95% | 危急 | 立即停业务、freeze,否则库会停写 |
20. 危险命令与避坑清单
| # | 命令 | 风险 | 防护 |
|---|---|---|---|
| 1 | rm -rf $KINGBASE_DATA |
数据全丢 | 先 sys_rman 全量备份 |
| 2 | kill -9 kingbase |
崩溃恢复 | 用 sys_ctl stop -m fast |
| 3 | DROP DATABASE |
不可恢复 | 先 sys_dump;限制权限 |
| 4 | TRUNCATE / DELETE 无 WHERE |
数据丢失 | 事务内先 SELECT COUNT(*) |
| 5 | VACUUM FULL 大表 |
排他锁,业务全停 | 低峰执行或用在线重建 |
| 6 | 关闭 autovacuum |
膨胀 + 事务号回卷 | 绝对禁止 |
| 7 | 直接删 sys_wal 文件 |
备机全量重建、PITR 断档 | 修归档 / 删复制槽 |
| 8 | 改 database_mode |
不可能,只能重initdb | 初始化时想清楚 |
| 9 | V9 升级后回退 V8 | 事务号格式不兼容,库起不来 | 升级前完整备份 |
| 10 | 单机 License 配 RAC | 启动失败 | 确认授权类型 |
变更前五步
- 备份:
sys_rman --type=full backup,记录备份 ID; - 确认角色:
sys_is_in_recovery(),别在备机上做写操作; - 确认事务号:
age(datfrozenxid)是否健康; - 备份配置:
cp kingbase.conf kingbase.conf.bak.$(date +%F); - 留痕:记录变更前后
sys_stat_replication、sys_stat_activity快照。
21. 附录:一键巡检脚本
#!/usr/bin/env bash
# kes_health_check.sh —— 一分钟巡检
# 用法:su - kingbase 后执行 ./kes_health_check.sh
set -uo pipefail
export KINGBASE_HOME=${KINGBASE_HOME:-/opt/Kingbase/ES/V9}
export KINGBASE_DATA=${KINGBASE_DATA:-/opt/Kingbase/ES/V9/data}
PORT=${PORT:-54321}
Q() { "$KINGBASE_HOME/Server/bin/ksql" -h 127.0.0.1 -p "$PORT" -U system -d test \
-A -F $'\t' -t -c "$1" 2>/dev/null; }
echo "==================== KingbaseES 巡检 $(date '+%F %T') ===================="
echo -e "\n--- 1. 版本与兼容模式 ---"
Q "SELECT version();"
Q "SHOW database_mode;"
echo -e "\n--- 2. 实例状态 ---"
"$KINGBASE_HOME/Server/bin/sys_ctl" status -D "$KINGBASE_DATA" 2>&1 | head -3
echo -e "\n--- 3. 连接数 ---"
Q "SELECT 'total=' || COUNT(*) FROM sys_stat_activity;"
Q "SELECT 'active=' || COUNT(*) FROM sys_stat_activity WHERE state='active';"
Q "SHOW max_connections;"
echo -e "\n--- 4. 复制状态与延迟 ---"
Q "SELECT client_addr, state, sync_state,
sys_wal_lsn_diff(sys_current_wal_lsn(), replay_lsn) AS lag_bytes
FROM sys_stat_replication;"
echo -e "\n--- 5. 长事务(>5min)---"
Q "SELECT pid, usename, ROUND(EXTRACT(EPOCH FROM (now()-xact_start))) AS sec,
LEFT(query,70)
FROM sys_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. 事务号使用率(>50% 关注)---"
Q "SELECT datname, age(datfrozenxid) AS xid_age,
ROUND(age(datfrozenxid)::numeric/2147483647*100, 2) AS used_pct
FROM sys_database ORDER BY used_pct DESC;"
echo -e "\n--- 7. 死元组 Top10(>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 sys_stat_user_tables
WHERE n_dead_tup > 10000 ORDER BY dead_pct DESC LIMIT 10;"
echo -e "\n--- 8. 慢查询(当前活跃 >5s)---"
Q "SELECT pid, ROUND(EXTRACT(EPOCH FROM (now()-query_start))) AS sec, LEFT(query,80)
FROM sys_stat_activity
WHERE state='active' AND now()-query_start > interval '5 seconds'
ORDER BY sec DESC LIMIT 5;"
echo -e "\n--- 9. 锁等待 ---"
Q "SELECT COUNT(*) FROM sys_locks WHERE NOT granted;"
echo -e "\n--- 10. 归档状态 ---"
Q "SELECT archived_count, failed_count, last_archived_wal FROM sys_stat_archiver;"
echo -e "\n--- 11. 复制槽持有 WAL ---"
Q "SELECT slot_name, active,
sys_size_pretty(sys_wal_lsn_diff(sys_current_wal_lsn(), restart_lsn)) AS retained
FROM sys_replication_slots;"
echo -e "\n--- 12. 表空间 / 磁盘 ---"
Q "SELECT datname, sys_size_pretty(sys_database_size(datname))
FROM sys_database ORDER BY sys_database_size(datname) DESC LIMIT 5;"
df -h "$KINGBASE_DATA" /archive/kb 2>/dev/null | awk 'NR==1 || /[0-9]%/{print " "$0}'
echo -e "\n--- 13. 日志 ERROR 计数(近 500 行)---"
for f in "$KINGBASE_DATA"/sys_log/kingbase-*.log; do
[ -f "$f" ] && printf " %-60s %s\n" "$f" "$(tail -500 "$f" | grep -c 'ERROR')"
done
echo -e "\n==================== 巡检结束 ===================="
速查表
| 需求 | 命令 |
|---|---|
| 启停 | sys_ctl start/stop -D $KINGBASE_DATA -m fast |
| 状态 | sys_ctl status -D $KINGBASE_DATA |
| 重载配置 | sys_ctl reload -D $KINGBASE_DATA |
| 升主 | sys_ctl promote -D $KINGBASE_DATA |
| 逻辑备份 | sys_dump -Fc -f out.dmp db |
| 物理备份 | sys_rman --type=full backup |
| 恢复 | sys_rman --type=full restore |
| 归档 | SELECT sys_switch_wal() |
| 事务号 | SELECT age(datfrozenxid) FROM sys_database |
| 膨胀 | sys_stat_user_tables.n_dead_tup |
| 锁 | sys_locks |
| 慢 SQL | log_min_duration_statement |
| 主备 | repmgr cluster show |
| 切换 | repmgr standby switchover |
最后一句:金仓是「最像 PostgreSQL 的国产库」,但有三个关键差异——端口 54321、
sys_前缀、database_mode不可改。另外,V9R2C016 把事务号扩到 64 位是这几年国产库里最实在的一处改进,升级时别忘了核对autovacuum那两个参数的旧值是否把新默认覆盖了。