概述
在数据库国产化替代的浪潮下,电科金仓 KingbaseES,是政企客户 PostgreSQL、Oracle 数据库国产化迁移的主流选型之一。本次基于 KingbaseES V009R002C016PS003 补丁版本,针对四大核心能力开展隔离环境实测,完整复现 "发现 --- 验证 --- 修复" 全链路验证过程,为国产数据库选型与运维提供一手证据。本文为完整操作实录版,保留各实验的关键命令、参数与原始日志,可复现。
一、实验环境总览
|-------|-----------------------------------------|
| 项目 | 配置 |
| 服务器 | 192.168.x.195,Rocky Linux 8.10(x86-64) |
| 数据库版本 | KingbaseES V009R002C016PS003(PS003 补丁版) |
| 实例 | 127.0.0.1:54331,Oracle 兼容模式 |
| 物理内存 | 62 GiB,可用约 56 GiB,Swap 7.9 GiB |
| 根文件系统 | XFS 48 GiB(可用约 11 GiB,reflink=1) |
| 测试方式 | 独立测试库/隔离实验实例,不触碰正式生产数据 |
连接示例:
bash
export KINGBASE_PASSWORD='Kbxxxx'
/opt/Kingbase/ES/V9R2C16/Server/bin/ksql \
-h 127.0.0.1 -p 54331 -U system -d xid_vacuum_lab_20261010
本文四大实验均基于独立环境完成,结论严格区分"已实测"与"受环境限制未执行",命令、参数、日志均按本机实际记录。
二、实测一:64位事务ID与自动清理
(一)参数配置信息说明
autovacuum_freeze_max_age 参数的相关配置说明:
|------------------------------------------------|------------------|----------------------|---------------|---------------------|
| 参数 | 变更前 | 变更后 | 类型 | 最大值 |
| autovacuum_freeze_max_age(普通事务ID) | 默认 200000000(2亿) | 默认 10000000000(100亿) | integer→int64 | 1152921504606846975 |
| autovacuum_multixact_freeze_max_age(MultiXact) | 默认 400000000(4亿) | 默认 20000000000(200亿) | integer→int64 | 1152921504606846975 |
两者数据类型均由 integer 升级为 int64,最大值从 20 亿提升至 1152921504606846975,彻底消除了旧的 20 亿参数天花板。
(二)64位事务ID证据链
通过组合证据确认 xid 已真正升级为 64 位,而非单一接口误判。
① xid 类型物理宽度为 8 字节
sql
SELECT oid, typname, typlen, typbyval, typcategory
FROM sys_type
WHERE typname IN ('xid','xid8') ORDER BY typname;
结果:xid 类型 typlen=8。系统目录字段同为 8 字节:
sql
SELECT c.relname, a.attname, t.typname, t.typlen
FROM sys_class c
JOIN sys_attribute a ON a.attrelid=c.oid
JOIN sys_type t ON t.oid=a.atttypid
WHERE c.relname IN ('sys_database','sys_class')
AND a.attname IN ('datfrozenxid','relfrozenxid')
ORDER BY c.relname;
结果:sys_class.relfrozenxid、sys_database.datfrozenxid 均为 xid /typlen=8。
② 大于 32 位上限的 XID 值可表达
sql
SELECT '4294967295'::xid AS max_u32,
'4294967296'::xid AS over_u32,
'9223372036854775807'::xid AS max_i64;
结果:4294967295、4294967296、9223372036854775807 均可正确转换,已突破 32 位无符号上限。额外边界测试显示,输入 18446744073709551616 或 -1 时,类型转换会饱和返回 18446744073709551615,属于无符号类型转换语义,业务程序不可依赖该返回值做合法性校验逻辑。
③ age 返回 bigint,控制文件 NextXID 为纯数值
sql
SELECT datname, datfrozenxid, age(datfrozenxid) AS xid_age,
pg_typeof(age(datfrozenxid)) AS age_type
FROM sys_database WHERE datname=current_database();
结果:xid_age=34,age_type=bigint。
bash
su - kingbase -c "/opt/Kingbase/ES/V9R2C16/Server/bin/sys_controldata /opt/Kingbase/ES/V9R2C16/data" \
| grep -Ei 'Database cluster state|Latest checkpoint.s NextXID|Latest checkpoint location'
结果:Latest checkpoint's NextXID: 1174,以纯数值记录,未见传统 32 位事务号常用的 epoch:xid 形式。
提示:txid_current () 在老版本也可能返回 bigint,但底层事务 ID 仍是 32 位,因此不能单独作为 64 位事务 ID 的判定证据,必须组合上述多项证据链判断。本版本没有 pg_current_xact_id() / pg_current_xact_id_if_assigned() 接口,txid_current_snapshot () 在 PS003 补丁版本暂不支持事务快照查询,验证 64 位 XID 请采用本次实测验证有效的查询语句。
(三)VACUUM/Autovacuum 参数实测
bash
SELECT name, setting, boot_val, source, vartype, min_val, max_val, context
FROM sys_settings
WHERE name IN (
'autovacuum_freeze_max_age','autovacuum_multixact_freeze_max_age',
'vacuum_freeze_min_age','vacuum_freeze_table_age',
'vacuum_multixact_freeze_min_age','vacuum_multixact_freeze_table_age')
ORDER BY name;
结果(部分):autovacuum_freeze_max_age=10000000000(int64,max 1152921504606846975)、autovacuum_multixact_freeze_max_age=20000000000(int64)。其余 Autovacuum:autovacuum=on、max_workers=3、naptime=60s、vacuum_threshold=50、scale_factor=0.2。
超旧 32 位参数上限的会话级验证与恢复:
sql
SHOW vacuum_freeze_min_age;
-- 50000000
SET vacuum_freeze_min_age=1000000001;
-- 超越原有 10 亿上限,设置成功
SHOW vacuum_freeze_min_age;
-- 1000000001
SET vacuum_freeze_table_age=2000000001;
-- 超越原有 20 亿上限,设置成功
RESET vacuum_freeze_min_age;
RESET vacuum_freeze_table_age;
SHOW vacuum_freeze_min_age;
-- 50000000(已恢复)
SHOW vacuum_freeze_table_age;
-- 150000000(已恢复)
(四)Autovacuum 实际触发验证
创建隔离表并制造死元组(只对测试表设置表级参数,不改实例全局):
sql
CREATE TABLE xid_vacuum_probe(
id bigint PRIMARY KEY, payload text, updated_at timestamp default now()
) WITH (
autovacuum_vacuum_threshold=0, autovacuum_vacuum_scale_factor=0,
autovacuum_analyze_threshold=0, autovacuum_analyze_scale_factor=0,
autovacuum_freeze_min_age=0
);
sql
INSERT INTO xid_vacuum_probe(id,payload)
SELECT g, repeat(md5(g::text),4) FROM generate_series(1,10000) g;
UPDATE xid_vacuum_probe SET payload=payload||'_u', updated_at=clock_timestamp() WHERE id<=5000;
DELETE FROM xid_vacuum_probe WHERE id>7500;
结果:CREATE TABLE、INSERT 0 10000、UPDATE 5000、DELETE 2500。统计快照:n_live_tup=7500, n_dead_tup=7500。约一个 autovacuum_naptime 周期后:n_dead_tup=0,autovacuum_count=1、autoanalyze_count=1,last_autovacuum=2026-10-10 15:15:20。证明 Autovacuum 已启用且能依据表级阈值正常回收死元组、更新统计信息。
(五)VACUUM FREEZE 实际行为
bash
VACUUM (VERBOSE, FREEZE, ANALYZE) xid_vacuum_probe;
关键日志:
bash
INFO: aggressively vacuuming "public.xid_vacuum_probe"
INFO: "xid_vacuum_probe": found 0 removable, 15 nonremovable row versions in 1 out of 334 pages
Skipped 0 pages due to buffer pins, 333 frozenTup pages.
INFO: analyzing "public.xid_vacuum_probe"
VACUUM执行后 relfrozenxid 从 1169 推进到 1171,冻结年龄保持为 1;vacuum_count=1、autovacuum_count=1。手工与自动清理计数均成功记账。
(六)长期运行余量结论
- 普通事务强制冻结阈值提升 50 倍(2 亿 → 100 亿),MultiXact 同样提升 50 倍(4 亿 → 200 亿);
- 相关参数类型由 integer 升级为 int64,最大允许值达 1152921504606846975,消除旧 20 亿天花板;
- xid 为 8 字节,可表达超过 32 位上限的事务号;
- 64 位 XID 大幅扩大编号空间、降低回卷停库紧迫性,即便升级 64 位事务 ID,仍建议常规执行 VACUUM 完成垃圾回收、管控表膨胀;长事务会影响清理效率,属于通用数据库运维关注点,需持续监控。
生产环境仍需监控:
sql
-- 数据库级冻结年龄
SELECT datname, age(datfrozenxid) FROM sys_database ORDER BY age(datfrozenxid) DESC;
-- 表级冻结年龄与 Autovacuum 统计
SELECT schemaname, relname, age(relfrozenxid) AS xid_age,
n_live_tup, n_dead_tup, last_autovacuum, autovacuum_count
FROM sys_stat_user_tables
JOIN sys_class ON sys_class.oid=sys_stat_user_tables.relid
ORDER BY age(relfrozenxid) DESC;
三、实测二:实例级动态内存与 HashAgg 大聚合保护
(一)核心机制
max_dynamic_memory 是实例级内存上下文(context=kingbase)的动态内存上限参数,当前版本默认 -1(含义 "不限制"),extra_desc: -1 means no limit。本次将参数临时配置为 64MB,重启实例完成验证。
(二)构造独立测试数据
sql
CREATE DATABASE kb_memtest;
CREATE UNLOGGED TABLE hashagg_src(id bigint NOT NULL, grp bigint NOT NULL, payload text NOT NULL);
INSERT INTO hashagg_src
SELECT g, g, repeat(md5(g::text), 2) FROM generate_series(1, 800000) AS g;
ANALYZE hashagg_src;
结果:rows=800000、total_size=89 MB。插入约 1.404s,分析约 161ms。
(三)对照组 A:充足 work_mem,HashAgg 全内存完成
sql
SET max_parallel_workers_per_gather=0; SET enable_sort=off; SET enable_hashagg=on;
SET work_mem='128MB'; SET hash_mem_multiplier=2;
SET temp_file_limit='512MB'; SET log_temp_files=0;
EXPLAIN (ANALYZE, BUFFERS, TIMING, SUMMARY)
SELECT grp, count(*) AS cnt, sum(length(payload)) AS bytes
FROM hashagg_src GROUP BY grp;
关键执行计划:Batches: 1、Memory Usage: 139281kB、无Disk Usage------哈希表完全驻留内存。结果核对:group_count=800000, input_rows=800000, payload_bytes=51200000。
(四)对照组 B:低 work_mem,HashAgg 受控落盘
sql
SET work_mem='1MB'; SET hash_mem_multiplier=1;
-- 其余同对照组 A
关键执行计划:Planned Partitions: 32, Batches: 289、Memory Usage: 1209kB, Disk Usage: 95472kB、temp read=16486, written=28055。聚合结果完全一致。日志记录临时文件:
bash
2026-10-10 15:16:59 CST LOG: temporary file:
dPath "base/syssql_tmp/syssql_tmp3899293.0", sz 97763328
(五)实例级 max_dynamic_memory 上限测试
① 临时设置 64MB 上限并重启生效
# ksql 中执行
sql
ALTER SYSTEM SET max_dynamic_memory='64MB';
# 实例级参数需重启生效
bash
systemctl restart kingbase-v9r2c16.service
systemctl is-active kingbase-v9r2c16.service
systemctl is-enabled kingbase-v9r2c16.service
生效结果:max_dynamic_memory=64 MB,source=configuration file,service active / enabled,listener 0.0.0.0:54331。
② 超限保护:高 work_mem 被受控拒绝
sql
SET statement_timeout='60s';
SET max_parallel_workers_per_gather=0; SET enable_sort=off; SET enable_hashagg=on;
SET work_mem='128MB'; SET hash_mem_multiplier=2;
SET temp_file_limit='512MB'; SET log_temp_files=0;
SHOW max_dynamic_memory;
-- 64MB
-- 执行上述 HashAgg 查询
数据库返回:
bash
WARNING: The memory usage has reached the upper limit.
ERROR: out of memory
DETAIL: Failed on request of size 24 in memory context "ExpressionContext".
Time: 185.899 ms
系统资源对比:测试前后 available=57188→57187MB、swap used=0、服务 active------该报错由 KingbaseES 实例内部内存上限拦截触发,不是操作系统 OOM Killer 杀掉进程。日志同步记录 upper limit / out of memory / 临时文件证据。
③ 上限内运行:低 work_mem 自动落盘并成功
保持 64MB 上限,仅把 work_mem='1MB'、hash_mem_multiplier=1:
关键执行计划:Planned Partitions: 32, Batches: 297、Memory Usage: 1209kB, Disk Usage: 95480kB。结果再次核对成功:group_count=800000, input_rows=800000, payload_bytes=51200000。
(六)恢复与清理
sql
ALTER SYSTEM RESET max_dynamic_memory;
systemctl restart kingbase-v9r2c16.service
DROP DATABASE kb_memtest;
恢复后核对:max_dynamic_memory=-1 MB(source=default)、work_mem=4096kB、temp_file_limit=-1、hash_mem_multiplier=2,service active,listener 54331,swap used 0B。
(七)结论与运维建议
- max_dynamic_memory 为实例提供内存保护能力,不能替代 SQL 治理:该内存防护能力需要合理调参;参数配置需结合业务并发、负载规划,才能发挥实例内存保护效果;上线前应结合并发数、连接池和峰值负载压测;
- work_mem 按会话、按执行节点分配,复杂 SQL 多个节点并存时内存需求随并发相乘;
- OLTP 全局 work_mem 宜保守,报表/批处理用 SET LOCAL work_mem=... 做事务级调整,不要为消除临时文件无上限提高全局值;
- 大查询设置合理 temp_file_limit 与 statement_timeout(本次用 512MB / 60s),用 EXPLAIN (ANALYZE, BUFFERS) 观察 Batches / Memory Usage / Disk Usage,用 log_temp_files 记录证据;
- 监控应同时覆盖 KingbaseES 日志中的 upper limit / out of memory / temporary file,以及 OS 的可用内存、Swap、磁盘使用率和 OOM Killer 事件;
- 本次将 max_dynamic_memory 设置为 64MB 仅用于验证内存保护机制,并非生产推荐配置,测试完成后参数已恢复默认无限制状态;
四、实测三:在线转集群与多模式备份(可行性验证)
(一)不停机转集群能力确认
随安装介质附带的《KingbaseES 读写分离集群使用手册》明确支持 cluster_install.sh convert 两阶段转换:
-
配置 use_exist_data=1、当前 data、当前节点、运行中的超级用户/密码/端口/兼容模式以及完全同版的 zip_package;
-
以数据库运行用户执行:
bash./cluster_install.sh convert -
单机实例转为单节点集群形态后,再在线扩容接入第二台服务器,构建一主一备读写分离集群。
convert 条件逐项核对:
|-----------------------------------------------------------------------------------------------------------------------|-----------------------------|----|
| 官方条件 | 当前实测 | 判定 |
| use_exist_data=1,数据库运行中 | 运行中 | 满足 |
| zip_package 与运行实例版本完全一致 | 运行 PS003;已获取完整同版本安装包 | 满足 |
| all_ip 仅配置当前数据节点 | 可配置 192.168.x.195 | 可行 |
| 超级用户/密码/端口/兼容模式 | system/密码/54331/oracle | 可行 |
| hot_standby=on | on | 满足 |
| wal_level>=replica | replica | 满足 |
| 预加载 repmgr | 已在 shared_preload_libraries | 满足 |
| max_connections/max_wal_senders/max_replication_slots > 5 | 100/10/10 | 满足 |
| 不存在 .nodes.info | 未发现 | 满足 |
| 不存在 esrep 数据库/用户 | 查询为空 | 满足 |
| convert 执行用户与数据库运行用户一致 | kingbase 运行 | 满足 |
(二)四种物理备份能力均具备
sys_rman/sys_backup.sh 已安装,版本 V009R002C016PS003。
统一命令形态:
bash
/opt/Kingbase/ES/V9R2C16/Server/bin/sys_rman \
--config=<REPO>/sys_rman.conf --stanza=<名称> \
--archive-copy --type=<full|diff|incr|page> backup
|-----|-------------|-----------------|---------------------|
| 类型 | 参数 | 依赖 | 粒度 |
| 全量 | --type=full | 无 | 所有数据文件 |
| 差异 | --type=diff | 最近一次全量 | 自全量以来变化的数据文件 |
| 增量 | --type=incr | 前一个备份集 | 自前一个备份以来变化的数据文件 |
| 块增量 | --type=page | 前一个全量/差异/增量/块增量 | 只复制变化的数据块(需 ktrack) |
块增量备份依赖 ktrack 模块,模块加入预加载库后,开启 ktrack.enable=1;修改 ktrack.map_size 需重启实例。模块启用后,需要重新执行一次全量备份。
(三)COW 写时复制备份
COW 前置条件已满足:根文件系统为 XFS 且 reflink=1、内核 4.18.0-553(符合 Linux≥4.5 要求)。初始化配置:
bash
reflink=y(sys_rman 配置项)
单次命令示例:
bash
sys_rman --config=<REPO>/sys_rman.conf --stanza=<名称> \
--reflink=y --type=diff backup
开启后,非全量备份集可独立使用,未变更的数据文件通过 reflink 共享底层存储块;sys_rman 会自动探测,不支持时自动回退传统复制。应通过备份日志和 sys_rman info 确认实际启用,不能只看配置值。
(四)建议的安全实验步骤
先做备份实验再做转集群,每步后执行 sys_rman info、校验日志并做测试还原。
- 准备条件:新增至少一台与 192.168.x.195 网络互通的 Rocky Linux 8 服务器(时间差<2s,UID/GID 一致);获取厂商认可的、与 PS003 完全一致的完整 Server TAR;由厂商/授权工具确认 RWC、RepmgrTool、OneStepClusterOperator、KConsole 集群功能许可;新增独立备份卷或外部 REPO(建议实验卷≥20 GiB);转换前做一份可还原验证的全量备份,并导出原始 kingbase.conf、sys_hba.conf、systemd 单元和授权文件。
- 备份实验 :独立 REPO 上配置 sys_backup.conf(IP 192.168.x.195、端口 54331、用户 system、独立 _repo_path,先设 _reflink=n、_incr_type=file)→sys_backup.sh init 会自动修改 WAL 归档配置并执行首次全量备份,属于会变更实例配置的操作,变更前务必备份原有配置文件→ 依次执行 full/diff/incr 并记录 → 测试库安装启用 ktrack 后做 page 块增量 → _reflink=y 验证 COW 实际生效 → 每种模式至少完成一次还原到独立测试目录的演练。
- 转集群实验 :在克隆/专用实验环境准备一致数据、版本、授权 → 模板填写 install.conf(all_ip 仅 192.168.x.195,use_exist_data=1、54331、oracle、运行用户、同版 zip_package)→ 预检主机/授权/端口/SSH 互信 → 以 kingbase 执行 cluster_install.sh convert,核对数据库持续可连接、.nodes.info、esrep、repmgrd/kbha、repmgr cluster show → 在线扩容第二台,验证流复制、只读查询、VIP、主备切换与故障恢复 → 转换后取消原单机 sys_rman 定时任务,以整个集群重新 sys_backup.sh init。
五、实测四:坏块检测与 sys_repair 修复
(一)实验设计
在完全隔离的主备实验环境(独立 initdb 实例 + Linux 网络命名空间),对一张 400 行测试表的第 100 号数据页只改写页头 2 字节校验和制造故障,完整走通 "发现→保护→修复→刷盘→重启验证" 全流程。
|-------|-------------------------------------------------------------------|
| 项目 | 实测值 |
| 实验主库 | /opt/Kingbase/ES/V9R2C16/lab_sysrepair_data(10.200.x.1:54332) |
| 实验备库 | /opt/Kingbase/ES/V9R2C16/lab_sysrepair_standby2(10.200.x.2:54332) |
| 数据校验和 | on(initdb -k 创建),块大小 8192 字节 |
| 故障对象 | repair_lab 第 100 号数据页,file path base/15693/16402 |
故障仅注入停机状态下的实验主库文件,正式业务实例 54331 及其他原有实例(54321--54330)不受任何影响。
(二)准备 sys_repair 实验实例
bash
/opt/Kingbase/ES/V9R2C16/Server/bin/initdb \
-D /opt/Kingbase/ES/V9R2C16/lab_sysrepair_data \
-U system -E UTF8 --locale=C \
--auth-local=trust --auth-host=scram-sha-256 \
--pwfile=/home/kingbase/lab_sysrepair.pw -k
输出:Data page checksums are enabled.。sys_repair 需加入 shared_preload_libraries 后重启,再:
bash
CREATE EXTENSION sys_repair;
核心接口:verify_table(regclass) / verify_database() 返回 bool;bad_block_info() 返回 setof record(本版本 8 列);clear_bad_block_info();get_health_row(regclass);repair_page(spc, db, relfile, relOid, blockNum)。
(三)建立实验数据和基线
sql
CREATE TABLE repair_lab(id integer PRIMARY KEY, payload varchar2(7000), row_hash varchar2(32));
ALTER TABLE repair_lab ALTER COLUMN payload SET STORAGE PLAIN;
INSERT INTO repair_lab
SELECT g, (SELECT string_agg(md5((g*1000+s)::text),'') FROM generate_series(1,215) s),
md5(g::text) FROM generate_series(1,400) g;
CREATE TABLE repair_lab_baseline AS SELECT * FROM repair_lab;
CHECKPOINT;
对象定位:table oid=16386、relfilenode=16402、database oid=15693、tablespace oid=1663、file path=base/15693/16402、table size=3200 kB。第 100 号块中的行:id=101, ctid=(100,1), row_hash=38b3eff8...。故障前 verify_table=t、bad_block_info() 为空。
(四)建立健康页来源(物理备库)
bash
/opt/Kingbase/ES/V9R2C16/Server/bin/sys_basebackup \
-D /opt/Kingbase/ES/V9R2C16/lab_sysrepair_standby2 \
-R -X stream -h 10.200.1.1 -p 54332 -U system -P -v
备库复核:sys_is_in_recovery=t、verify_table=t、rows=400、id 101=present。仅在备库处于恢复状态、复制正常且目标表健康时,才把它作为修复页来源。
(五)离线注入页校验和故障
sql
/opt/Kingbase/ES/V9R2C16/Server/bin/sys_ctl stop -D /opt/Kingbase/ES/V9R2C16/lab_sysrepair_data -m fast -w
# 第 100 号页偏移 8 字节处校验和改为 0xFFFF,偏移 = 100*8192+8 = 819208
bash
printf '\377\377' | dd \
of=/opt/Kingbase/ES/V9R2C16/lab_sysrepair_data/base/15693/16402 \
bs=1 seek=819208 count=2 conv=notrunc,fsync status=none
文件 SHA256 由 ebf2a1ab... 变为 18d152db...。重启后扫描:verify_table=f、verify_database=f,bad_block_info() 定位到 base/15693/16402 第 100 号块(repair_time=NULL)。
(六)先保护健康数据
sql
DROP TABLE IF EXISTS repair_lab_healthy_backup;
CREATE TABLE repair_lab_healthy_backup AS
SELECT * FROM get_health_row('repair_lab'::regclass)
AS t(id integer, payload varchar2(7000), row_hash varchar2(32));
结果:healthy_rows=399(所有可正常读取的数据行),损坏页内 id=101 行无法读取,该数据需要从健康备库获取------保护了所有可读行,损坏页中的 id=101 仍只能从健康备库取回。
(七)修复连接参数排错
第一次误用普通连接串(host=... port=... dbname=... user=...)报 Connect to remote node failed / fe_sendauth: no password supplied。正确格式是简单的 IP:端口:
sql
ALTER SYSTEM SET sys_repair.sys_repair_conninfo='10.200.x.2:54332';
SELECT sys_reload_conf();
生产环境使用密码认证时,数据库服务进程必须能访问密码文件,建议为 systemd 服务设置 KINGBASE_PASSFILE=/path/to/db.pass,密码文件归数据库运行用户所有、权限 600。仅在交互终端导出变量不能保证服务进程继承。
(八)执行页修复
sql
SELECT repair_page (1663::oid, 15693::oid, 16402::oid, 16386::oid, 100);
日志输出:
bash
WARNING: Page is invalid: base/15693/16402, blockNum: 100
WARNING: Repair invalid page:base/15693/16402, blockNum: 100 successfully.
坏块记录写入 repair_time=2026-10-12 09:31:36。修复后业务查询可正常读取数据,但此时数据仅在内存缓冲区,需执行检查点落盘后,再执行表校验才能得到持久化后的真实结果。
(九)检查点与重启验证
bash
CHECKPOINT;
SELECT verify_table('repair_lab'::regclass);
SELECT verify_database();
检查点后:table_after_checkpoint=t、database_after_checkpoint=t、rows=400、mismatches_vs_baseline=0。随后重启实验主库再验证:table_after_restart=t、database_after_restart=t、rows=400、mismatches_vs_baseline=0。
判定修复成功不能仅依赖 repair_page 执行返回结果或者单次 count ()查询结果,至少应同时核对成功日志、repair_time、CHECKPOINT 后的表级/库级扫描、完整数据比较和重启后的复扫。
(十)实验收尾
停止主备实验实例、删除临时网络命名空间 kb_repair_ns 及 veth 接口、保留实验数据目录与故障前页文件。最终状态:kingbase-v9r2c16.service=active/enabled、正式 listener 0.0.0.0:54331、实验 listener 54332 已停止。
(十一)生产使用建议
- sys_repair 依托有效的页数据源(健康备库 / 备份页 / WAL)完成数据修复,不支持凭空生成缺失数据;
- 修复前先做冷备/快照,并用 get_health_row() 保护所有可读数据;
- 每次重启后应重新扫描登记坏块(坏块信息保存在内存共享区,数据库重启后会清空,重启后需重新扫描识别坏块);
- relfilenode、关系 OID、数据库 OID、表空间 OID、块号必须逐项从当前环境查询;
- 修复后必须执行CHECKPOINT,再做表级、库级扫描和完整数据比较;
- 生产环境不要用 trust 认证,应使用最小网段 + SCRAM 密码 + 600 权限密码文件;
- sys_repair 依赖健康数据源(备库 / 备份 / WAL);若无可用健康数据源,请保留故障原始文件,优先评估备份恢复方案或联系厂商获取技术支持,不要直接覆盖数据文件;
六、总结
KingbaseES V9R2C16(PS003)在本次实测中展现出扎实的国产数据库硬实力:
- 64位事务ID 从类型、取值、接口到控制文件全链路升级,冻结参数 int64 化彻底消除 20 亿天花板,长期运行余量提升 50 倍;
- 实例级动态内存管控提供可控内存保护能力,配合 work_mem 落盘机制,复杂大查询聚合可实现防护与正常执行;
- 在线转集群与多模式备份 能力完备(全量/差异/增量/块增量 + COW);
- 坏块检测与 sys_repair 修复 走通了"发现---保护---修复---刷盘---重启复核"完整故障处置闭环,结果与基线零差异。
电科金仓KingbaseES在事务可靠性、内存安全、高可用与故障自愈能力上表现均衡,为 PostgreSQL/Oracle 国产化替代提供了可信的落地选项。