背景
WRS 目前主要使用场景有三种:
- 弱读:通过获取租户级别 WRS version 作为快照进行读取。
- 备份恢复:租户从 restore 转换为 standby 后,读取内部表获取所有日志流可读点的最小值,作为获取 schema 的快照点。
- 冻结、转储和合并
- 冻结时获取 WRS 作为 memtable 的右边界并写入 memtable。
- 转储时等到 end log ts 推过 WRS。
- 合并时等待 WRS 推过合并点。
当 WRS 出现异常时,可能导致备份恢复状态无法推进、内存爆满和 clog 盘爆满等问题。
适用版本
OceanBase 数据库 V4.x 版本。
引发问题的可能原因
wrs 线程卡住
WRS 是 server 级别的后台线程,遍历所有租户的所有日志流。当被一个日志流卡住时,后续租户和日志流不会被遍历。未来将优化处理,拆分为租户级别且使用 try lock 保证遍历。
回放报错\事务无法推进
日志流 WRS 通过以下两部分计算取最小值:
日志当前连续回调的最大 log ts(leader 写日志时回调,follower 上是回放)。
所有进入 prepare 阶段的事务中最小的 prepare version。
当回放卡住或事务长时间未结束时,会影响 WRS 的推进。
无主
当日志流无主,不会产生日志和事务,WRS 无法推进。此时需排查无主的原因。
排查步骤
确定问题租户和日志流。
通过查询
__all_virtual_ls_info判断是否有主。 如果无主则可以参考以下文档排查无主原因。判断 WRS 状态
查看
__all_virtual_ls_info中的 weak_read_scn 判断 WRS 状态。weak_read_scn = 0:可怀疑 WRS 线程被卡住。使用 obstack 获取 WRS 线程状态。
线程名:Txxxx_Weakweak_read_scn 有效但无法推进。
检查 WRS 定期打印的日志,确认 WRS 是否正常工作。
grep -rn "get wrs ts" ./observer.log | vim -如果日志正常打印,通过 get wrs ts 日志中的 min_tx_service_ts 判断是否是由于事务一直未推进造成无法更新。
TRANS_LOG(INFO, "get wrs ts", K(ls_id), K(timestamp), K(min_tx_service_ts));- 若
timestamp = min_tx_service_ts,则怀疑事务长期未结束。 - 否则查看回放线程状态,是否因为回放卡住导致。
- 若
如果日志未正常打印,则使用 obstack 获取 WRS 线程状态,查看 WRS 线程是否卡住。