前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >OB 运维 | OB4.X-Follower 节点时钟偏差导致合并卡住?

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

作者头像
爱可生开源社区
发布2024-10-21 15:02:23
发布2024-10-21 15:02:23
8300
代码可运行
举报
运行总次数:0
代码可运行
作者:郑增权,爱可生 DBA 团队成员,OceanBase 和 MySQL 数据库技术爱好者。

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

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 租户。

代码语言:javascript
代码运行次数:0
运行
复制
select * from __all_tenant;

查看租户级合并信息

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

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

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

代码语言:javascript
代码运行次数:0
运行
复制
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)。

代码语言:javascript
代码运行次数:0
运行
复制
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 卡住了合并。

代码语言:javascript
代码运行次数:0
运行
复制
select * from cdb_ob_zone_major_compaction;

查看合并诊断信息

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

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

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

代码语言:javascript
代码运行次数:0
运行
复制
 select * from __all_virtual_compaction_diagnose_info where  create_time >= '2024-06-12%';

确认存储层合并是否完成

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

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

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

代码语言:javascript
代码运行次数:0
运行
复制
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,可以看到不存在仍在运行的合并任务。

代码语言:javascript
代码运行次数:0
运行
复制
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
代码语言:javascript
代码运行次数:0
运行
复制
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 副本版本尚未推高至当前合并版本号。

代码语言:javascript
代码运行次数:0
运行
复制
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 的合并。

代码语言:javascript
代码运行次数:0
运行
复制
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已经冻结。

代码语言:javascript
代码运行次数:0
运行
复制
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
代码语言:javascript
代码运行次数:0
运行
复制
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

代码语言:javascript
代码运行次数:0
运行
复制
grep "REPORT: batch update tablets" observer.log | grep "ret=-" 

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

代码语言:javascript
代码运行次数:0
运行
复制
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。

代码语言:javascript
代码运行次数:0
运行
复制
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 了,导致线程被暂停。
代码语言:javascript
代码运行次数:0
运行
复制
grep "YB420ABA40A3-00061A354A6E3DD4-0-0" observer.log* | grep "packet wait too much time"

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

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

代码语言:javascript
代码运行次数:0
运行
复制
clockdiff 10.186.64.160

5解决方法

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

1. 将时间回调正常

代码语言:javascript
代码运行次数:0
运行
复制
systemctl stop ntpd
date && ntpdate 10.186.64.160 && date
systemctl start ntpd && systemctl status ntpd
clockdiff 10.186.64.160

2. 查看合并状态

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

代码语言:javascript
代码运行次数:0
运行
复制
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# #时间偏差#

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 爱可生开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1背景
  • 2环境信息
  • 3视图排查
    • 查看集群租户信息
    • 查看租户级合并信息
    • 查看租户角色信息
    • 查看各租户 compaction_scn 小于 GLOBAL_BROADCAST_SCN 的信息
    • 查看 ZONE 级合并信息
    • 查看合并诊断信息
    • 确认存储层合并是否完成
  • 4日志排查
    • 1. 查看是否存在 tablet 版本尚未推高至当前合并版本号
    • 2. grep 前方复制的 tarce_id : 查看详细信息
    • 3. 确认 Tablet 对应租户是否发起了版本号为 broadcast_scn 的合并。
    • 4. 确认 zone3 合并前的转储 memtable 是否冻结
    • 5. 确认 zone3 转储是否成功生成了对应的转储/合并 sstable
    • 6. 租户合并信息汇报确认
    • 7. grep 复制的 trace_id,可以看到存在向 __all_tablet_meta_table 汇报失败的行为
    • 8. 在 trace_id 中检索关键字 "original error message",看它对应的远端地址(remote_addr) 是哪个OBServer节点
    • 9. 根据提示到 remote_addr ( 10.186.64.161) 的 observer.log 中检索当前的trace_id
    • 10. 查看与时钟源的时间差
  • 5解决方法
    • 1. 将时间回调正常
    • 2. 查看合并状态
  • 6结论
  • 7优化措施
    • 温馨提示
    • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档