作者:关炳文,爱可生 DBA 团队成员,负责数据库相关技术支持,一步两阶梯,兼具勤奋与慵懒。
爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
本文约 1100 字,预计阅读需要 3 分钟。
前一阵,我们介绍了 OceanBase 增量日志代理服务(OBLogProxy)的一则故障案例:《OBLogProxy 在 Binlog 模式下的故障案例解析》,本期我们将介绍另一个相关案例。以下是正文内容。
1. 背景
曾经在某客户环境中部署的 OBLogProxy[1] 服务并未使用。最近因扩容重启主机,需要手动重启该服务。服务启动成功,但是 show binlog status
展示的 pid
为 0
,并且 Binlog 日志从三个月前至今无新增。
服务启动日志如下。
[root@oblogproxy oblogproxy]# ./run.sh start
DEPLOY_PATH : /usr/local/oblogproxy
is_running : (6347)/usr/local/oblogproxy logproxy is running!
kill_proc : (6347)/usr/local/oblogproxy succ!
./run.sh: line 53: 6347 Terminated ./bin/${BIN} -f ./conf/conf.json &>${log_path}/out.log
is_running : (7735)/usr/local/oblogproxy logproxy is running!
logproxy started复制
2. 故障分析
2.1 OBLogProxy 状态检测
直连 OBLogProxy 服务,检查服务状态。
mysql -h 'IP' -P 2983
show Binlog instances\G复制

根据上图可知,running
、obcdc_running
和 convert_running
三列分别标识 binlog 实例主进程、obcdc 进程 和 converter 进程 的运行状态。
三者均为 Yes 时,表示 Binlog 实例运行正常,否则即表示相应组件的运行状态异常。
继续检查 Binlog converter(bc)进程,该进程负责拉取和解析 Clog ,并转换为 Binlog 文件。
执行以下命令,可以看到 bc 进程并未启动,则需要从日志中去查找原因。
[root@oblogproxy ~]$ ps -ef|grep binlog_converter
root 30687 29844 0 17:16 pts/1 00:00:00 grep --color=auto binlog_converter复制
2.2 日志分析
2.2.1 查看 bc 进程日志
bc 进程日志文件是 oblogproxy/run/$cluster_name/$tenant_name/log/binlog_converter.log
。
[2025-02-24 10:33:14] [critical] obcdc_access.cpp(96): Failed to init libobcdc, ret: -4018
[2025-02-24 10:33:14] [error] binlog_converter_entry.cpp(66): !!! Exit binlog converter process with pid: 24479
[2025-02-24 10:33:14] [warning] thread.cpp(37): The current thread :(24482) has already stopped
[2025-02-24 10:33:14] [warning] thread.cpp(37): The current thread :(24482) has already stopped复制
从日志中发现,bc 进程在启动后很快就退出了,原因是 libobcdc 初始化失败,错误代码 4018。
这在 OceanBase 中通常原因是读取数据不存在,此时可以初步猜测 bc 进程拉取日志阶段发生了异常。libobcdc 是 C++ 动态库,负责从 OceanBase 集群中拉到的增量日志按事务提交顺序向外透出。那么我们需要继续从 libobcdc 日志里找出初始化失败的原因。
2.2.2 查看 libobcdc 日志
libobcdc 日志文件是 oblogproxy/run/$cluster_name/$tenant_name/log/libobcdc.log
。
[2025-02-24 10:33:11.551061] WDIAG [TLOG] get_data_dict_in_log_info (ob_log_meta_data_queryer.cpp:49) [24479][][T0][Y0-0000000000000000-0-0] [lt=45][errcode=-4018] can't find datadict snapshot_scn older than start_timestamp_ns(ret=-4018, ret="OB_ENTRY_NOT_EXIST", tenant_id=1006, start_timestamp_ns=1733201736158282000)
[2025-02-24 10:33:11.551097] WDIAG [TLOG] get_data_dict_in_log_info_ (ob_log_meta_data_service.cpp:375) [24479][][T0][Y0-0000000000000000-0-0] [lt=34][errcode=-4018] sql_queryer get_data_dict_in_log_info fail(ret=-4018, ret="OB_ENTRY_NOT_EXIST", tenant_id=1006, start_timestamp_ns=1733201736158282000, data_dict_in_log_info={snapshot_scn:-1, end_scn:-1, start_lsn:{lsn:18446744073709551615}, end_lsn:{lsn:18446744073709551615}})
[2025-02-24 10:33:11.551149] ERROR issue_dba_error (ob_log.cpp:1875) [24479][][T0][Y0-0000000000000000-0-0] [lt=26][errcode=-4388] Unexpected internal error happen, please checkout the internal errcode(errcode=-4018, file="ob_log_meta_data_service.cpp", line_no=389, info="[FATAL][DATA_DICT] Can't find suitable data_dict to launch OBCDC, please try use online schema(refresh_mode=online && skip_ob_version_compat_check=1)")复制
在日志中搜索关键字 error,发现报错内容 can't find datadict snapshot_scn older than start_timestamp_ns,意味着下游请求位点的时间戳 1733201736158282000
没有找到对应可消费的 Clog 记录。
登录集群 sys
租户,查询各个日志流最小可消费位点中的最大值和开启归档的时间,与请求位点进行对比,请求位点至少需要大于前面两者的最小值。
obclient [oceanbase]> SELECT CEIL(MAX(BEGIN_SCN)/1000) AS START_TS_US FROM oceanbase.GV$OB_LOG_STAT;
+------------------+
| START_TS_US |
+------------------+
| 1737628799517391 |
+------------------+
1 row in set (0.004 sec)
MySQL [(none)]> SELECT CEIL(MAX(START_SCN)/1000) as START_TS_US FROM oceanbase.DBA_OB_ARCHIVELOG;
+------------------+
| START_TS_US |
+------------------+
| 1733387084685441 |
+------------------+复制
-------->请求位点
[root@ob log]# date -d @1733201736
Tue Dec 3 12:55:36 CST 2024
-------->日志流最小可消费位点
[root@ob log]# date -d @1737628799
Thu Jan 23 18:39:59 CST 2025
-------->归档开始时间
[root@ob log]# date -d @1733387084
Thu Dec 5 16:24:44 CST 2024复制
对比结果:请求位点 < min(日志流最小可消费位点,归档开始时间)
结论
OBLogProxy 服务重启后需要拉取的断点是从 2024 年 12 月 03 号开始的,而归档开始时间是 2024 年 12 月 05 号,OBLogProxy 无法获取上游可消费数据导致服务启动后异常。
处理方法
释放并重建 Binlog 任务。 指定租户的所有 Binlog 实例,同时删除已生成的存量 Binlog 文件。重建 Binlog 任务后,binlog_converter
进程便会以当前时间从上游拉取和解析 Clog。
1. 登录 Binlog Server。
mysql -h $IP -P2983
2. 释放 Binlog 任务。
DROP Binlog FOR TENANT $cluster_name.$tenant_name;
3. 创建 Binlog 任务。
CREATE BINLOG FOR TENANT $cluster_name.$tenant_name TO USER $username PASSWORD `xxx` WITH CLUSTER URL '$obconfig_url';
4. 查看所有 Binlog 实例状态信息。
SHOW Binlog INSTANCES;
预期状态:running、obcdc_running 和 convert_running 三列的值均为yes。复制
拓展阅读
《如何判断启动时间戳是否过小?》[2]
《如何重建 Binlog 任务?》[3]
oblogproxy: https://www.oceanbase.com/docs/community-oblogproxy-doc-1000000000861451
[2]《如何判断启动时间戳是否过小?》: https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013720
[3]《如何重建 Binlog 任务?》: https://www.oceanbase.com/docs/community-oblogproxy-doc-1000000001999434
本文关键字:#OceanBase# #oblogproxy# #clog# #binlog#
✨ Github:https://github.com/actiontech/sqle
📚 文档:https://actiontech.github.io/sqle-docs/
💻 官网:https://opensource.actionsky.com/sqle/
👥 微信群:请添加小助手加入 ActionOpenSource
🔗 商业支持:https://www.actionsky.com/sqle