最近在带OceanBase集群运维,总有同事拿着MySQL的使用习惯来问我:“OceanBase的my.cnf在哪个目录?”每次我都要先纠正一下:OceanBase没有一份像MySQL那样的全局配置文件,它把“配置”拆成了启动配置和系统配置项两条线。尤其是刚接触赵渝强老师那套OceanBase课程的同学,在这块经常绕晕:一会儿看到 observer.config.bin,一会儿看到 ALTER SYSTEM SET,还有OBD的 config.yaml,到底该改哪个、什么时候生效?
这篇文章就把OceanBase的配置文件到底有哪几层、配置项怎么查询和修改、哪些坑不能踩一次说清楚。文章节奏偏运维实操,也顺带照顾要考OceanBase认证或者准备面试的同学,看完你就能自己登录集群,把配置问题排查明白。
1. 先分清三件事:启动参数、配置文件与配置项
1.1 OceanBase没有my.cnf,但配置文件并不少
MySQL的配置管理很直接,一个my.cnf写死一大堆参数,启动时全量加载。OceanBase是分布式架构,一台observer要加入集群、参与选举、同步内部表,如果还靠每台机器一份散落的配置文件去维持一致,很容易出现A机器改了一个参数、B机器没改的情况。
所以OceanBase把“配置”拆成了两层:
- 安装部署层:负责告诉observer进程“你是谁的副本、数据放哪里、监听哪个端口、内存给多大”。这些是进程启动前就要确定的,属于启动参数或部署配置文件。
- 集群运行层:集群起来之后,可以在线管理的系统参数,比如查询超时时间、是否开启回收站、SQL审计开关。这些参数统一存在集群内部表里,通过SQL语句修改,不依赖某台机器的文本文件。
这套结构有点像一个公司:启动配置文件相当于新员工的入职档案,进去之前就定好部门、工位、工资;系统配置项则像公司日常制度,由管理层开会决定后全员同步,改完马上执行,不用把每个员工单独叫去改档案。
搞清楚这个底层区别,后面所有操作就不会乱。
1.2 配置项的三要素:作用范围、生效方式、值类型
看OceanBase的配置项,我习惯先抓住三个核心属性。
第一是作用范围。配置项分成集群级和租户级。memory_limit、system_memory 这些是整套集群物理资源维度,必须由系统租户(sys)来设置;而 ob_query_timeout、undo_retention 这类租户行为参数,可以在租户内设置,也可以由系统租户指定某个租户来设置。
第二是生效方式。配置项在官方文档里会标明 Dynamic effective 还是 Static effective。动态生效的改动,执行完立刻作用于运行中的进程,不用重启;静态生效的改动,必须重启observer进程才真正落到运行环境。最容易踩坑的就是把静态配置项当成my.cnf参数,以为改完配置就算done,结果业务高峰根本没有变化。
第三是值类型。执行 SHOW PARAMETERS LIKE 能看到 data_type 字段,常见的有 STRING、INT、BOOL、CAPACITY、TIME 等。注意很多配置项的单位是一个带单位的字符串,比如 "100G"、"120s"、"100ms",不能只传数字,否则执行可能报错或不生效,这个我们后面专门说。
1.3 为什么分布式数据库要把配置项集中管理
单机数据库改配置,改完重启一次就行。OceanBase有三台、五台甚至更多observer,如果靠手工去每台节点改本地文件,且不说效率,单是“一致性”就没办法保证。配置项集中到内部表后,系统的rootservice会通过内部通信把变更广播到所有节点,并且持久化,这样就不会出现“部分节点配置不同”的脑裂状态。
另一个更深层的理由是,OceanBase的很多配置在设计上要支持在线调优。比如某业务租户大查询把资源占满了,你希望临时调低该租户的并发重试阈值,这种操作在运行中直接执行 ALTER SYSTEM SET 就能完成,不需要停机窗口。这也是OceanBase适合做金融级核心系统替换的原因之一。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 部署层面:OBD配置文件与手工启动的参数传递
2.1 用OBD部署,真正的配置文件是config.yaml
现在绝大多数场景学习、生产测试都用OBD部署。你执行 obd cluster edit-config <集群名> 打开的那个文件,就是OBD集群配置文件,默认存放在部署用户的家目录下,例如 /home/admin/.obd/cluster/<集群名>/config.yaml。
一个典型的片段长这样:
yaml复制oceanbase-ce:
servers:
- 192.168.1.10
- 192.168.1.11
- 192.168.1.12
global:
devname: eth0
cluster_id: 1
memory_limit: 64G
system_memory: 10G
datafile_size: 100G
log_disk_size: 80G
cpu_count: 16
server:
- 192.168.1.10:
mysql_port: 2881
rpc_port: 2882
home_path: /home/admin/oceanbase
- 192.168.1.11:
mysql_port: 2881
rpc_port: 2882
- 192.168.1.12:
mysql_port: 2881
rpc_port: 2882
这里的 global 段下面的键值,会由OBD转换成observer进程启动时需要的启动参数,逐个传给节点。注意 server 段依然可以针对单机覆盖部分参数,这种“global + 单机覆盖”的设计,让混合规格机型的部署变得容易。
config.yaml 只解决“启动参数从哪来”。如果你只是改了 config.yaml 里的一个键,动态参数也许不会自动应用到运行中的进程。这也是新手最常踩的坑:改完文件没有重启,或者执行了 obd cluster reload 后想当然以为全部生效。实际上,配置变更中如果涉及 system_memory、memory_limit、datafile_size 这类静态项,OBD会提示你执行 obd cluster restart 才能完成最终生效。
2.2 手动部署时,observer命令行的-o参数是什么
如果不用OBD,而是手工方式启动observer,命令通常长这样:
bash复制/home/admin/oceanbase/bin/observer \
-i eth0 \
-P 2882 \
-p 2881 \
-z zone1 \
-n obcluster \
-c 1 \
-d /home/admin/oceanbase/store \
-l WARN \
-o "system_memory=30G,memory_limit=80G,cpu_count=16,datafile_size=200G"
拆开看:-i 指定网卡名,-P 是RPC通信端口,-p 是MySQL协议端口,-z 指定所属zone,-n 是集群名,-c 是集群ID,-d 是数据目录,-l 是启动日志级别。最后的 -o 比较特殊,它后面跟了一长串 key=value 且用英文逗号隔开的参数,这些才是我们日常调优最关心的资源参数。
这里给第一次手工部署的同学提个醒:那些 -o 里带的参数会持久化到observer所在目录的配置文件 etc/observer.config.bin。这个文件在OceanBase 3.x时代比较常见,4.x用OBD之后普通用户接触少了。它是二进制格式,不是给人直接用vim编辑的文本。你拿 cat 去看会看到乱码,用 strings 能捞出明文参数。千万不要手工去改这个二进制文件,改坏了observer可能起不来。正确的姿势是:要么启动命令用 -o 重新传参,要么用OBD统一管理。
2.3 配置文件、参数与运行期的耦合关系要心里有数
我在真实环境里见过一个让人头大的问题:集群刚部署完,DBA通过 ALTER SYSTEM SET 把某个租户参数在线调低了,运行一个多月一直正常。后来某天机房切换重启了observer,参数又变回了原来的默认值,业务超时告警一片。为什么?因为重启时observer会重新加载启动配置文件里的值,把之前在运行期用 ALTER SYSTEM SET 改掉的值覆盖掉。
这个案例给我最大的教训是:任何通过SQL在线修改的配置项,只要不是想永久生效,都要同步评估是否要固化到OBD配置或启动参数中,否则一次重启就全部回退。 反过来也一样,动态参数如果希望长期保持某个值,最稳妥的做法是同时改两处:先用 ALTER SYSTEM SET 让运行中的进程立刻调整,再改OBD的 config.yaml 或启动参数,保证重启之后依然延续。
3. 运行时配置项:查询、修改、恢复的标准姿势
3.1 查看配置项,别只会到处翻日志
查看配置项最常用的是SQL命令 SHOW PARAMETERS,在系统租户里可以看集群全局,在业务租户里只能看到本租户范围内的内容。
sql复制SHOW PARAMETERS LIKE 'memory_limit';
也可以加通配符模糊匹配:
sql复制SHOW PARAMETERS LIKE '%cpu%';
看到的结果表包含很多列,挑几个关键的说:
svr_ip、svr_port:配置项所在节点,全集群每个节点都会有自己一行记录。zone:所属的zone。name、data_type、value:配置项名、类型和值。info:配置项说明。section:所属分类,像SSTABLE、LOG、ROOTSERVICE等。scope:适用范围,比如CLUSTER表示集群级,TENANT表示租户级。edit_level:这点尤其重要,字符串是DYNAMIC_EFFECTIVE就是动态生效,STATIC_EFFECTIVE是静态生效需要重启。
新版OceanBase还推荐查视图 oceanbase.GV$OB_PARAMETERS,执行效果类似:
sql复制SELECT svr_ip, svr_port, name, value, edit_level
FROM oceanbase.GV$OB_PARAMETERS
WHERE name IN ('memory_limit', 'system_memory');
3.2 ALTER SYSTEM SET语法与作用范围控制
修改配置项的核心命令是 ALTER SYSTEM SET,大致的格式如下:
sql复制ALTER SYSTEM SET parameter_name = 'value'
[SCOPE = MEMORY | SPFILE | BOTH]
[SERVER = 'ip:port' | ZONE = 'zone_name' | TENANT = 'tenant_name']
[COMMENT '描述信息'];
注意两点,缺一不可。
第一,值要用单引号包起来。MySQL里很多不是字符串的参数可以直接写裸值,OceanBase这里经常需要用 '120s' 之类的字符串写法,不写引号很容易报语法错误。
第二,作用范围要拎清。默认不加 SERVER、ZONE 时修改的是整个集群的所有observer;如果只改某台节点,可以用 SERVER;如果只想改某个zone,可以用 ZONE。租户级配置则用 TENANT 指定租户名,或先登录对应租户再执行。
举例,系统租户下修改某业务租户的空闲事务超时时间:
sql复制ALTER SYSTEM SET ob_trx_idle_timeout = '120s' TENANT = 'mysql001';
修改某个zone的大查询阈值:
sql复制ALTER SYSTEM SET large_query_threshold = '80ms' ZONE = 'zone1';
修改集群内所有节点的系统内存,因为 system_memory 是静态生效,所以执行成功后需要重启才真正生效:
sql复制ALTER SYSTEM SET system_memory = '32G' SCOPE = BOTH;
这里的 SCOPE = BOTH 含义是把新值同时写入内存和持久化配置,保证重启后依然保留。默认就是BOTH,所以大多数时候可以不写。如果你只希望临时改一下内存、重启后回退,可以用 SCOPE = MEMORY。
3.3 验证变更与重置默认值
执行 ALTER SYSTEM SET 成功不代表配置已经生效生效,第一步先查询确认:
sql复制SHOW PARAMETERS LIKE 'ob_trx_idle_timeout';
有经验的DBA会同时对比svr_ip各节点的value是否一致。集群规模大时,心跳同步可能有几秒延迟,刚执行完立刻查,个别observer节点显示旧值是正常的,等几秒再刷一次,基本能收敛。如果长时间不一致,要排查是否有observer宕机或网络分区,这个后面我们放到排查部分讲。
想要把某个配置项恢复成默认值,可以用 ALTER SYSTEM RESET:
sql复制ALTER SYSTEM RESET ob_trx_idle_timeout TENANT = 'mysql001';
如果没有 RESET 权限或版本不支持,最直接的办法是把原始默认值查询出来,手动 SET 回去。所以任何配置变更之前,先把当前值记录下来,这是运维的基本素养。
4. 常用配置项盘点与生产调整经验
4.1 资源与存储类:内存、数据文件、日志盘
OceanBase对内存的管理和传统数据库有区别,observer进程能用的总内存由 memory_limit 控制。在这个总池子里,又单独划分了一块 system_memory 给内部功能模块、元数据、请求处理等系统使用。这两个参数配合得好不好,直接决定集群稳定性。
经验上,如果一台机器内存是128G,常见的保守配法是:
memory_limit设置为总内存的70%-80%左右,比如96G,给OS、OBServer之外的其他进程留出余量。system_memory一般设置为总内存的10%-20%,至少不低于8G,如果租户数量多、转储频繁,可以适当调大。datafile_size决定数据文件初始大小,生产环境通常按磁盘可用空间和使用规划分配,避免datafile_size设得太小而频繁扩容,也不要超过真实磁盘容量。
日志方面重点看 log_disk_size,它控制clog日志盘空间上限,太小会导致日志快速积压后写入暂停。生产环境通常给到内存池的1倍或更大。这几个参数都属于 STATIC_EFFECTIVE,调整后务必规划重启窗口。
4.2 SQL执行与租户行为类:超时控制是关键
线上环境最频繁收到业务方吐槽的,莫过于“查询超时”“事务超时”。OceanBase几个常用参数常常被提起:
ob_query_timeout:普通查询超时时间。ob_trx_timeout:事务整体超时时间。ob_trx_idle_timeout:事务空闲超时,即事务开了但没有后续动作,超过后自动回滚或异常。large_query_threshold:大查询判定阈值,超过该时间的SQL会被认为是大查询,可能走不同的队列策略。
比如某业务存在大量报表分析SQL,平均要跑三五秒,系统默认的1s超时显然扛不住,可以在租户内执行:
sql复制ALTER SYSTEM SET ob_query_timeout = '10s';
这里要提醒一句:超时时间不是越长越好。把全局 ob_query_timeout 拉到很长,虽然业务不报错了,但慢SQL会把CPU、IO资源耗尽。更合理的做法是保留合适的全局超时,对特殊场景用SQL级hint或者单独限流方案解决。我见过一个环境为省事把 ob_query_timeout 改成 300s,结果一次全表扫描把租户资源打满,其他正常查询全部排队,教训很深刻。
4.3 日志、回收站与可观测类参数
除了资源和超时,日常运维还会用到日志级别、回收站、SQL审计等参数。日志级别常用 syslog_level,线上为了减少IO一般设WARN,排查问题时可以临时调到DEBUG,但问题定位完要改回来。回收站相关的 recyclebin 是租户级参数,控制DROP表是否进入回收站,对于防止误删很有用。SQL审计开关则影响性能统计和诊断,适合在做SQL治理时打开,平时可以关闭降低开销。
把常用配置项整理成一张参考表,在实际环境里可以按 section 分类检索:
| 配置项 | 典型用途 | 生效方式 | 修改入口 |
|---|---|---|---|
| memory_limit | observer总内存上限 | 静态 | sys租户执行 |
| system_memory | 系统模块预留内存 | 静态 | sys租户执行 |
| datafile_size | 数据文件大小 | 静态 | sys租户执行 |
| log_disk_size | clog日志盘空间上限 | 静态 | sys租户执行 |
| large_query_threshold | 大查询判定阈值 | 动态 | sys或租户内执行 |
| ob_query_timeout | 查询超时时间 | 动态 | 租户内执行 |
| ob_trx_timeout | 事务超时时间 | 动态 | 租户内执行 |
| ob_trx_idle_timeout | 空闲事务超时时间 | 动态 | 租户内执行 |
| syslog_level | observer运行日志级别 | 动态 | sys租户执行 |
| recyclebin | 回收站开关 | 动态 | 租户内执行 |
不同版本的OceanBase,默认值和可修改粒度会有差异,真正生产操作前,建议先执行 SHOW PARAMETERS LIKE 确认好当前值域和说明,再动手。
5. 配置运维避坑与问题排查实录
5.1 典型问题:重启后配置被“打回原形”
这是配置运维最高频的现象。处理这类问题,首先要区分“当前运行值”和“启动持久化值”。如果你通过 ALTER SYSTEM SET 修改的是动态参数,且没有同步修改OBD config.yaml 或observer启动参数,重启后进程重新加载启动配置,自然恢复旧值。处理手段很简单:把需要保留的动态参数固化到OBD配置,对OBD管理的集群执行:
bash复制obd cluster edit-config <集群名>
obd cluster restart <集群名>
如果集群不是OBD部署的,就要在observer启动脚本中把参数加到 -o 序列里。手工部署的集群运维成本确实高一些,很多时候“配置不生效”的真相其实是“启动配置和运行配置各说各话”。
5.2 配置项改不生效的几个直接原因
改配置没效果,逐条排除下面这些原因,能省下大量排查时间:
- 权限不足:普通租户用户试图修改集群级参数,命令不会被执行。日志或客户端会提示权限类错误,需要使用系统租户账号操作。
- 作用范围写错:只想改zone1,结果语句没带
ZONE,改成了全局,或相反。运气好只是影响范围变大,运气差会在某个zone引发意外。 - 值没加引号或单位错误:设置时间类参数时不带单位,很多版本会直接报错或解析成错误值。标准姿势是带上明确单位字符串,不要偷懒。
- 静态参数被当成动态参数:修改成功,但没有重启,运行中的observer还是老样子,业务侧自然看不到效果。记得看
edit_level列。 - 缓存了旧配置:部分客户端或连接池存在会话级参数缓存,改完后新会话生效,旧会话仍然用旧值。测试时开一个全新连接看结果。
我把这些整理成速查表,方便你在工位贴一份:
| 表面现象 | 可能原因 | 处理动作 |
|---|---|---|
| 命令执行成功,但值没变 | 静态参数未重启 | 检查edit_level,筹备重启 |
| 业务租户执行报权限错误 | 无sys管理权限 | 用系统租户或让DBA操作 |
| 值变化但部分节点仍旧 | 心跳同步延迟/节点异常 | 等几秒再查,检查observer状态 |
| 重启后回退 | 启动配置覆盖动态值 | 同步修改OBD或启动脚本 |
| 时间参数不生效 | 忘记带单位字符串 | 改成'120s'这类写法 |
5.3 别乱碰的隐藏参数与内部参数
前面说的都是正常配置项,社区里还流行一种“隐藏参数”,名字通常以 _ 开头,例如 _ob_xx_xxx。这类参数不属于官方公开配置,是为了特殊问题排查或内核调优预留的,值域、副作用、依赖关系没有完整文档。
不要听风就是雨,拿网上的隐藏参数对着生产集群一阵 ALTER SYSTEM SET。很多隐藏参数在执行时会绕过常规校验,一旦设置错误,轻则内存超限、日志狂刷,重则集群数据异常、无法重启。如果确实排查某个问题需要动隐藏参数,正确处理是先找原厂工程师或走官方工单确认,并让集群处于可回退状态。
5.4 一次真实改动流程演示
拿一个常见的租户超时调整举例,完整演示正确操作顺序。
登录系统租户,先查看目标租户当前超时配置:
sql复制SHOW PARAMETERS LIKE 'ob_trx_idle_timeout';
业务反映空闲事务经常占用连接,希望把空闲事务超时从3分钟缩短到60秒。执行修改:
sql复制ALTER SYSTEM SET ob_trx_idle_timeout = '60s' TENANT = 'mysql001';
修改后立即确认:
sql复制SHOW PARAMETERS LIKE 'ob_trx_idle_timeout';
接着在业务租户内确认新链接的生效情况:
sql复制ALTER SYSTEM SET ob_query_timeout = '5s';
这里如果你的部署是OBD管理,且希望重启后仍保持这些值,记得在部署机上执行 obd cluster edit-config 把对应参数补到配置文件中,然后保存;如果这些是纯临时调整,那就不用改文件,但要记录清楚变更背景,避免时隔久远自己都忘了改过什么。每次变更我习惯把命令输出也存档,真正排查回退问题时不用从头摸索。
最后再说两句
我在实际使用中最大的体会是:OceanBase的配置体系其实是一种“部署态配置 + 运行态配置项”的双层结构。网上的教程大多只讲一层,结果小朋友拿着OBD配置改了半天,以为集群配置已经更新,实际上observer进程早就加载到内存里的还是旧参数。配置文件决定进程怎么起,配置项决定集群怎么跑,二者有交集但不完全等价。
还有一个工作习惯可以分享:生产环境动配置前,先写一份变更单,记录“当前值、目标值、作用范围、是否静态生效、是否要改OBD配置、是否需要重启、回退方案”这几个要素。一套OceanBase集群少则三五台,多则几十台,靠记忆管理配置项迟早出事。等你逐渐熟悉了 SHOW PARAMETERS 的每一列含义,掌握了配置项的静态动态区分,OceanBase运维工作中一大半的“玄学问题”都会变成可以预判的常规操作。
