Oracle DBA 第一次接手 OceanBase 集群时,最先问的问题往往不是 SQL 兼容性,也不是备份怎么做,而是:数据库连进程都看不到,到底怎么判断它健不健康?这个困惑很真实。Oracle 的数据库实例由 SGA 和一组后台进程构成,DBA 已经习惯用 ps 看到 PMON、SMON、DBW0、LGWR,通过进程状态判断实例状态。OceanBase 完全不同:它在单个节点上只有一个操作系统进程 observer,几乎所有功能都以线程方式在这个进程内部运行。Oracle DBA 转型 OceanBase 时,最需要先调整的不是某个参数,而是“多进程”这个运行模型。把它想通了,后续会话管理、性能排查、备份恢复才有着力点。
1. 为什么 Oracle DBA 转型 OceanBase,首先要“忘掉”多进程
1.1 Oracle 的进程模型已经成为 DBA 判断实例状态的习惯
Oracle 是一个典型的多进程数据库。一个完整的 Oracle 实例,除了共享内存 SGA 之外,还包含一组后台进程。常见的有 PMON、SMON、DBWn、LGWR、CKPT、ARCn 等,它们分别负责进程清理、实例恢复、脏块写盘、重做日志写入、检查点推进和归档日志处理。DBA 的日常巡检脚本里,经常会有这样的命令:
ps -ef | grep ora_pmon_如果能看到ora_pmon_<sid>,说明实例进程实体存在。如果某个关键后台进程异常,实例可能处于半可用状态。DBA 凭借进程列表就能快速判断数据库是否启动成功、归档是否正常、RAC 节点是否都活着。
这套经验本身没有错,但它和 Oracle 的实现方式强绑定。Oracle 选择多进程架构,是为了让不同职责的后台进程相互隔离,避免单点崩溃把整个实例拖垮,同时在不同硬件上也能形成清晰的资源边界。DBA 在这个模型里工作了十几年后,会把“通过进程列表观察数据库”当成默认能力。真正开始接触 OceanBase 时,这种默认能力反而会成为第一道认知障碍。
1.2 OceanBase 的单进程多线程架构为什么会让 DBA 不适应
OceanBase 在单个节点上只有一个操作系统进程,名字叫 observer。所有写日志、处理 SQL、事务提交、副本同步、合并数据等操作,都以线程的方式在 observer 进程内部完成。从操作系统层面看,你执行:
ps -ef | grep observer只会看到一个进程。如果按 Oracle 的习惯去数进程数量、看进程状态,会立刻产生误判:数据库是不是没起来?后台模块是不是丢了?实际上 observer 进程内部有非常多线程,负责网络接收、SQL 编译执行、事务管理、日志同步、资源回收等任务。
要求“忘掉多进程”,不是把 Oracle 的数据库知识全部扔掉,而是要先放下“数据库的健康状态等于一组后台进程状态之和”这个旧模型。OceanBase 的健康状态,必须通过 observer 进程状态、系统视图、日志和租户资源指标来综合判断。这一层转不过来,后面查会话、看日志、做性能分析都会走错方向。
2. 先对照清楚两套运行骨架:进程 vs 线程
2.1 Oracle 关键后台进程与职责
Oracle 后台进程数量不少,但对 DBA 来说,先在脑子里建立一个最小集合就够了:
| 进程 | 职责 | 异常时的影响 |
|---|---|---|
| PMON | 清理异常退出的用户进程,恢复未完成事务的锁资源 | 连接维护异常 |
| SMON | 实例恢复、临时空间清理、合并空闲空间 | 崩溃后恢复异常 |
| DBWn | 把缓冲池中的脏块写回数据文件 | 检查点推进慢,缓存压力升高 |
| LGWR | 把 redo log buffer 写入联机重做日志文件 | 提交性能下降 |
| CKPT | 触发更新数据文件和控制文件的检查点信息 | 崩溃恢复时间变长 |
| ARCn | 在归档模式下复制联机重做日志为归档日志 | 日志无法归档,数据库可能停止 |
每个进程在故障排查时都有自己的“戏份”。例如日志切换慢,DBA 会先看 ARCn 是否有 backlog;写入频繁导致脏块多,DBA 会怀疑 DBWn 跟不上。多进程模型把问题归属变得比较直观。
2.2 OceanBase observer 进程内部的线程分组
observer 是单进程,但它内部并非一个简单的线程池,而是按功能分组的线程体系。常见分组如下:
- 网络线程:负责监听端口、接收客户端连接请求和数据库内部通信。
- SQL 执行线程:负责接收 SQL、生成执行计划、执行计划并返回结果。
- 事务线程:管理事务的开启、提交、回滚,以及事务相关锁资源。
- 日志线程:生成事务日志(clog),写入本地磁盘,并同步给其他副本。
- 合并线程:在 major freeze 时把内存中的增量数据合并到 SSTable,生成新的数据版本。
- 后台维护线程:包括资源监控、GC、成员管理、与 RootService 通信等。
在操作系统层面,可以用下面的命令看到线程活动:
top -H -p $(pgrep observer)或
ps -eLf | grep observer能看到线程名、CPU 占用和内存占用。但要注意,观察线程只是手段,业务层面的 SQL 慢、锁等待、合并卡顿,仍然要通过数据库视图和日志来定位。不要试图在操作系统线程名上找到与 Oracle 后台进程一对一的对应关系。
2.3 架构对照速查表
| 维度 | Oracle | OceanBase |
|---|---|---|
| 进程模型 | 多进程 + 共享内存 SGA | 单进程多线程 |
| 存储架构 | 文件系统上的数据文件,RAC 依赖共享存储 | shared-nothing,数据分布在多个 observer 节点 |
| 高可用 | RAC + Data Guard,通过 redo 同步 | 多副本 + Paxos 协议,通过日志流同步 |
| 内存管理 | SGA + PGA,可单独调池子大小 | observer 进程内统一管理,按租户和 Unit 分配 |
| 观察入口 | ps、v$process、v$bgprocess | ps、oceanbase 系统视图、observer.log |
| 扩展方式 | 升级硬件或增加 RAC 节点 | 增加 observer 节点并搬迁数据分区 |
这张表是转型期最值得贴在桌面上看的。后续所有操作差异,根子都在这些结构性区别上。
3. 日常运维操作怎么切换:从进程指令到线程视角
3.1 查看实例是否存活
Oracle DBA 习惯先看 PMON 进程:
ps -ef | grep ora_pmon_<sid>OceanBase 里先看 observer 进程是否存在:
ps -ef | grep observer看到进程只是第一步。observer 进程存在,不表示集群一定可用。还要登录到集群的 sys 租户检查节点状态:
obclient -h127.0.0.1 -P2881 -uroot@sys -p USE oceanbase; SELECT * FROM oceanbase.DBA_OB_SERVERS;这个视图会返回每个 observer 节点所在的 zone、SQL 服务状态、心跳状态和资源水位。正常状态是 active,能对外提供 SQL 服务。更完整的健康判断还要结合租户视图和日志,不要只听一个进程是否存在。
3.2 查看会话和活跃 SQL
Oracle 里查会话用 v$session:
SELECT sid, serial#, username, status, sql_id, event FROM v$session WHERE username IS NOT NULL;OceanBase 的会话视图名和字段不一样。常见版本中可以查:
USE oceanbase; SELECT tenant_id, svr_ip, svr_port, id, user_name, state, sql_id FROM GV$OB_PROCESSLIST WHERE state != 'SLEEP';这里svr_ip和svr_port能告诉你这个会话到底连在哪个 observer 节点上。如果集群有多个节点,一条 SQL 可能被路由到某个具体节点执行,也可能由于主副本位置不同而转发到其他节点。这个“会话和节点绑定”的视角,是 Oracle 单实例时代不太需要关心的。
注意:OceanBase 不同版本中,动态性能视图的名称和字段会有差异。遇到视图不存在或字段名变动时,先查当前版本的官方文档,不要硬套网上的旧脚本。
3.3 终止会话
Oracle 终止会话的命令是:
ALTER SYSTEM KILL SESSION 'sid,serial#';OceanBase 在 MySQL 模式下可以用 KILL 语句终止一个连接:
KILL session_id;在 Oracle 模式租户中,也可以使用兼容的语法终止会话,但具体 SQL 格式依赖当前版本和接入方式。终止会话前要确认该会话是否处于事务中,如果这个会话已经申请了行锁,强行 kill 可能导致业务侧短暂感知到连接中断。
另外,OceanBase 的会话视图里一个常见问题:同一个客户端连接在事务执行过程中,可能显示为不同状态,不要只依赖命令行结果判断,必要时配合日志确认。
3.4 日志体系:从 alert 日志到 observer.log
Oracle DBA 排查问题时,第一步经常是看 alert 日志,路径大约在:
$ORACLE_BASE/diag/rdbms/<dbname>/<sid>/trace/alert_<sid>.logOceanBase 的对应物是 observer 日志,默认在 observer 进程启动目录下的log/observer.log。还有一个重要差异:OceanBase 是分布式系统,一个操作可能同时涉及多个节点,因此排查时不能只看单个节点的日志,要从发生问题的租户、表、分区入手,再决定去看哪个节点的 observer.log。
常见排查命令是通过关键字过滤日志:
grep -n "ERROR" log/observer.log | tail -n 100 grep -n "WARN" log/observer.log | tail -n 50生产环境应该把日志级别、日志轮转、保留天数纳入初始化配置,否则磁盘被日志写满,比数据库本身的问题更难处理。
4. 性能排查:不再按进程归因,而是按线程与租户定位
4.1 Oracle 的性能排查习惯
Oracle DBA 做性能分析时,通常按这个链条走:
- 查看当前等待事件,定位会话在等什么。
- 分析 SQL,找到 CPU 高、逻辑读高或物理读高的语句。
- 查看 AWR 报告,对比时间区间内的负载变化。
- 如果发现写库慢,会去看 DBWn 或 LGWR 相关指标。
这套思路的核心是“按进程归因”:每个 session 对应一个 server process,每个后台进程负责一种资源。当某个进程指标异常时,DBA 容易判断问题出在哪里。
4.2 OceanBase 性能排查入口
OceanBase 没有 server process 的概念,但保留了很多类似 Oracle 的排查视图。最先要建立的是三个入口:
- 会话入口:
GV$OB_PROCESSLIST或GV$OB_SESSIONS,看当前有哪些会话、在哪个节点、在做什么。 - SQL 入口:
GV$OB_SQL_AUDIT,记录一段时间内 SQL 的执行耗时、返回行数、物理读等。 - 租户资源入口:sys 租户下的
DBA_OB_TENANTS和资源规划视图,看租户 CPU、内存是否够用。
下面这个查询可以快速找出最近一段时间执行耗时最高的 SQL:
USE oceanbase; SELECT tenant_name, svr_ip, svr_port, sql_id, elapsed_time, executations FROM GV$OB_SQL_AUDIT WHERE tenant_name = 'test_tenant' ORDER BY elapsed_time DESC LIMIT 20;需要说明的是,GV$OB_SQL_AUDIT默认采集最近一段时间的请求,数据存在内存中,不是历史归档。生产环境想长期保存 SQL 记录,需要依赖平台侧监控系统或自行定时采集。
4.3 等待事件视角的延续与变化
OceanBase 在兼容模式下也提供了等待事件相关信息,但 DBA 不要拿 Oracle 的全部等待事件经验直接套用。OceanBase 的常见等待可能包含网络同步、日志落盘、锁等待、合并等待等,语义和 Oracle 有部分重叠,也有很大不同。
排错顺序建议:
- 先确认是不是 SQL 问题:看执行计划、统计信息和走索引的情况。
- 再确认是不是租户资源不足:CPU 是否打满、内存是否触顶。
- 然后确认是不是分布式协调问题:主副本是否集中在单一节点,跨节点访问是否明显。
- 最后才看操作系统层面的线程和 IO。
4.4 线程状态和操作系统资源怎么看
如果确实需要从操作系统层面观察 observer 的资源消耗,建议用:
top -H -p $(pgrep observer)这个命令能看到 observer 进程内所有线程的 CPU 占用。某个线程 CPU 高,不一定等于某个租户有问题,它可能只是网络线程在集中处理大量请求。因此线程观察只能作为辅助手段,最终定位仍然以系统视图和日志为准。
4.5 内存调整思路完全不同
Oracle 的内存管理核心是 SGA 和 PGA,DBA 常常调整:
ALTER SYSTEM SET shared_pool_size=8G SCOPE=BOTH; ALTER SYSTEM SET pga_aggregate_target=4G;OceanBase 里没有共享池和 PGA。内存被 observer 进程统一管理,在租户层面通过资源单元分配。资源单元一般按 CPU 和内存设置。一个最小例子:
CREATE RESOURCE UNIT unit_test MAX_CPU = 4, MEMORY_SIZE = '8G';租户资源调整不是简单的内存参数变更,而是影响整个资源池的分配。生产环境调整 CPU 或内存前,要先确认集群规模和资源池归属,避免某个租户调整后导致其他租户资源不足。
5. 事务与高可用机制:从进程协作切换到日志流
5.1 Oracle 的高可用基础
Oracle 高可用通常围绕共享存储和日志复制展开。单实例中,事务提交依赖 LGWR 写 redolog;RAC 中多个实例共享同一套数据文件,通过 Cache Fusion 协调缓存一致性;Data Guard 通过主库发送 redo 到备库完成容灾。DBA 看到的是多个实例进程、控制文件、数据文件和归档日志之间的协作。
5.2 OceanBase 的高可用基础
OceanBase 的高可用核心是多副本和 Paxos 协议。一个表的某个分区,会在不同节点上保存多个副本。某条事务提交时,日志必须到达多数派副本,才算真正提交成功。单个 observer 宕机时,如果多数派还活着,系统可以继续对外提供服务,并且会自动从其他副本补齐数据。
这段机制带来的 DBA 体验差异是:你不再需要手工切换 instance、激活 standby,而是观察副本状态和日志流是否健康。出现节点故障时,系统会自动选主、补副本,DBA 需要做的是确认故障节点是否隔离完整、日志同步是否恢复、副本最终是否补齐。
5.3 备份恢复思路差异
Oracle DBA 的备份习惯以 RMAN 为中心:全量备份、增量备份、归档日志、PITR 恢复。OceanBase 的备份恢复是按租户级别进行的,常见步骤是:
- 先配置备份目的端,例如 NFS 或对象存储。
- 执行租户全量备份。
- 定期执行增量备份和日志备份。
- 做恢复演练时,把备份数据恢复到指定时间点。
生产环境必须定期做恢复演练,而不是只看备份任务是否成功。分布式数据库的备份链更复杂,涉及到日志归档的连续性和多个副本之间的数据一致性,恢复流程必须验证过才可信。
5.4 扩容和迁移思路差异
Oracle 单实例扩容通常是升级 CPU、内存和磁盘;RAC 扩容是加新节点,但对共享存储依赖强,存储扩容成本高。OceanBase 扩容的思路是增加 observer 节点,RootService 负责把部分分区的副本迁移到新节点,并保持数据均衡。
第一次做 OceanBase 扩容时,最常见的心理误区是:以为新增节点后数据会立即均匀分布。实际上数据分区迁移和日志同步需要时间,期间可能伴随跨节点访问和短暂的性能波动。DBA 要观察迁移进度、副本状态和集群均衡度,而不是只看到节点进程已经启动就宣布扩容完成。
6. 转型过程中最常踩的坑
6.1 用进程数量判断实例状态
现象:执行ps -ef | grep observer只看到一个进程,于是怀疑数据库没有启动。
原因:OceanBase 在单节点上就是单进程,observer 是否健康不能靠进程数量判断。
处理:用 obclient 登录 sys 租户,查询DBA_OB_SERVERS的节点状态,并检查log/observer.log中的错误信息。
预防:把“进程存在”和“集群健康”拆成两个检查项,进程检查放最后,系统视图和日志检查放前面。
6.2 找不到 v$session 就认为会话体系不完整
现象:在 OceanBase 中执行SELECT * FROM v$session;发现视图不存在或返回空。
原因:OceanBase 的动态性能视图位于oceanbase库下,且统一以GV$OB_或DBA_OB_前缀命名,和 Oracle 的系统视图不是完全同名。
处理:优先查询GV$OB_PROCESSLIST和GV$OB_SESSIONS,以当前部署版本的视图清单为准。
预防:在转型初期,先把常用视图的对照表整理到自己的笔记里,不要每次都试错。
6.3 想调 SGA 或 PGA 池子
现象:按照 Oracle 经验,把shared_pool_size或db_cache_size设置到 OceanBase 中,发现根本不存在这些参数。
原因:OceanBase 没有 SGA/PGA 概念,内存按租户和 Unit 分配,内部有 MemTable、缓存、执行内存等多个部分。
处理:通过资源单元和租户资源池管理内存。如果内存紧张,重点看 MemTable 内存是否因大量写入而不合理膨胀,以及合并是否被阻塞。
预防:出现问题先查租户内存视图和合并状态,不要盲目调整缓存池大小。
6.4 看到 ORA- 错误就按 Oracle 经验推原因
现象:OceanBase Oracle 模式下返回一个以ORA-开头的错误码,DBA 按 Oracle 的常见报错去排查,结果方向不一致。
原因:OceanBase 为兼容 Oracle 错误码做了一部分映射,但错误产生的内部机制和排查路径并不同。
处理:先确认错误发生在连接、解析、执行还是分布式事务阶段,再结合 observer.log 定位;如果日志没有明确线索,再查对应官方文档。
预防:不要把 Oracle 的 ORA- 错误码手册当成 OceanBase 的标准手册,只把它当作入门的提示。
6.5 在操作系统线程名上找对应关系
现象:用ps -eLf | grep observer看到很多线程,试图在线程名里找到类似dbwr、lgwr的对应物。
原因:Observer 线程命名和 Oracle 后台进程没有一一对应关系,不同版本线程名也可能不同。
处理:把操作系统线程当作辅助信息,判断资源热点时可以看 top -H;但业务问题定位要回到数据库视图和日志。
预防:明确数据库内部的线程职责,不强行映射到 Oracle 进程名。
7. 给 Oracle DBA 的 OceanBase 学习路径
7.1 第一步:重构架构模型
不要急着写代码或调参数,先建立三个基本概念:分区、副本和日志流。
- 分区:一张大表的数据被打散到多个分区,分区是数据分布和复制的基本单位。
- 副本:每个分区在多个节点上有副本,副本之间通过 Paxos 协议保持一致。
- 日志流:事务修改和副本同步都围绕日志流展开,一个副本落后时就出现同步延迟。
理解了这几个概念,再看 OceanBase 的运维操作,就会觉得很多设计是自然结果:为什么节点坏了还能继续写?为什么新增节点后数据会自动均衡?为什么查询可能被转发到其他节点?答案都在这个模型里。
7.2 第二步:用最小集群跑通一次完整运维闭环
学习环境建议先部署一个最小集群。可以用 OBD 在一台机器上通过多个 observer 目录模拟多节点环境,操作门槛低。跑通以下环节:
- 部署集群并启动 observer。
- 连接 sys 租户,创建资源单元和资源池。
- 创建业务租户,并创建一个普通用户。
- 建表、插入数据、查询数据。
- 查看复制副本状态和会话状态。
- 手动发起合并,观察合并效果。
- 执行一次备份和恢复。
这七个步骤覆盖了 Oracle DBA 最关心的日常运维主链路。做过一次,后面再深入某个模块就有上下文。
7.3 第三步:建立新的工具链和命令集合
常用工具不需要一次学全,先掌握这几个:
| 工具 | 用途 | 对比感受 |
|---|---|---|
| obclient | 连接 OceanBase 执行 SQL | 类似 sqlplus |
| OBD | 本地部署和管理集群 | 类似 Oracle 的安装配置脚本 |
| OCP | 图形化运维和监控平台 | 类似 Oracle Enterprise Manager |
| oceanbase 视图 | 查集群、租户、会话、SQL 审计 | 类似数据字典和动态性能视图 |
生产中尽量把“命令能力”沉淀成脚本或运维文档。遇到新问题时,先看日志,再看视图,不要只靠网上零散的命令。
7.4 第四步:做一次真实场景的 SQL 迁移演练
可以从一个简单的 Oracle 应用开始,把表和 SQL 迁到 OceanBase 的 Oracle 模式。重点检查:
- sequence 使用:OceanBase 的序列和 Oracle 有差异,应用不能依赖完全相同的缓存行为。
- 时间函数:部分 Oracle 时间函数可能被兼容,但函数行为和格式默认值需要验证。
- 分页查询:Oracle 的 ROWNUM 和 OceanBase 兼容写法是否一致。
- 隐式类型转换:两种数据库对字符串和数字的转换规则可能不同。
- 执行计划:相同 SQL 的执行计划可能不同,要重新验证索引是否有效。
这类测试不要只在功能层面看结果,还要压一下并发和事务混合场景,模拟真实负载下的性能表现。
7.5 第五步:维护一张“每天要看”的运维检查清单
在从 Oracle 思维切换到 OceanBase 思维的过程中,把关键指标写进清单比记住所有细节更可靠。一个可复用清单如下:
- 集群健康:查询
DBA_OB_SERVERS,判断所有 observer 节点状态是否正常。 - 租户状态:查询
DBA_OB_TENANTS,确认租户是否正常。 - 会话分布:查询
GV$OB_PROCESSLIST,看是否存在堆积会话。 - SQL 异常:查询
GV$OB_SQL_AUDIT,找到耗时最长或返回行数异常大的 SQL。 - 节点资源:使用
top和系统监控查看 CPU、内存、磁盘。 - 合并进度:确认最近一次 major freeze 是否完成,是否被阻塞。
- 日志同步:查看副本是否有延迟,多数派是否正常。
- 备份状态:检查最近一次全量备份、增量备份和日志备份是否成功。
- 磁盘空间:检查 observer 数据目录和日志目录的容量。
- 错误日志:看看
observer.log中是否有大量 ERROR 或 WARN。
这张清单不需要一次全部自动化,先手工执行几周,等熟悉了哪些指标对应什么问题,再逐渐接入监控平台。
7.6 关于“忘掉”的最终建议
“忘掉多进程”不是把你十几年积累的数据库知识清零,而是把进程模型从“默认前提”变成“其中一种实现”。Oracle 用多进程,OceanBase 用单进程多线程,但两者最终要解决的是同一个问题:在资源有限的硬件上,安全、高效、可靠地处理并发事务。
真正需要带走的不是 PMON、DBWn 这些进程名,而是关于资源管理、并发控制、故障恢复、性能分析的方法论。把这些方法论迁移到 OceanBase 的单进程多线程模型上,学习曲线会比想象中短。先从认识 observer 这一个进程开始,然后理解线程、租户、副本、日志流,最后你会发现:不是数据库变复杂了,而是分布式数据库把原来藏在单机进程后的复杂性,显式地放到了你面前。