ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

OceanBase状态矛盾排查:oceanbase-ce not running的根因与修复

OceanBase状态矛盾排查:oceanbase-ce not running的根因与修复 如果你负责维护OceanBase 4.x集群大概率见过这个诡异场面用obd cluster status查看状态集群明明显示running但某个组件的oceanbase-ce偏偏变成了not running。我一开始也以为是界面没刷新后来被线上问题连续折腾了几次才意识到这个组合状态背后通常意味着节点上的observer进程已经“掉线”而OBD自身的状态判断机制又和真实进程状态存在错位两组信息互相矛盾特别容易误导人。这篇文章我直接把排查思路、常见坑位、处理命令和预防手段全部整理出来。不管你是刚接触OceanBase的新手还是已经被这个问题折磨过的运维老手照着下面的顺序走一遍基本能把根因揪出来。1. “running”与“not running”并存到底发生了什么首先要理解OBDOceanBase Deployer的状态输出逻辑。OBD在4.x版本中承担了集群部署、启停、状态查询和日常运维的入口职责。当我们执行obd cluster status 集群名时表格里会列出这个集群下所有组件在各个节点上的状态其中oceanbase-ce对应的就是数据库核心进程observer。这里有个关键点集群状态running和组件状态not running并不是同一个维度。OBD在计算“集群状态”时会综合所有组件的存活情况和运行标记但它的判断来源主要有两个第一个来源是进程存活探测。OBD会通过ssh到目标节点执行类似pgrep -f observer的检查或者直接调用observer提供的管理接口请求心跳。第二个来源是OBD自身的状态缓存文件。OBD会把之前一次成功的启停操作结果记录在本地元数据里方便快速展示。问题恰恰出在这里。当你看到oceanbase-ce is not running但集群状态还是running时最常见的解释是OBD对集群整体状态的判断依据了历史操作结果或部分节点的运行情况而对oceanbase-ce这个组件的状态判断却走到了实时探测分支于是两组结果对不上。另一种常见情况是OBD的实时探测出现了网络超时、ssh认证失败、免密登录失效等问题导致它没法准确拿到observer进程的真实状态于是保守地标记为not running。这时候集群里的observer进程可能还活得好好的业务读写也不受影响纯粹是OBD和节点之间的“通讯断了”。还有第三种可能也是我在实际环境里遇到最多的observer进程真的已经挂掉或处于“假死”状态。所谓“假死”就是进程还残留着但已经不对外服务日志里报各种内部错误OBD尝试和它做管理探活时拿不到响应于是判定为not running。而集群状态因为还有其他节点在正常服务observer的自动选举和多数派机制还在支撑集群对外仍然显示running实际已经进入了“降级”状态。所以这个报错本身不能直接告诉你根因你必须亲自去节点上确认进程、看日志、查资源才能定位问题。这也是我这篇文章想重点讲透的地方——不要凭状态字面意思下结论要看底层真实情况。2. 三步定位从进程到OBD状态的真实原因排查这个问题我习惯按照“进程是否存活”、“OBD通信是否正常”、“日志暴露什么线索”三个维度来推进。顺序不能乱因为只有先排除最基础的问题才能进一步分析复杂因素。2.1 第一步先看observer进程是不是真的“活着”在状态显示not running的那个节点上执行下面的命令ps -ef | grep observer | grep -v grep正常情况下你会看到类似这样的输出admin 12345 1 0 2024-01-01 ? 00:00:30 ./bin/observer -o ...如果进程列表里没有observer那说明进程确实已经退出。这时候不需要再看OBD那一层了问题根源就是进程没了接下来直接去查退出原因。如果进程还在那恭喜你问题大概率出在“进程存活但服务异常”或“OBD探测失败”这两类情况里。下一步就要验证observer进程对应的端口是否在监听netstat -lntp | grep 2881OceanBase observer默认会监听2881SQL客户端连接端口和2882内部RPC端口。如果2881端口没有监听说明进程虽然没被kill但内部网络层已经崩了这通常和observer启动参数、网络配置或资源异常有关。如果2881端口在监听那就说明observer大概率还在正常对外服务。这里补充一个细节observer进程的用户通常是admin或者部署时指定的用户不是root。如果你用root执行ps没看到记得切到对应用户再看一遍或者直接执行ps -ef | grep -v grep | grep observer用这个命令能看到完整信息避免权限导致的不必要误判。2.2 第二步区分“进程真死”和“状态误报”如果进程和端口都正常但OBD还是显示not running那就进入了“状态误报”的可能区间。这时候你要做两件事。第一件事检查OBD所在节点到observer节点的网络连通性。OBD通常是独立部署在一台机器上也可能是集群里某个节点它去探测observer节点时依赖ssh和TCP连接。你需要在OBD所在机器上手动执行类似这样的命令ssh admin目标节点IP echo ok如果ssh卡住、超时、提示认证失败说明OBD根本没法连接目标节点状态自然拿不到。常见原因是/root/.ssh/authorized_keys配置丢失或权限不对。known_hosts文件中目标节点的主机密钥变化导致ssh的StrictHostKeyChecking校验失败。目标节点sshd服务异常。第二件事检查配置文件config.yaml或cluster.yaml里的节点信息是否和实际环境一致。这个文件是OBD在部署集群时生成的里面记录了集群名称、组件类型、每个节点的IP、端口、用户名、路径等信息。如果节点IP调整过、observer端口改过、数据目录挪过位置但配置文件没更新OBD就会拿着旧信息去做探测结果当然是拿不到真实状态。我遇到过一个案例集群做过一次故障迁移observer从旧机器迁移到了新机器IP变了但配置文件里还写着旧IP。结果每次看状态都是not running实际新机器上observer跑得稳稳当当。改完配置文件里的IP再执行obd cluster reload状态立刻恢复正常。2.3 第三步日志才是最终的裁判当进程不存在或端口异常时不要急着重启先去翻日志。observer的日志目录通常位于安装目录下的log子目录默认路径类似/root/oceanbase/log/ /home/admin/oceanbase/log/里面最重要的文件是observer.log和alert.log。此外OBD自身也会记录操作日志一般位于~/.obd/log/obd.log在定位“oceanbase-ce is not running”时我一般按下面这个顺序查日志先看alert.log里面会有横向的错误告警信息比如磁盘空间不足、内存超限、内部选举超时等。再看observer.log的末尾分析observer进程在被杀掉或退出前做了什么。如果进程是被正常停止的日志里往往会留下明确的管理命令记录如果是被系统kill掉日志末尾可能没有特殊内容。最后看obd.log确认OBD在状态探测时是不是有报错比如ssh连接失败、超时等。查日志时推荐用tail和grep配合避免一次性打开巨大的日志文件。比如tail -n 200 /home/admin/oceanbase/log/observer.log或者搜索关键字grep -i error /home/admin/oceanbase/log/observer.log | tail -n 50日志里的时间信息很重要要和OBD显示not running的时间点做对比。通常Root Cause都会在状态异常前的几十秒内出现顺着时间轴往前回溯比漫无目的翻日志高效得多。3. 实际运维中我踩过的四个典型场景定位到具体原因后处理方式也不一样。我把这几年遇到过的典型场景梳理了一下每个场景背后的过程和解决思路都不太一样分享出来给大家参考。3.1 磁盘写满observer进程被“饿死”这是最高频的场景没有之一。OceanBase的observer进程运行时会持续写clog、sstable和临时文件如果数据目录所在磁盘写满触发了系统或内核的保护机制observer进程可能会直接退出或者进入只读状态无法恢复。排查手段很简单df -h df -i第一行看空间容量比例第二行看inode是否耗尽。很多朋友只看df -h忽略了inode耗尽的情况。一旦文件数量超过文件系统限制即使还有剩余空间也无法创建新文件observer写入clog时会直接报错。处理方式是清理过期日志、大文件、临时文件腾出空间然后启动observer。如果环境里的磁盘容量规划本身就吃紧建议及时做扩容并配置好磁盘空间告警不要把磁盘用满后再被动处理。3.2 内存不足进程被系统强制清理observer进程对内存的消耗比较大因为它要缓存大量数据以提高查询性能。如果宿主机内存不足触发OOM Killerobserver会是第一批被选中的进程这类问题在混合部署环境下特别常见。排查时可以看系统日志dmesg | grep -i oom journalctl -u systemd -f | grep -i oom如果确认是OOM导致就要调整observer的内存参数。在OceanBase 4.x中常见的内存参数包括memory_limit_percentage和system_memory。可以通过obd cluster edit-config来调整修改后执行obd cluster reload生效。一个比较稳妥的设置思路是observer的内存占用上限不要超过宿主机物理内存的70%到80%同时预留出一部分给OS文件缓存和其他进程。如果你所在环境还有监控agent、日志采集、备份任务等更要留出充足余量。3.3 节点IP或端口调整OBD与observer失联这类场景的特征非常明确observer进程在跑端口也在监听业务也能正常连接但OBD状态就是报not running。结合前文提到的排查思路大概率是配置文件和实际环境不一致。我之前遇到过一起集群中的一台机器因为网卡故障换了新网卡IP从192.168.1.10变成了192.168.1.20。observer进程在新的IP上正常监听但OBD的配置文件里还记录着旧IP导致探测全部失败。处理方式修改OBD配置文件中的节点IP保存。执行obd cluster reload 集群名让OBD重新加载配置。再次检查obd cluster status状态恢复正常。这种场景最坑的地方在于业务绕开了OBD这个管理入口直接用新的IP地址连接数据库所以业务侧完全没有感知只有运维侧会看到状态异常。建议每次变更IP、端口后都要同步更新OBD配置并把配置文件纳入版本管理。3.4 配置参数异常observer启动即退出如果observer进程进程崩溃、反复重启Elasticity的启动参数或配置文件有问题也会导致OBD探测不到稳定进程。常见的原因包括memory_limit配置超过实际物理内存observer启动时直接失败。data_dir或clog_dir目录不存在或权限不对。端口被占用observer无法绑定到指定端口。配置里出现了不支持的参数版本部分参数在4.x版本中已经变更。处理方式是先手动启动observer看报错cd /home/admin/oceanbase ./bin/observer -o ...执行后观察日志输出根据具体报错内容修正配置。如果端口被占用先确认是谁占用了端口再决定是否修改observer的监听端口或者释放端口。4. 恢复操作从快速重启到稳妥验证找到根因之后恢复操作要根据故障类型来选择。这里不是我建议什么都直接重启而是要有针对性地操作避免造成不必要的业务抖动。4.1 快速拉起obd cluster restart的适用场景如果observer进程确实已经退出且日志里没有明显的严重错误可以尝试用OBD快速拉起obd cluster start 集群名或者直接重启obd cluster restart 集群名obd cluster restart会对集群中所有组件执行重启代价是会造成所有节点上的数据库实例短暂中断。如果你是单机部署或测试环境这么操作没问题但如果是生产多节点集群我建议优先只重启异常节点或组件尽量减少影响面。如果执行obd cluster start后OBD提示oceanbase-ce已经存在但状态异常可以加--force参数强制重新拉起但使用之前要确认没有未提交事务或主备切换风险。4.2 只处理问题组件obd cluster start指定组件OBD支持只启动某个组件这一点很有用。命令格式如下obd cluster start 集群名 --components oceanbase-ce这个命令会只启动集群中的observer组件不会影响其他组件比如obproxy、oms等。如果你的集群里还有其他节点在正常运行这样可以避免重启全集群带来的不必要风险。还有一种情况是你只想在某个特定节点上启动observer那么可以使用--servers参数指定节点IPobd cluster start 集群名 --components oceanbase-ce --servers 192.168.1.20这种“定点恢复”的思路在生产环境里非常实用。它能最大程度保证集群对外可用性同时精准解决问题节点。4.3 reload与clean状态刷新时要小心的操作当你确认observer进程本身没问题只是OBD状态显示错误时优先使用reloadobd cluster reload 集群名这个命令会重新加载配置并尝试和observer重新建立管理连接刷新状态缓存。命令执行前建议先手动检查一遍端口和进程确保observer是真的健在否则reload后又会从not running变成“启动失败”。至于obd cluster clean这种操作一定要谨慎。这个命令会清理集群组件的数据目录直接执行会造成数据丢失。除非你非常明确自己在做什么比如测试环境重建集群否则不要轻易尝试。我在团队里给新同学培训时从来都是强调这个命令要打上“高危”标签。4.4 验证恢复如何确认集群真的健康无论用了哪种方式恢复最后都不能只看obd cluster status返回running就完事。我建议做下面几步验证obd cluster status 集群名确认所有节点的oceanbase-ce组件状态都是active。用SQL方式验证集群健康SELECT * FROM oceanbase.DBA_OB_SERVERS;这一步能确认所有observer节点是否都在正常工作STATUS字段是否为ACTIVE。还可以直接查看租户的副本状态SELECT * FROM oceanbase.DBA_OB_TENANTS;确认租户状态为NORMAL说明对外服务正常。如果有副本处于REBUILD或DISABLED状态说明可能还需要等待副本恢复或重新建副本。另外建议验证一下基本的DDL和DML操作执行一条简单的建表、插入、查询确认从中协调到分片的数据路径都是通的。只有这一整套走通我才放心把状态改回“正常”。5. 预防这类状态错位的经验清单处理完故障后如果不做预防过几个月大概率还会再来一遍。我总结了一套比较实用的预防经验可以最大程度避免“集群状态running但组件状态not running”这种闹心事。5.1 监控不能只看obd cluster statusOBD只是一个运维管理工具不能替代对数据库本身的监控。我建议无论集群大小都要配置一套完整的监控告警体系至少包含以下指标进程存活监控Zabbix、Prometheus或自研脚本对observer进程做探活。系统资源监控CPU、内存、磁盘空间、inode使用率。数据库层监控observer主备状态、租户状态、日志告警。进程和系统资源的监控可以第一时间发现observer进程退出而数据库层监控能追踪到内部异常。千万不要等到OBD状态出问题了才发现那时候很可能已经影响业务了。5.2 保留配置文件与操作日志的习惯OBD的配置文件是核心资产每次变更前先备份一份cp ~/.obd/cluster/集群名/config.yaml ~/.obd/cluster/集群名/config.yaml.bak.$(date %Y%m%d%H%M)这样即使改坏了也能快速回滚。OBD的操作日志默认会保留但日志轮转策略可能跟不上排查需求。建议定期检查日志目录大小避免日志把磁盘占满。5.3 定期更新OBD与补丁OBD本身也在迭代很多状态判断的逻辑bug会在后续版本中修复。如果你长期不更新OBD遇到模棱两可的状态信息就很被动。我通常每季度关注一次OceanBase官方发布版本评估后对OBD做例行升级。升级前也要做好兼容性检查确认新版本OBD支持当前的observer版本。升级操作最好先在测试集群演练一遍再进入生产环境。6. 最后再分享一个排障小技巧排查这类问题时有很多朋友习惯盯着obd cluster status刷新越刷越焦虑。我的建议是先别管OBD显示什么直接登录到节点上用ps、netstat、df、dmesg这几个命令把系统底层的实际情况摸清楚。系统层的数据不会说谎OBD的状态只是基于这些底层信息做的一次汇总和判断底层对了上层自然就对了。另外如果observer进程反复启动失败我强烈建议把--traceid打开用OceanBase特有的诊断链路去追踪问题根因。在命令行启动observer时加上./bin/observer -o ... --traceid日志里会打出一长串trace id后续在observer.log里搜索这个id可以串起整条内部执行链路比手工翻日志高效得多。还有一个容易被忽视的地方检查系统时间。如果节点之间的系统时间偏差过大可能导致observer之间的时钟同步失败进而引发内部选举异常OBD在探测时也会因为超时或握手失败而误判状态。建议给所有节点配置NTP同步确保时间一致性。这篇文章算是我在OceanBase运维路上的一个阶段性总结。每次遇到“oceanbase-ce is not running”这种和集群状态矛盾的报错我都会下意识地按照“看进程、看配置、看日志、再动手”的流程走一遍最后基本都能找到明确的原因。这次的分享也是希望能帮大家少走一些弯路把排查思路固化下来下次再遇到就能从容应对了。
返回列表