ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

从Oracle到OceanBase:告别多进程思维,理解单进程多线程架构

从Oracle到OceanBase:告别多进程思维,理解单进程多线程架构 先说一个真实场景一个 Oracle DBA 第一次拿到 OceanBase 环境习惯性敲下ps -ef | grep -i oracle结果屏幕上除了 grep 本身什么都搜不到。第一反应是“是不是没装上”第二反应是“是不是崩了”。实际上服务跑得好好的只是这台机器上已经没有一个叫oracle的进程了。如果你也有过类似经历或者正准备从 Oracle 体系迁移到 OceanBase这篇内容建议先收藏。它的核心就一句话把“多进程”这个思维惯性忘掉OceanBase 用的是单进程多线程架构。这个差异不是概念层面的它会直接影响你的日常巡检方式、故障排查路径、性能诊断习惯甚至影响你对“数据库是不是正常”的判断。比如在 Oracle 里pmon挂了会有人紧张smon异常会有人看日志进程数量对不上就要查是不是PMON退出。但在 OceanBase 里没有pmon/smon/dbwr/lgwr/ckpt这组进程只有一个observer主进程和若干周边进程。再看ps的时候判断依据完全变了。这不是说 Oracle 的判断方法错了而是说 OceanBase 的进程模型本来就不是按 Oracle 的思路设计的。本文会从架构差异、进程排查、资源管理、性能诊断、安装部署这几个方面拆开讲最后给出一份 Oracle DBA 转 OceanBase 初期的避坑清单。文章里的命令和示例都按常见部署环境做了通用化处理具体路径和版本信息以你本机环境为准。1. 核心能力速览先给一张“架构对照速览表”把 Oracle 和 OceanBase 最关键的差异列出来。这张表不是为了全面对比两款数据库而是聚焦在“为什么不能沿用多进程思维”这件事上。维度Oracle 经典架构OceanBase 架构进程模型多进程SMON、PMON、DBWR、LGWR、CKPT 等单进程observer内部多线程SQL 接入专用/共享服务器进程1521 端口监听observer SQL 端口 2881OBProxy 端口 2883内存管理SGA PGA通过 pfile/spfile 配置内存按租户资源单元UNIT划分系统内存单独预留日志文件redo log / archive logclog提交日志 schema 变更日志等会话查看v$session / v$processGV$OB_PROCESSLIST / GV$OB_SQL_AUDIT备份恢复RMAN、expdp/impdp、Data GuardOMS 数据迁移、obdumper/obloader、物理备份恢复、备租户部署工具DBCA、手工脚本、grid 安装OBD 一键部署、OCP 管控平台高可用基础RAC Data Guard 组合Paxos 多副本协议单集群内多副本从这张表能看出OceanBase 并不是把 Oracle 的进程拆成不同名字而是从底层换了一套运行模型。所以 Oracle DBA 转型时第一步不是去记新进程名而是先接受“进程维度”已经不是首要排查维度这件事。2. 架构思维转换为什么 OceanBase 没有“多进程”Oracle 用多进程本质上是把数据库的不同职责拆给不同进程比如日志写入专门由 LGWR 负责数据文件写入由 DBWR 负责实例异常监控由 PMON 负责。这带来的好处是职责清晰出了问题可以盯着某个进程查坏处是进程间通信开销大内存共享要特别小心遇到异常退出还要处理进程级故障恢复。OceanBase 的选择是单进程多线程。一个observer进程内部包含了网络处理、SQL 引擎、事务引擎、存储引擎、日志模块等所有核心组件不同模块用线程来并发。这样做的好处是线程共享进程内存通信成本低也能更灵活地控制连接数、CPU 时间片和内存边界。代价是——你以前那套“ps看进程”的方法在 OceanBase 上基本失效了一半。用一条命令来看ps -ef | grep observer典型的输出是root 12345 1 0 10:00 ? 00:00:00 /home/admin/oceanbase/bin/observer只有一个 observer 进程。如果你再数一下它内部的线程数会发现数量多到让你怀疑人生# 找到 observer 的 PID 后按线程统计 ps -eLf | grep 12345 | wc -l在负载正常的节点上observer 的线程数达到几百个是常见情况。线程分别负责网络 IO、SQL 处理、事务提交、clog 落盘、合并压缩、后台巡检等。想再细看线程级别可以用top -Hp pid或者用pidstat -t -p pid按线程观察 CPU 使用。这一步和 Oracle 上ps -L看线程的思路类似但观察对象从“多个进程”变成了“一个进程下的多个线程”。所以架构思维的转变可以浓缩成三点巡检时不再问“这个进程还在不在”而是问“observer 是否存活、内部关键线程是否正常、租户资源是否健康”。排查异常时不再按“哪个进程出问题”分线索而是按“哪个模块出问题”分线索比如网络模块、SQL 模块、事务模块、存储模块。杀进程、重启服务时不再有“先杀 PMON 还是先杀 SMON”这种操作而是按集群运维规范统一启停。3. 进程与线程排查日常运维操作差异Oracle DBA 最熟的运维动作在 OceanBase 里多半要换个做法。下面挑几个高频场景对比。3.1 查看实例是否活着Oracle 一般先ps -ef | grep pmon如果 pmon 在再sqlplus / as sysdba看实例状态。OceanBase 的对应操作更简单但也有讲究# 检查 observer 进程是否存在 ps -ef | grep observer # 连接 observer 本机 SQL 端口执行系统租户查询 obclient -h127.0.0.1 -P2881 -urootsys -p -A登录到 sys 租户后可以检查集群状态SELECT * FROM GV$OB_SERVERS;这个视图会返回每个 observer 节点的状态、CPU 容量、内存容量、磁盘使用情况。只要这里能看到节点进程层面那份ps只是参考不用太较真。3.2 观察线程使用在 Oracle 里遇到性能问题会ps -ef | grep ora_看看哪个后台进程 CPU 高。在 OceanBase 里重点是看 observer 进程内部哪些线程在消耗 CPU# 按 CPU 排序看 observer 的线程 top -H -p $(pgrep -f observer | head -1)进去后按大写P排序就能看到线程名和 CPU 占用。常见线程名包括Tsys、TMySQL、Txn、Clog、Merge等具体名字在不同版本里会有差异。通过线程名可以大致判断瓶颈在网络、事务还是合并任务。3.3 重启和停止服务Oracle 用sqlplus执行shutdown immediateOceanBase 的常规方式是用 OBD 或 OCP 操作也可以在系统租户里执行ALTER SYSTEM STOP SERVER或SHUTDOWN但生产环境推荐走管控平台或 OBD# 停止整个集群以 OBD 部署为例 obd cluster stop 部署名 # 启动整个集群 obd cluster start 部署名这里要特别提醒不要在生产环境随意kill -9observer 进程。observer 内部有大量状态在内存里强杀可能导致异常恢复流程、回放日志或者触发副本重新选择。日志模块有自己的落盘机制但 “observer 可以随便杀” 是一个错误的观念。正常操作应该用kill不带 -9触发优雅退出或在管控层执行标准停止命令。3.4 查看运行日志Oracle 的告警日志路径一般叫alert_sid.logOceanBase 的日志目录和文件命名不同。默认情况下observer 日志在~/store/log或logs目录下observer.log主服务日志rootservice.logRootService 相关日志election.log选举相关日志clog相关日志可能在独立目录日常排查先看observer.log用grep按关键字和日志级别过滤cd /home/admin/oceanbase/log grep -i -E error|warn observer.log | tail -n 100日志格式通常包含时间、模块、线程号、级别、日志内容等字段。排查的时候先定位时间段再按WARN和ERROR级别过滤效率更高。4. 资源管理从 SGA/PGA 到租户资源单元Oracle 的内存用 SGA 和 PGA 区分DBA 很习惯调shared_pool_size、db_cache_size、pga_aggregate_target这类参数。OceanBase 不是这个思路它把资源管理的核心单位改成了“租户”租户资源由资源单元UNIT定义。一个租户会占用一组 CPU 和内存配额资源单元在创建时指定min_cpu、max_cpu、memory_size等参数。同一个 OB 集群里可以有多个租户租户之间通过资源单元的配额做隔离。所以你在 OceanBase 里查内存不是在查“共享池还有多少”而是查“租户资源是否够用”、“内存是否触达上限”。常用检查语句如下-- 查看集群资源池分布 SELECT * FROM DBA_OB_RESOURCE_POOLS; -- 查看租户的资源单元配置 SELECT * FROM DBA_OB_UNIT_CONFIGS; -- 查看租户内存使用情况 SELECT * FROM GV$OB_MEMORY WHERE TENANT_ID 租户ID;这里和 Oracle DBA 直觉最大的冲突点在于Oracle 多数情况下是“按实例全局配置资源”OceanBase 是“按租户维度切分资源”。一个节点如果跑多个租户CPU 和内存是提前通过资源单元划定的不像 Oracle 的 SGA 里各组件可以动态竞争。所以做容量规划时要先把租户的memory_size规划好而不是上线后才发现内存不够。CPU 方面OceanBase 的min_cpu和max_cpu配合调度器控制租户能使用的 CPU 上限。判断租户 CPU 是否打满可以看GV$OB_SERVERS里的 CPU 容量和当前使用数据或者结合 OCP 监控看。对于 Oracle DBA比较容易理解的类比是max_cpu像cpu_count和资源管理器配合起来的效果memory_size像SGA_TARGETPGA_AGGREGATE_TARGET的组合但实现方式完全不同。磁盘方面Oracle 有表空间、数据文件、临时表空间OceanBase 有数据文件sstable、clog 日志等。磁盘空间规划时要同时关注数据存储、clog、日志文件以及合并带来的临时空间需求。5. 性能诊断从 v$session 到 GV$OB_* 视图Oracle DBA 做性能诊断基本绕不开v$session、v$sql、v$active_session_history这一组动态性能视图。OceanBase 有对应的视图体系名字有一定相似性但使用方式要重新熟悉。5.1 查当前会话和并发Oracle 看v$sessionOceanBase 看GV$OB_PROCESSLIST-- 查看当前租户活跃会话 SELECT * FROM GV$OB_PROCESSLIST WHERE STATE ACTIVE;这个视图能看客户端 IP、端口、SQL ID、事务状态、会话状态等信息。排查“哪个会话卡住了”先从这里定位TRACE_ID和 SQL ID再往 SQL 审计视图查。5.2 查 SQL 执行历史SQL 性能问题建议直接看审计视图-- 最近慢 SQL SELECT * FROM GV$OB_SQL_AUDIT WHERE ELAPSED_TIME 1000000 ORDER BY REQUEST_TIME DESC LIMIT 50;ELAPSED_TIME的单位是微秒要注意换算。Oracle 中v$sql主要看累计统计OceanBase 的GV$OB_SQL_AUDIT偏向每次执行的审计记录按时间范围捞慢 SQL 更方便。拿一条 SQL 的TRACE_ID可以串起一次请求在 observer 内部各个模块的执行记录这有点像 Oracle 里用 SQL 的SQL_ID去查v$sql_plan和v$sql_monitor的组合但追踪粒度更细。5.3 查执行计划OceanBase 查看执行计划有专门的接口-- 查看某条 SQL 的执行计划 EXPLAIN SELECT * FROM T1 WHERE ID 1; -- 通过 SQL 审计视图拿到 plan id 后查看对应计划 SELECT * FROM GV$OB_SQL_PLAN WHERE PLAN_ID plan_id;要注意OceanBase 的执行计划里会出现 “表扫描”、“聚合”、“NESTED-LOOP JOIN”、“HASH JOIN” 这些算子和 Oracle 的TABLE ACCESS BY INDEX ROWID、NESTED LOOPS概念很像但算子命名和细节不完全一致。Oracle DBA 需要适应的是部分调优手段从“改 hint、改索引”延伸到“看分区裁剪和副本选择”因为 OceanBase 的分布式执行计划会考虑数据分布和节点间的数据交换。5.4 查等待事件和底层信息Oracle 的等待事件体系非常成熟有v$system_event、v$session_wait。OceanBase 也有等待事件相关信息可以通过内部视图查询但名称不同。刚上手时不用急着背事件名先学会看三类信息当前有没有 CPU 打满、内存触顶慢 SQL 的执行计划是不是走了全表扫描或没切对分区事务有没有长时间未提交导致锁等待或 clog 压力。判断事务冲突时可以看GV$OB_TRANSACTION_PARTICIPANTS或通过 SQL 审计观察WAIT_CLASS、WAIT_EVENT字段。整体上OceanBase 的性能诊断路径是SQL 审计 → 慢 SQL → 执行计划 → 资源视图比 Oracle 的“会话 → 等待事件 → SQL → 执行计划”更依赖 SQL 审计层的数据。6. 安装部署体验从手工建库到 OBD 一键部署Oracle 安装有多繁琐经历过的人都知道下载补丁、配置 grid、改内核参数、跑 DBCA、处理监听问题、设置环境变量一个环节出错整晚就没了。OceanBase 当前的本地部署体验要轻很多社区版常用 OBD 工具可以在测试机上快速拉起一个集群。以下是通用操作示例不同版本的 OBD 和安装包路径需要按实际环境调整# 解压软件包假设安装包已放置到指定目录 tar -xzf oceanbase-ce-版本.tar.gz # 初始化部署目录示例路径按实际调整 mkdir -p /data/oceanbase/{store,etc,run,log} # 使用 obd 设置部署配置 obd cluster create 部署名 -c 配置文件路径配置文件里要写清楚节点 IP、observer 安装路径、数据目录、SQL 端口、RPC 端口等。一个最小测试配置通常包括obproxy: servers: - 127.0.0.1 global: listen_port: 2883 prometheus_listen_port: 2884 home_path: /home/admin/obproxy oceanbase-ce: servers: - 127.0.0.1 global: home_path: /home/admin/oceanbase data_dir: /data/oceanbase/store log_dir: /data/oceanbase/log mysql_port: 2881 rpc_port: 2882配置完成后启动obd cluster start 部署名然后测试连接obclient -h127.0.0.1 -P2881 -urootsys -p连接成功后可以先执行一个基础查询确认集群状态SELECT * FROM GV$OB_SERVERS;如果是第一次体验建议直接用 OBD 装一个单节点集群配置两个租户一个 sys 租户用于管理一个业务租户用于测试。这样既能感受单进程多线程架构也能体验租户资源隔离。很多 Oracle DBA 会关心一个兼容性问题PL/SQL、存储过程、包这些能不能直接用。OceanBase 的 Oracle 模式在语法兼容方面已经做了很多工作但存储过程、包的部分行为仍有差异。真实项目迁移时不能靠“语法看起来一样”就判定可用要在测试环境跑一轮 PL/SQL 兼容性验证。像 Oracle 的CONNECT BY START WITH、NOT EXISTS、TRUNC(SYSDATE)这类常用写法在 OceanBase Oracle 模式下大多有对应支持但分层查询、正则表达式等细节仍建议逐条验证。7. 常见误区与排查清单Oracle DBA 刚转 OceanBase 时出错往往不是难在 SQL而是难在运维习惯。下面列几个高频误区。7.1 用ps找一堆进程最容易踩的坑。看到ps -ef | grep observer只有一个进程就觉得“是不是失败了”。实际只要GV$OB_SERVERS里能看到节点进程就正常。7.2 用kill -9强杀 observer 进程这是高危操作。非正常退出可能导致恢复时间变长极端情况要等副本重建。正确方式是使用obd cluster stop或管控平台操作。7.3 把租户内存当成 Oracle 的 SGA 来调Oracle 的内存参数可以调共享池、缓冲区缓存OceanBase 的内存主要由租户资源单元管控调整方式不同-- 修改租户资源单元示例 ALTER SYSTEM ALTER RESOURCE UNIT unit_name SET MAX_CPU 4, MEMORY_SIZE 8G;修改前要确认集群节点剩余资源足够。这类操作在 OCP 里也有可视化界面生产环境优先走管控平台。7.4 主备切换和 RAC 思路混淆Oracle 的 RAC 是共享存储多实例架构Data Guard 是主备物理复制。OceanBase 的高可用是基于 Paxos 协议的多副本架构同一个租户的多个副本之间是强一致的主副本故障后会自动选主。Oracle DBA 有时会下意识把“备库”当成物理 Standby 来理解实际上 OceanBase 的备副本同样参与一致性协议和 Data Guard 的主备模式不是一回事。7.5 忽略分区键对执行计划的影响Oracle 分区表需要手工管理分区OceanBase 对分区表的支持类似但分区键的选择会影响分布式执行计划。如果 SQL 没有裁剪到正确的分区可能会跨节点扫描性能差距极大。调优时不要只加索引先看分区键是否合理。7.6 通过内网安全访问和端口混淆Oracle 默认 1521OceanBase observer 默认 2881SQLRPC 默认 2882OBProxy 默认 2883。很多 DBA 第一次连不上是因为把 2883 当成了 observer 端口直连或者防火墙没放行 RPC 端口。排查连接问题时先把端口层次理清楚直连 observer 用 2881走 OBProxy 用 2883RPC 端口只在节点内部使用通常不对外网开放。8. 常见问题与排查方法问题现象可能原因排查方式解决方案ps看不到 Oracle 进程概念混淆以为 Oracle 进程必须存在检查 observer 进程和GV$OB_SERVERS确认 observer 存活即可连接 2881 失败防火墙未放行、observer 未启动telnet 127.0.0.1 2881查看 observer.log放行端口或启动 observer连接 2883 失败OBProxy 未启动或端口配置错误检查 OBProxy 配置obclient -P2883重启 OBProxy 或修正端口执行 SQL 很慢分区裁剪没生效、执行计划走全表扫描查看GV$OB_SQL_AUDIT和执行计划调整 SQL 写法或分区键内存使用率高租户 unit 内存配置偏大查看DBA_OB_UNIT_CONFIGS按业务量调整 unit 配置kill -9后恢复异常进程被强杀触发恢复流程查看 observer.log、rootservice.log按标准方式重启必要时联系社区支持存储过程运行报错PL/SQL 兼容性差异在测试库逐条执行并比对结果改写不兼容语法用兼容模式验证节点 CPU 打满慢 SQL 并发高或后台合并任务top -Hp observer_pid看线程优化 SQL、调整合并窗口数据迁移不完全目标端字符集或类型映射不匹配检查迁移任务日志和抽样数据使用 OMS 重新校验或手工补齐9. Oracle DBA 转 OceanBase 的最佳实践下面给一套实用的推进路径适合刚从 Oracle 转过来、还没摸清 OceanBase 脾气的 DBA。先不要在生产环境直接做迁移。找一台测试机用 OBD 部署一个单节点集群然后跑三件事把常用的巡检命令写成新脚本。比如把ps -ef | grep pmon改成检查observer进程 GV$OB_SERVERS把v$session查询改成GV$OB_PROCESSLIST把v$sql慢 SQL 查询改成GV$OB_SQL_AUDIT。把业务侧最核心的 50 条 SQL 导到测试租户执行记录执行计划差异。重点关注分区裁剪、连接方式、隐式类型转换。Oracle 里某些 SQL 在 OB 上可能因为统计信息不同而选择完全不同的计划。验证一套备份恢复流程。OceanBase 的物理备份、逻辑导出导入和多副本机制都要在测试环境走通再考虑生产切换。数据迁移建议优先考虑 OMS 或逻辑导出导入工具。Oracle 的expdp/impdp在 OceanBase 不适用命令不同校验方式也要重新设计。字符集、字段类型长度、约束、自增列这些都要逐项比对。日常巡检建议用好这三个维度巡检项关注点关键视图/命令节点状态observer 是否在线、磁盘空间GV$OB_SERVERS、df -h租户资源CPU、内存是否触达上限DBA_OB_UNIT_CONFIGS、GV$OB_MEMORYSQL 性能慢 SQL、执行计划变化GV$OB_SQL_AUDIT、EXPLAIN日志和监控建议统一接到 OCP 或 Prometheus Grafana。虽然命令行能查到所有信息但告警和历史趋势还是靠监控平台更可靠。OBProxy 也要纳入监控范围因为用户连接走 OBProxy 时OBProxy 本身会成为新的故障点。如果遇到官方文档没覆盖的问题优先去 OceanBase 社区或官方资料库搜索不要直接用 Oracle 的故障处理思路硬套。比如“日志切换慢”在 Oracle 里是 redo 相关在 OceanBase 里可能是 clog 落盘或磁盘 IO 问题“锁等待”在 Oracle 里查v$lock在 OceanBase 里要通过事务参与者视图和 SQL 审计去定位。把排查思路切换到“线程 视图 日志”三位一体很多问题会好查很多。最后说一个最实在的操作建议一上来别碰 OCP 的大规模部署先手动用 OBD 装一个节点把 observer、OBProxy、租户、备份恢复全部走一遍。只有亲手操作过才能真正理解单进程多线程架构和 Oracle 多进程架构的差异。等到你不再下意识执行ps -ef | grep pmon的时候这关就算过了。
返回列表