OB 运维 | OB4.X-Follower 节点时钟偏差导致合并卡住?

科技   科技   2024-10-15 16:30   上海  

作者:郑增权爱可生 DBA 团队成员,OceanBase 和 MySQL 数据库技术爱好者。

爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。

本文约 1300 字,预计阅读需要 5 分钟。



1背景

某客户由于 OBServer 机器(租户 Follower 节点)发生过重启,且时钟同步服务未自动启动,导致此机器时间比时钟源落后 60s+!

集群合并时,发现时间落后的 OBServer 所在的 zone3 一直处于 COMPACTING 状态,合并无法完成。本文复现问题(步骤略)并记录排查过程。

环境说明:客户发生故障的环境为 OB 社区版,本文基于 OB 企业版复现,两版本均可复现。

2环境信息

  • OceanBase: 4.2.1.4
  • 架构:1-1-1
  • zone1: 10.186.64.161 (RS Leader)
  • zone2: 10.186.64.162
  • zone3: 10.186.64.163
  • 时钟源: 10.186.64.160

3视图排查

查看集群租户信息

集群存在 5 个租户,其中 1001 和 1003 是 META 租户。

select * from __all_tenant;

查看租户级合并信息

LAST_SCN 表示上一轮已完成合并的版本号,GLOBAL_BROADCAST_SCN 表示当前这一轮全局广播的合并版本号。

  • LAST_SCN == GLOBAL_BROADCAST_SCN:当前轮次的合并已经结束

  • LAST_SCN != GLOBAL_BROADCAST_SCN:当前轮次的合并尚未结束。若长时间合并未结束,则可能是合并卡住了。

当前所有租户均处于合并卡住的状态。

select * from cdb_ob_major_compaction;

查看租户角色信息

若当前合并处于卡住状态(本文状态),直接查看卡住的租户 1 号日志流的 Leader 在哪个机器上。

若当前不处于合并卡住状态,则需找到合并卡住的租户的 1 号日志流切主历史。从切主历史中,找到需要排查的时间段内,租户的 1 号日志流的 Leader 在哪台机器上再进行排查。

可以看到租户 1 号日志流的 Leader 节点都在 10.186.64.161。

查看各租户 compaction_scn 小于 GLOBAL_BROADCAST_SCN 的信息

RS 端判定合并结束的主要流程:检查每个 zone 中的 tablet 版本号是否皆已推高至当前合并版本号,如果是,则更新 __all_zone_merge_info 内部表中对应 zone 的 last_merged_scn 并将 is_merging 置为 false。

__all_tablet_meta_table 存在于 SYS/META 租户下:比如要查 1004 租户下的某个 tablet,需要先切至其 META 租户才能查到 1004 的 tablet meta 信息( SYS 租户 2881 直连登陆后:alter system change tenant META$1004;)。

meta 表目前实现了对应的虚拟表 __all_virtual_tablet_meta_table,通过虚拟表查询则不需要切换租户。

下图可以看到有大量的 tablet 版本号未推高至当前合并版本号,导致合并卡住,需要进一步排查存储层为何尚未将这些 tablets 的版本推高至当前合并版本号(GLOBAL_BROADCAST_SCN)。

select count(*) from __all_virtual_tablet_meta_table where tenant_id = 1    and compaction_scn < 1718165680404973713;
select count(*) from __all_virtual_tablet_meta_table where tenant_id = 1001 and compaction_scn < 1718165680509150848;
select count(*) from __all_virtual_tablet_meta_table where tenant_id = 1002 and compaction_scn < 1718165680443836989;
select count(*) from __all_virtual_tablet_meta_table where tenant_id = 1003 and compaction_scn < 1718165680590612402;
select count(*) from __all_virtual_tablet_meta_table where tenant_id = 1004 and compaction_scn < 1718165680471683591;

查看 ZONE 级合并信息

可以看到是 zone3 卡住了合并。

select * from cdb_ob_zone_major_compaction;

查看合并诊断信息

RS_UNCOMPACTED:不一定存在异常。说明还存在 tablet 版本尚未推高至当前合并版本号,可以先通过 GV$OB_COMPACTION_PROGRESS 判断是否处于正常合并进行的状态。

如果还有 RUNNING 的合并,则大概率是合并任务的问题。

这里可以看到存在 tablet 数据快照版本号未更新的情况(compaction_scn_not_update)。

 select * from __all_virtual_compaction_diagnose_info where  create_time >= '2024-06-12%';

确认存储层合并是否完成

TABLET_COMPACTION_FINISHED:代表存储层合并已完成。

可以看到每个租户所有 zone 存储层均已完成合并,但 RS 未完成后续操作导致合并卡住。

结合前方排查信息,RS 未进行后续操作的原因是存在 tablet 数据快照版本号未更新,需要进一步排查为何数据快照版本号(compaction_scn)未更新的原因。

select * from __all_virtual_server_compaction_event_history where tenant_id = 1    and compaction_scn = 1718165680404973713 and event like '%FINISHED%' order by zone;
select * from __all_virtual_server_compaction_event_history where tenant_id = 1001 and compaction_scn = 1718165680509150848 and event like '%FINISHED%' order by zone;
select * from __all_virtual_server_compaction_event_history where tenant_id = 1002 and compaction_scn = 1718165680443836989 and event like '%FINISHED%' order by zone;
select * from __all_virtual_server_compaction_event_history where tenant_id = 1003 and compaction_scn = 1718165680590612402 and event like '%FINISHED%' order by zone;
select * from __all_virtual_server_compaction_event_history where tenant_id = 1004 and compaction_scn = 1718165680471683591 and event like '%FINISHED%' order by zone;

查看 GV$OB_COMPACTION_PROGRESS,可以看到不存在仍在运行的合并任务。

select * from GV$OB_COMPACTION_PROGRESS where status != 'FINISH';

排查至此我们发现从相关视图中可以找到的信息比较有限,转入日志排查,尝试寻找合并卡住的具体原因。

4日志排查

1. 查看是否存在 tablet 版本尚未推高至当前合并版本号

由于合并服务注册在每个租户 1 号日志流的 Leader上,前方已查出在 10.186.64.161 ,查看此机器的日志。

在 10.186.64.161 执行如下语句,定位未成功合并的分区。

  • tail -10 为可选项,避免打印信息过多
  • 我们复制一个 trace_id 用于后续排查,此处我们选择 sys 租户的 trace_id
grep --color=always "replica not merged" rootservice.log | tail -10

2. grep 前方复制的 tarce_id : 查看详细信息

zone1 和 zone2 的 unmerged_cnt=0,说明所有 tablet 副本版本都已推高至当前合并版本号。

zone3 的 unmerged_cnt=891,说明 zone3 中还有 891 个 tablet 副本版本尚未推高至当前合并版本号。

grep "YB420ABA40A1-00061A34C8AC5770-0-0" rootservice.log* | grep --color=always "unmerged_cnt" |  grep --color=always -E "zone1|zone2|zone3"

3. 确认 Tablet 对应租户是否发起了版本号为 broadcast_scn 的合并。

可以看到卡住的租户都发起了版本号等于 broadcast_scn 的合并。

grep "try to schedule merge" observer.log.202406121* | grep --color=always  "tenant_id" | grep --color=always "scn:{val:"

4. 确认 zone3 合并前的转储 memtable 是否冻结

需要确认 memtable 的 snapshot version 是否大于本次合并的版本号,如果小于,则说明备机读时间戳没有推过冻结点。

  • 若没有日志,说明 memtable 没有冻结。
  • tail -1 为可选项,避免打印信息过多,实际排查请去掉

可以看到  memtable 的 snapshot version 大于对应租户本次合并的版本号 ,即 zone3 合并前的转储 memtable已经冻结。

grep --color=always "ready for flush" observer.log* | grep -w T1    | grep --color=always -w "snapshot_version:{val" | tail -1
grep --color=always "ready for flush" observer.log* | grep -w T1001 | grep --color=always -w "snapshot_version:{val" | tail -1
grep --color=always "ready for flush" observer.log* | grep -w T1002 | grep --color=always -w "snapshot_version:{val" | tail -1
grep --color=always "ready for flush" observer.log* | grep -w T1003 | grep --color=always -w "snapshot_version:{val" | tail -1
grep --color=always "ready for flush" observer.log* | grep -w T1004 | grep --color=always -w "snapshot_version:{val" | tail -1

5. 确认 zone3 转储是否成功生成了对应的转储/合并 sstable

可以看到存在 4012 报错的 MINI_MERGE

  • MINI_MERGE:表示转储,冻结 MemTable 通过转储变成 Mini SSTable
grep "sstable merge finish" observer.log* | grep -v "ret=0"  | grep --color=always "ret="

复制 trace_id 检索,确认此处转储最终状态是否为成功。

  • 此处结果显示报错的转储最终是成功的,即转储全部成功生成了对应的转储/合并 sstable

6. 租户合并信息汇报确认

__all_tablet_meta_table 表存在于 SYS/META 租户下,即 SYS 租户或 META 租户会向 __all_tablet_meta_table 表汇报合并信息(普通租户需切至对应的 META 租户进行汇报),我们主要基于 tenant_id 为 1、1001、1003 这三个租户来看下是否汇报成功。

取一条租户汇报失败的语句,复制其 trace_id

grep "REPORT: batch update tablets" observer.log | grep "ret=-" 

7. grep 复制的 trace_id,可以看到存在向 __all_tablet_meta_table 汇报失败的行为

grep "YB420ABA40A3-00061A354A6E3DD4-0-0" observer.log* | grep "__all_tablet_meta_table" | grep errcode | grep compaction_scn | head -1

可以看到 1001 租户 在发起对应的 GLOBAL_BROADCAST_SCN(1718165680509150848 )汇报时遭遇 6210 超时报错。

汇报超时:OB_TRANS_TIMEOUT。

8. 在 trace_id 中检索关键字  "original error message",看它对应的远端地址(remote_addr) 是哪个OBServer节点

可以看到 remote_addr 是 10.186.64.161。

grep "YB420ABA40A3-00061A354A6E3DD4-0-0" observer.log* | grep "original error message"

9. 根据提示到 remote_addr ( 10.186.64.161) 的 observer.log 中检索当前的trace_id

报错 :PNIO packet wait too much time between proxy and server_cb 可能是如下四种情况导致:

  1. 两台机器之间时钟不同步,使用 clockdiff IP 命令来确认。
  2. 网络延迟大,通过 ping 大包来确认。
  3. 系统负载高导致,网络、CPU、内存使用异常。
  4. OBServer 进程被 gdb 或者 pstack 了,导致线程被暂停。
grep "YB420ABA40A3-00061A354A6E3DD4-0-0" observer.log* | grep "packet wait too much time"

10. 查看与时钟源的时间差

可以看到 zone3 的 OBServer 机器与时钟源存在落后 65s 的时间偏差。

clockdiff 10.186.64.160

5解决方法

  1. 将租户 leader 切至 zone3 所在的 OBServer 节点(临时解决,不建议)。
  2. 将 zone3 所在 OBServer 节点系统时间调整为正确时间(合理解决,建议),本文采用。

1. 将时间回调正常

systemctl stop ntpd
date && ntpdate 10.186.64.160 && date
systemctl start ntpd && systemctl status ntpd
clockdiff 10.186.64.160

2. 查看合并状态

可以看到 zone3 已经合并成功。

select * from cdb_ob_zone_major_compaction;

6结论

合并卡住的原因是更新 __all_tablet_meta_table 系统表 OB_TRANS_TIMEOUT (超时),zone3 上各分区的新 major sstable 已生成,但是由于时间偏差(zone3 节点 OBServer 机器时钟落后 65s),zone3 无法将 compaction_scn 汇报到 __all_tablet_meta_table 表,导致 RS 判断合并未完成,zone3 合并状态一直处于 COMPACTING 状态。

7优化措施

  1. 合理配置时钟源和时钟服务自启动
  2. 关注时钟延迟相关告警信息

温馨提示

可以使用 obdiag 或者 OBStack 进行合并卡住问题分析

参考资料

  1. 《如何排查合并卡住问题》:https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000685150?back=kb
  2. 《OceanBase 数据库 V4.x 版本 RS 端合并卡住排查手册》:https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000816610?back=kb
  3. 《如何调整 OBServer 的操作系统时间》:https://www.oceanbase.com/knowledge-base/oceanbase-database-20000000070?back=kb
  4. 《compaction_diagnose 视图使用指南》:https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000209906?back=kb
  5. 《OceanBase 数据库中启用 pkt-nio 功能时 RPC 的 fly_ts 耗时长的原因》:https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000699896?back=kb

本文关键字:#OceanBase# #时间偏差#


一文讲透 OceanBase 单机版【建议收藏】
如何有效使用 outline 功能?
OceanBase 4.X-2F1A 仲裁高可用方案初探
Oracle 中部分不兼容对象迁移到 OceanBase 的处理方式
一个关于 NOT IN 子查询的 SQL 优化案例
Join 估行不准选错执行计划该如何优化?
一个提升本地索引性能的 SQL 优化案例
一则 Oracle 迁移到 OB 后存储过程语法报错问题诊断案例
优化器走对,执行计划导致查询快 1000 倍
如何通过日志观测冻结转储流程?


✨ Github:https://github.com/actiontech/sqle

📚 文档:https://actiontech.github.io/sqle-docs/

💻 官网:https://opensource.actionsky.com/sqle/

👥 微信群:请添加小助手加入 ActionOpenSource

🔗 商业支持:https://www.actionsky.com/sqle


爱可生开源社区
爱可生开源社区,提供稳定的MySQL企业级开源工具及服务,每年1024开源一款优良组件,并持续运营维护。
 最新文章