暂无图片
暂无图片
4
暂无图片
暂无图片
暂无图片

Kingbase 三种兼容模式运维对比

背景

交付现场最常被问到的一句话:Kingbase 开了 Oracle、MySQL、SQL Server 兼容,运维是不是也得拆成三套手册?

业务和开发更关注 SQL 兼容性,比如该用 nvl 还是 ifnull,分页写 TOP 还是 LIMIT,空串和 NULL 怎么处理。DBA 关心的则是另一件事:Oracle、MySQL、SQL Server 三种兼容模式,日常运维到底是不是三套东西。

如果启停、配置、权限、备份都能共用一套方法,后续写运维手册、做交接、处理故障都会简单很多。

所以这次专门搭了三套实例,把常见运维操作逐项跑了一遍。

结果比较明确:三种兼容模式主要差在初始化和 SQL 兼容层,到了 DBA 日常运维这一层,很多东西其实是共通的。

下面直接看实测。

实验环境

代号 兼容模式 主机 端口 版本 系统用户 数据目录
O oracle 161.118.XXX.XXX 54322 V009R002C014 kingbaseo /opt/kingbaseo/data
M mysql 161.118.XXX.XXX 54323 V009R003C018 kingbasemy /opt/kingbasemy/data
S sqlserver 213.35.XXX.XXX 54321 V009R004C019 kingbase /opt/kingbase/data

三端超级用户都是 system,测试库都是 test。

这里三个实例的版本号本身就不同。V009 后面的 R 段用于区分兼容版本:R002 对应 oracle,R003 对应 mysql,R004 对应 sqlserver。也就是说,这批产品是通过不同发行版来区分兼容模式的,安装时选了哪个 ISO,基本就确定了后面的模式。

因此本文比较的是日常运维接口是否一致,不是说三个版本内部行为完全相同。后面如果涉及升级、补丁或者版本变更,仍然需要分别验证。

先确认一下实际模式,避免后面测试时把环境搞混:

模式 version database_mode port
oracle KingbaseES V009R002C014 oracle 54322
mysql KingbaseES V009R003C018 mysql 54323
sqlserver KingbaseES V009R004C019 sqlserver 54321

version 可以看版本,database_mode 用来确认当前兼容模式。两个信息都确认无误后再继续测试。

共性一:启停入口相同

三端命令形态一模一样:

sys_ctl -D <DATA> status sys_ctl -D <DATA> stop -m fast sys_ctl -D <DATA> -l <logfile> start

实测:

模式 status stop start
oracle running → PID 明确 done started
mysql running → PID 明确 done started
sqlserver running → PID 明确 done started

实测下来,三种模式的启停方式没有区别,统一使用 sys_ctl。兼容模式主要影响 SQL 兼容层,并不会改变实例进程的基本管理方式。

多实例部署时要特别注意 -D 后面的数据目录。Linux主机1 上 oracle 和 mysql 两个实例放在同一台机器,如果数据目录写错,实际操作的就会是另一个实例。

实际写脚本时建议把 DATA 目录做成变量或配置项,不要每次手工输入。

所以在运维手册里,启停部分完全可以统一写,不需要按兼容模式拆成三套。

共性二:配置与访问控制同源

三端都是这两个文件在管事:

  • kingbase.conf:端口、监听、连接数、shared_buffers、日志
  • sys_hba.conf:客户端认证

关键行抽出来对了一遍,结构完全一致:

参数 oracle mysql sqlserver
listen_addresses * * *
port 54322 54323 54321
max_connections 100 100 100
shared_buffers 128MB 128MB 128MB
logging_collector on on on

表里的端口不同只是实验环境安排,并不是兼容模式造成的差异。三个版本默认端口都是 54321。sqlserver 实例单独放在一台机器上,所以保留默认端口;oracle 和 mysql 共用 Linux主机1,为了避免端口冲突,分别改成了 54322 和 54323。

参数生效方式也基本一致。比如三端的 max_connections 修改后都需要重启实例,单纯执行 reload 并不会生效。

所以改参数前最好先确认参数的 context,可以通过 SHOW 或 pg_settings 查看。sys_ctl reload 只适用于支持热加载的参数,需要 restart 的参数三种模式处理方式相同。

认证部分三端也一致,都是通过 sys_hba.conf 配置 local / host 规则。实验环境如果需要临时开放外网,可以增加对应的 host 规则。

不过生产环境不建议直接使用 0.0.0.0/0 + md5 这种配置,至少要限制来源网段,并结合更安全的认证方式和主机防火墙。

共性三:账号与只读权限一套脚本

三端都是 ROLE/USER + GRANT 那套权限模型,只读账号可以共用一份骨架:

  1. CREATE ROLE … LOGIN PASSWORD …
  2. GRANT CONNECT ON DATABASE
  3. GRANT USAGE ON SCHEMA public
  4. GRANT SELECT ON 表
  5. REVOKE INSERT/UPDATE/DELETE
  6. REVOKE CREATE ON SCHEMA public(含 PUBLIC)

拿一张 ops_demo 样例表验证,三端各塞 3 行数据,然后用只读账号去撞权限边界:

模式 只读 SELECT INSERT 拒绝 CREATE TABLE 拒绝
oracle count=3 permission denied for table permission denied for schema public
mysql count=3 permission denied for table permission denied for schema public
sqlserver count=3 permission denied for table 需先 REVOKE CREATE FROM PUBLIC,否则默认能建表

这里 sqlserver 兼容实例和另外两个有一个细节差异:新建只读用户之后,用户仍然可以在 public schema 下执行 CREATE TABLE。

原因是 PUBLIC 默认拥有 public schema 的 CREATE 权限。只对新建用户做 REVOKE 并不够,还需要检查 PUBLIC 本身的权限。

从安全基线角度看,三种模式都建议显式检查并收紧 public schema 的 CREATE 权限。sqlserver 兼容版在本次测试环境里尤其需要补上:

REVOKE CREATE ON SCHEMA public FROM PUBLIC;

在 SQL 里直接写一个固定日期,三端的写法也不一样:

  • oracle / mysql:DATE ‘2024-01-01’ 直接可用
  • sqlserver:本次环境用 CAST(‘2024-01-01’ AS date) 更稳

这个差异属于 SQL 兼容层,不影响权限模型。但如果迁移脚本里直接复用 Oracle/MySQL 的日期写法,在 sqlserver 兼容实例上就可能报错,需要单独处理。

共性四:逻辑备份恢复同源

逻辑备份方面,三端使用的命令和参数形式一致:

export KINGBASE_PASSWORD=... sys_dump -h 127.0.0.1 -p <PORT> -U system -d test \ -t ops_demo -f /tmp/ops_demo_<mode>.sql ksql ... -c "DROP TABLE ops_demo;" ksql ... -f /tmp/ops_demo_<mode>.sql

先 dump 出来,再手动 DROP 掉原表,然后从 dump 文件恢复,数一下行数对不对得上:

模式 dump 文件 restore 后 count(*)
oracle /tmp/ops_demo_oracle.sql 3
mysql /tmp/ops_demo_mysql.sql 3
sqlserver /tmp/ops_demo_sqlserver.sql 3

三套实例恢复后都是 3 行,说明这组基础逻辑备份恢复操作在三种模式下可以直接复用。

实际做备份脚本时,可以把 HOST、PORT、USER、PASSWORD、DATA 等信息做成参数表,然后用同一套脚本处理不同实例,没有必要为三种兼容模式各维护一份。

这里验证的只是逻辑备份和恢复流程可以跑通,并不代表生产备份方案就只需要 sys_dump。

生产环境仍然要考虑物理备份、归档、PITR 和恢复演练。逻辑备份更适合小表、临时导出或跨版本数据迁移,不能替代完整的灾备方案。

共性五:观测手段一致

执行计划也用同一条 SQL 做了验证:

EXPLAIN (ANALYZE, BUFFERS) SELECT id, name, amt FROM ops_demo WHERE id = 1;

三端都能正常返回 Planning Time、Execution Time 和 Buffers,执行计划结构也一致。对 DBA 来说,平时分析 SQL 的方式并不会因为兼容模式不同而改变。

pg_stat_activity 在三种模式下都可以使用,日志也都位于 data/sys_log 目录,按 kingbase-YYYY-MM-DD_*.log 的形式滚动。

因此常规排障时,查看会话、执行计划和日志的路径基本一致。

排障动线可以固化成一条:

  1. sys_ctl status —— 先确认进程活着
  2. EXPLAIN (ANALYZE, BUFFERS) —— 慢就看计划
  3. 翻 sys_log —— 报错和异常留痕在这
  4. 查会话视图 —— 锁等待、长事务、活动连接一眼看清

这套排障顺序三种模式都可以直接使用。

边界:SQL 语法不同,mode 不能热切换

不过,运维方式接近,并不代表 SQL 兼容性也完全一样。下面是本次抽查的一些函数和语法差异:

检查项 oracle mysql sqlserver
dual
nvl(NULL,1) 1 1 无此函数
ifnull(NULL,1) 1 1 无此函数
isnull(NULL,1) 1 语法失败 1
if(1=1,‘Y’,‘N’) Y Y 语法失败
TOP 1 可用 可用 可用
LIMIT 1 可用 可用 可用
getdate()

分页语法相对宽松,TOP 和 LIMIT 在三端都可以使用。但函数差异仍然比较明显,比如 nvl、isnull、getdate 等,还是带有各自兼容模式的特征。

从这组测试可以得到几个比较实用的结论:

  1. 兼容模式在初始化阶段确定。 本次使用的 ISO 中,sqlserver 版默认就是 sqlserver 模式,mysql 版只支持 mysql。database_mode 不是一个可以在运行期随意切换的参数。
  2. 多模式并存要按多个实例来部署。 比较稳妥的做法就是不同 OS 用户、不同安装/数据目录、不同端口。
  3. 应用兼容和 DBA 运维要分开看。 SQL 函数、语法、驱动等需要按模式单独测试;启停、备份、权限、日志这些日常运维内容则可以大量复用。

一张图说清分工

693EB5E0-BDA7-4662-8B1B-5DC86CF80557

简单来说,兼容模式的主要分叉点出现在初始化和 SQL 兼容层;实例建立之后,DBA 日常操作的共性要明显更多。

统一运维 Checklist

如果要整理成现场运维 checklist,可以压缩成下面几条:

  1. 一实例一系统用户、一数据目录、一端口,别混
  2. 启停只认 sys_ctl -D,路径抽成变量,杜绝手打
  3. 参数改 kingbase.conf 或等价入口,先看 context 再决定 reload 还是 restart
  4. 访问控制改 sys_hba,外网开放单独评估,别拿实验环境的 0.0.0.0/0 上生产
  5. 业务账号给最小权限;只读账号只 SELECT,并显式收紧 public 的 CREATE
  6. 逻辑备份日备 sys_dump,物理备份 + PITR 另立方案,恢复演练定期真拉一次
  7. 故障动线:status → EXPLAIN → sys_log → 会话视图
  8. 要上新模式,老老实实重新 initdb,别幻想热切 database_mode

总结

两台 Linux主机、三种兼容模式跑下来,结论收敛成一张表:

维度 结论
启停 相同
配置文件 相同
账号权限 骨架相同,注意 public 默认权
逻辑备份 相同
计划与日志 相同
SQL 语法与函数 不同
mode 切换 初始化定型,改不了

如果只看这次实测,三种兼容模式最大的差异还是集中在 SQL 兼容性,而不是日常运维。

对于交付和运维团队来说,启停、配置、账号权限、逻辑备份、执行计划和日志排查这些内容,完全可以先整理成一套统一模板,再把不同实例的端口、目录、版本等信息参数化。真正需要按模式单独验证的,主要还是 SQL、函数、驱动以及应用侧兼容性。

后面做版本升级、参数调整或者批量迁移时,也建议把这份 checklist 在各模式实例上重新跑一遍。相比凭经验判断,实测结果更可靠。

附录:连接速查

# Oracle export KINGBASE_PASSWORD=... ksql -h 161.118.XXX.XXX -p 54322 -U system -d test # MySQL ksql -h 161.118.XXX.XXX -p 54323 -U system -d test # SQL Server ksql -h 213.35.XXX.XXX -p 54321 -U system -d test
# 通用启停 sys_ctl -D <DATA> status sys_ctl -D <DATA> stop -m fast sys_ctl -D <DATA> -l <LOG> start
# 通用表备份 sys_dump -h 127.0.0.1 -p <PORT> -U system -d test -t ops_demo -f ops_demo.sql
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论