OceanBase 数据库是一个分布式数据库,分区要正常提供读写服务,必须选出一个 Leader,整个选主的流程大致如下:
- OceanBase 数据库的选举块选出副本 Leader。
- Clog 模块从选举模块得知当前 Leader,Leader 在上任前执行 Clog reconfirm 过程, 确保数据是最新的。
- Leader 执行 Takeover 等操作后,正式上任。 如果新主从 OceanBase 数据库选举模块已经被选出,但是 Clog reconfirm 由于一些原因导致失败了,那最终对应的数据分区也是无法提供数据服务。 Clog reconfirm 过程的主要目的是对于滑动窗口中遗留的未确认日志进行重确认,并同步给 Follower 副本。OceanBase 数据库在事务提交的过程中,如果 Clog 已经成功同步到了多数派,事务就已经提交成功,若此时 Leader 宕机,有可能还在线的副本里就有 Clog 还未完成确认回放到 MemTable。那么 Clog reconfirm 就保证了在 Leader 切换的场景下,所有副本的 Clog 都已经完成了确认,还可以保证多数派的 Clog 同步一致状态,保证接下来的事务提交不受影响。Clog reconfirm 过程包含如下几个阶段:
| 阶段 | 阶段名称 | 阶段动作 |
|---|---|---|
| 1 | INITED 阶段 | 尝试将已确认日志提交回放,本地写 prepare 日志和本次Leader选举的标记信息。 |
| 2 | FLUSHING_PREPARE_LOG 阶段 | 发送 Leader 选举的标记信息给所有 Follower,等待 follower回复各自的日志,收到多数派回复后进入下个阶段。 |
| 3 | FETCH_MAX_LSN 阶段 | 等待副本最大提交日志 max_flushed_log_id 达到了多数派(含自己),则统计收到的最大 max_flushed_id 值,并做一些准备工作。 |
| 4 | RECONFIRMING 阶段 | 首先尝试将滑动窗口左侧已确认的 log 从滑动窗口滑出并提交回放,直到遇到第一条未确认 log 为止,然后对所有未确认日志执行重确认过程,即从多数派成员收集、确定该日志内容,然后同步给所有 follower;最后进入 START_WORKING 状态,写一条 start_working 日志。 |
| 5 | START_WORKING 阶段 | 等待 start_working 日志形成多数派。 |
| 6 | FINISHED 阶段 | 结束。 |
在上面 6 阶段中的关键阶段会将日志打印到 observer.log,例如: 阶段 2 收到多数派的回复的标志日志是(如果无法看到该日志说明本阶段被卡住了):
[20XX-XX-XX 20:28:06.142985] INFO [CLOG] ob_log_reconfirm.cpp:598 [127240][Y0-0000000000000000] [lt=25] max_log_ack_list majority(partition_key={tid:1099511627777, partition_id:0, part_cnt:1}, majority_cnt=2, max_log_ack_list=1{server:“10.101.XXX.XXX:261XXX”, timestamp:-1, flag:0})
单条 Clog reconfirm 过程的超时时间是 10s,即如果 10s 没有执行完会打印 ERROR 级别的超时日志,关键字为 is_reconfirm_role_change_or_sync_timeout。Clog reconfirm 通常由于卡在如上各个阶段而超时,卡住的原因主要有:无法提交回放、网络不通、日志盘满等。 Clog reconfirm 卡住的主要原因和关键日志信息有
| 主要原因 | 原因解释 | 关键日志及诊断方法 |
|---|---|---|
| Clog 回放卡住 | reconfirm 过程中需要将滑动窗口左侧已经确认的日志全部提交回放,一旦回放由于各种异常(内存分配失败、回放出错)卡住的话,滑动窗口就会发生积压,积压的日志数量达到阈值(目前是 2万)后,滑动窗口就满了,无法接收新的日志,reconfirm 也就无法正常执行下去。 | 如果滑动窗口中有已确认的日志需要提交回放,则可以看到 observer.log CLOG 模块报 [ERROR] 级别错误码 -4023,日志的关键字是:there are confirmed logs in sw, try again(partition_key={tid:1106108697592670, partition_id:0, part_cnt:1}, ret=-4023, new_start_id=371801833, start_id=371802703)回放卡主的原因可能很多,诸如 alloc memory failed 这样的内存分配错误、replay error 这种回放错误。需要进一步通过 observer.log 进行排查 grep ERROR observer.log | grep STORAGE | grep 'alloc memory' 、 grep ERROR observer.log | grep STORAGE | grep replay |
| Clog 满盘 | Clog reconfirm 过程中需要写 prepare、start_working 等日志,且需要达成多数派确认,如果 Server 的 Clog 盘满了导致无法写这些日志,且余下的正常 Server 不够多数派,那么 reconfirm 也会失败。 | 如果 Clog 发生满盘,observer.log 里 CLOG 模块报 [ERROR] 级别错误码 -4264, 日志的关键字是:log outof disk space(partition_key={tid:1102810162709414, partition_id:46, part_cnt:0}, server=“xx.xx.xx.xx:29432”, ret=-4264, free_quota=-3381817344) |
| Clog 同步网络不通 | Clog reconfirm 过程中候选 Leader 需要与各个 Follower 在多个阶段进行通信,因此如果网络出现问题,导致无法收发包或收发包延迟太大也可能导致 reconfirm 失败。 | 网络不通会导致 reconfirm 多个阶段均会失败,比如发送完 PREPARE 日志后一直收不到 Follower 的回复,会导致本机一直打印如下关键字的日志直至超时失败:max_log_ack_list not majority后续的写 start_working 日志也可能由于网络异常而导致无法收到多数派 ack,进而超时失败。 很多原因可能导致网络不通,排查步骤:
|
| 500 租户请求队列堆积 | 如果 500 请求队列发生堆积,无法处理新的 RPC 请求,reconfirm 相关的消息处理也会停滞 Leader 端日志显示,Follower 一直没有回复任何请求。这个时候需要进一步分析队列堆积情况和队列堆积原因。 | 查看队列堆积情况:搜索 Leader/Follower 的 observer.log,关键字是 dump tenant info(tenant={id:500, , 通过搜索关键字,可以看到 500 租户的队列情况,其中 req_queue 字段后跟的内容就是队列情况。通常在看出 500 租户队列请求队列堆积的情况下还需要一进步分析队列堆积的原因,这时候可以用 obstack 来打印当前的 OBServer 节点堆栈信息,并将信息一并发给 OceanBase 数据库技术支持进行问题诊断。 |
| 工作线程不足 | - | 看是否存在如下 easy 包处理超时的日志:[20XX-XX-XX 11:12:12.103] easy_request.c:420(tid:7fe2cdc9f700)[57136] rpc time, packet_id :2425446521, pcode :4096, client_start_time :1517541127590356, start_send_diff :8, send_connect_diff: 0, connect_write_diff: 5, request_fly_ts: 188, arrival_push_diff: 2, wait_queue_diff: 4508603, pop_process_start_diff :2, process_handler_diff: 4184, process_end_response_diff: 1, response_fly_ts: 447, read_end_diff: 1, client_end_time :1517541132103797, dst: 10.101.X.X:XXXXX可以看到 wait_queue_diff 达到了几秒级别,说明工作线程处理比较慢,检查 cpu_quota (cpu_quota_concurrency、workers_per_cpu_quota、system_cpu_quota)相关配置项是否配置过小。 |
如果根据以上诊断方法无法排查出 Clog reconfirm 失败的原因,那么请联系 OceanBase 数据库技术支持进行诊断。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




