本文介绍了如何确认无主状态,以及造成无主的原因的排查方法。
适用版本
OceanBase 数据库所有版本
问题描述
OceanBase 在正常状况下是不会出现副本无主的情况的。在运维过程中如果直接将 OB 的多数派副本所在的机器进行宕机,会造成副本无主,这是符合预期的行为,应当继续执行运维动作,无需干预。但是如果在 OceanBase 正常运行的过程中,OceanBase 的数据副本产生了无主的情况,是需要进行问题排查的。当副本出现了无主的现象,在 observer.log 中可以发现在调用时返回 -4038、-7006 的报错,表明需要进一步诊断OB无主的原因。
问题排查思路
在进行问题排查时,首先要确认当前确实有副本存在无主状态;然后根据如下几种情况进行详细的问题排查:
- observer.log 日志有明显的报错信息
- 时钟偏差
- 有租户、表或分区被删除
- 多数派副本宕机
- 网络问题
- Clog 模块恢复日志失败
- Load 过高
- Clog 盘满
问题排查步骤
确认无主状态
您可以使用命令行在后台查询日志或在数据库中查询相关表来确认是否有副本存在无主情况。
查询后台日志
1. 查询选举模块的 election.log 日志,具体命令如下:
[admin@hostname log]$ grep 'lease is expire' election.log其中 lease is expire 表示原主的租约过期,若该命令有返回内容,则说明本机认为该分区无主,该日志包含一个 partition_key。
2. 通过 partition_key 搜索 election.log 日志,具体命令如下:
[admin@hostname log]$ grep '{tid:xxxxxxxxxxxxxxxx, partition_id:x, part_cnt:x}' election.log如果出现 ERROR 级别的 leader_revoke 信息,表示有 Leader 卸任,此时有分区无主。
3. 通过 partition_key 搜索 observer.log 日志,具体命令如下:
[admin@hostname log]$ grep '{tid:xxxxxxxxxxxxxxx, partition_id:x, part_cnt:x}' observer.log如果有打印的 ERROR 日志中包含 reconfirm、leader_active_need_swtich 等关键词,也表示有分区无主。当发现无主报错 -4038、-7006 时,可以到 observer.log 日志中查询对应时段的 ERROR 日志。
查询内部表
您可以通过查询 __all_meta_table(对于 OceanBase 数据库 V2.X 及后续版本,查询__all_virtual_meta_table)、__all_virtual_clog_stat、__all_virtual_election_info 表来查询当前是否存在副本无主情况。具体命令如下:
obclient> SELECT * FROM __all_meta_table WHERE table_id=xxx;
obclient> SELECT * FROM __all_virtual_meta_table WHERE table_id=xxx;
obclient> SELECT * FROM __all_virtual_clog_stat WHERE table_id=xxx AND partition_idx=xxxx;
obclient> SELECT * FROM __all_virtual_election_info WHERE table_id=xxx AND partition_idx=xxxx;对于 __all_meta_table 和 __all_virtual_meta_table 请查看table_id、partition_idx ;__all_virtual_clog_stat、__all_virtual_election_info 表, role 为 2 或 leader 列为空的分区表示分区无主。
常用的查询无主的 SQL
1. 统计当前 election 模块无主的分区列表。
SELECT table_id, partition_idx FROM __all_virtual_election_info GROUP BY table_id, partition_idx) except (SELECT table_id, partition_idx FROM __all_virtual_election_info WHERE role = 12. 统计当前 clog 层无主的分区列表。
SELECT table_id, partition_idx FROM __all_virtual_clog_stat GROUP BY table_id, partition_idx) except (SELECT table_id, partition_idx FROM __all_virtual_clog_stat WHERE role = 'LEADER') ;3. 统计 RS 视角无主的分区列表(有schema,meta 表无主)。
SELECT tenant_id, table_id, partition_id FROM __all_virtual_partition_table GROUP BY 1,2,3 having min(role) = 2;排查无主问题根因
如果通过上述步骤发现存在分区无主,则按以下步骤排查无主的原因。
1. 查询 observer.log 日志,检索 ERROR 信息是否包含内存分配失败、磁盘已满等明显错误。
[admin@hostname log]$ grep ERROR observer.log2. 检查时钟偏差。
使用 chronyc sources -v 或 ntpq -p方式验证时钟时效。
3. 检查是否有租户、表或分区被删除。
租户被删除时,多个副本的删除时机可能不一致,如果 Leader 副本最后被删除,则会由于收不到投票而连REN失败,进而在租约过期时会出现无主的错误。 这种情况的典型日志如下所示。
ipayus001-[ election.log [2019-03-05 00:13:28.061153] ERROR [ELECT] run_gt1_task (ob_election.cpp:1477) [1870][Y0-0000000000000000] [log=50]leader_revoke, please attention!(election={partition:{tid:1111606255681671, partition_id:0, part_cnt:0}, is_running:true, is_offline:false, is_changing_leader:false, self:"10.100.xx.xx:2882", proposal_leader:"0.0.0.0", cur_leader:"0.0.0.0", curr_candidates:3{server:"10.100.xx.xx:2882", timestamp:1550489755142437, flag:0}{server:"10.100.xx.xx:2882", timestamp:1550489755142437, flag:0}{server:"10.100.xx.xx:2882", timestamp:1550489755142437, flag:0}, curr_membership_version:1551693618713066, leader_lease:[0, 0], election_time_offset:60000, active_timestamp:1551275100257609, T1_timestamp:1551773608000000, leader_epoch:1551693701600000, state:0, role:0, stage:1, type:-1, replica_num:3, unconfirmed_leader:"10.100.xx.xx:2882", takeover_t1_timestamp:1551773596800000, is_need_query:false, valid_candidates:0, cluster_version:4295229513, change_leader_timestamp:0, ignore_log:false, leader_revoke_timestamp:1551773608001085, vote_period:4, lease_time:9800000})这种情况下,可以通过日志中的 table_id 检查该分区对应的表的状态,如果表已被删除,则可以忽略该错误。
obclient> SELECT * FROM __all_meta_table WHERE table_id=xxx;
obclient> SELECT * FROM __all_virtual_meta_table WHERE table_id=xxx;说明
删除租户、表或分区导致的无主错误仅出现在 OceanBase 数据库 V2.1.x 及以前的版本。
4. 排查多数派副本是否宕机。
如果有副本宕机,正常副本无法凑够多数派,就会导致无主。
可以在所有副本上通过 partition_key 与 leader lease is expired 搜索 election.log 日志,典型日志如下所示。
election.log [2018-09-27 23:09:04.950617] ERROR [ELECT] run_gt1_task (ob_election.cpp:1425) [38589][Y0-0000000000000000] [log=25]leader lease is expired(election={partition:{tid:1100611139458321, partition_id:710, part_cnt:0}, is_running:true, is_offline:false, is_changing_leader:false, self:"10.100.xx.xx:2882", proposal_leader:"0.0.0.0", cur_leader:"0.0.0.0", curr_candidates:3{server:"10.100.xx.xx:2882", timestamp:1538050146803352, flag:0}{server:"10.100.xx.xx:2882", timestamp:1538050146803352, flag:0}{server:"10.100.xx.xx:2882", timestamp:1538050146803352, flag:0}, curr_membership_version:0, leader_lease:[0, 0], election_time_offset:350000, active_timestamp:1538050146456812, T1_timestamp:1538069944600000, leader_epoch:1538050145800000, state:0, role:0, stage:1, type:-1, replica_num:3, unconfirmed_leader:"10.100.xx.xx:2882", takeover_t1_timestamp:1538069933400000, is_need_query:false, valid_candidates:0, cluster_version:4295229511, change_leader_timestamp:0, ignore_log:false, leader_revoke_timestamp:1538069944600553, vote_period:4, lease_time:9800000}, old_leader="10.100.xx.xx:2882")检查各 curr_candidates 中的各个 OBServer 是否宕机,如果处于正常状态的副本不满足多数派,则无主的情况是符合预期的。但此时需要判断 observer 进程是否处于宕机重启扫盘阶段,可以通过以下方式搜索
observer.log日志,
如果存在该日志说明扫盘还未完成,副本处于 REPLAY 状态(即选举模块还未开始工作)。
其中 estimated_rest_time 表示预计扫盘完成所需时间,可以等待 REPLAY 完成后再检查是否仍存在无主的情况。
[2018-08-21 16:46:00.595078] INFO [CLOG] ob_log_scanner_v1.cpp:733 [119159][Y0-0000000000000000] [lt=16] [dc=0] scan process bar(clog)(param={file_id:57968, offset:48, partition_key:{tid:18446744073709551615, partition_id:-1, part_idx:268435455, subpart_idx:268435455}, log_id:18446744073709551615, read_len:0, timeout:10000000}, header={magic:17746, version:1, type:201, partition_key:{tid:1110506744103794, partition_id:0, part_cnt:0}, log_id:686524944, data_len:459, generation_timestamp:1534820857671385, epoch_id:1534819616115213, proposal_id:{time_to_usec:1534819616115213, server:"10.244.4.47:44433"}, submit_timestamp:1534820857670904, is_batch_committed:false, data_checksum:1992526323, active_memstore_version:"0-0-0", header_checksum:2540895702}, total_clog_file_cnt=4615, rest_clog_file_cnt=1648, estimated_rest_time(second)=455)5. 判断是否存在网络问题。
如果多数派副本进程都在,未发生宕机重启,且 election.log 日志中存在 leader lease is expired 信息,说明 Leader 连REN失败,这种情况可能是由于发生网络故障(单向或双向网络隔离、RPC 请求积压等)。 1. 检查是否存在网络隔离。
首先利用如下命令检查各个副本所在机器上的 iptables,查看是否主动阻塞了网络。
[admin@hostname ~]$ sudo iptables -L如果 Follower 与 Leader 间的网络被阻塞,导致 Leader 与多数派(包含自身)网络无法联通,则无主也是符合预期的,此时需要调整网络状况。
a. 检查是否存在请求积压。
选举模块需要利用 RPC 收发消息来执行选主、连REN,如果 RPC 层出现异常导致选举消息无法按时送达/处理,那么也可能引起无主,通过如下步骤可以排查是否发生了该问题: 1. 某个副本日志中存在 leader lease is expired 信息时,首先检查该副本的 RPC 是否工作正常:
通过以下命令搜索 observer.log,查看 request doing 值是否过大,如果达到千级别说明 RPC 消息有明显的积压,需要继续排查网络是否异常。
[admin@hostname log]$ grep 'RPC EASY STAT' observer.log通过以下命令搜索 observer.log,查看 500 租户请求队列的 total_size 值是否过大(通常如果该值为几千则认为过大)。如果 total_size 的值过大,则表示 500 租户存在请求积压,导致 Clog 模块发出的请求得不到处理。
[admin@hostname log]$ grep 'dump tenant info' observer.log如果本机的上述检查正常,那么需要到 Leader 所在机器上做相同检查,如果 Leader 上 RPC 故障也会导致无主。
如果本机与 Leader 的 RPC 均正常,且 Leader 所在的 OBServer 的 election.log 日志中存在 leader lease is expired 信息 ,则可能是集群中其他副本发生了异常,导致 Leader 连REN无法收到多数派的投票,从而连REN失败。
b. 检查 RPC 延迟
i. 通过 tsar 或 vsar 命令确认 Leader 所在机器的网络在卸任时间附近是否有异常,观察重传率、带宽值。典型的网络重传率高的 tsar 命令执行结果如下图所示。
ii. 如果 tsar 执行结果无明显异常,通过以下命令 election.log 日志,如果存在内容也说明选举的消息存在延迟。
[admin@hostname log]$ grep 'message not in time' election.log如果上述日志具有内容,继续搜索 observer.log 日志,检查是否存在 RPC 相关的异常。
iii. 如果以下命令也存在内容,请联系 OceanBase 技术支持人员处理。
[admin@hostname log]$ grep 'packet fly cost too much' observer.log6. 检查是否存在 Clog 再确认失败。
如果选举模块工作正常,并已经通过选举协议选出了 Leader,但 Clog 模块在再确认阶段失败,会导致选举出的 Leader 卸任。 这种情况可以通过搜索 election.log 日志中是否包含 take the initiative leader revoke 信息进行排查,典型日志如下所示。
[2018-09-20 04:09:46.236304] INFO [ELECT] leader_revoke (ob_election_mgr.cpp:296) [39144][Y0-0000000000000000] [log=25]take the initiative leader revoke(partition={tid:1101710651081570, partition_id:0, part_cnt:0})7. 判断是否为 Load 值过高引起的无主。
可以通过 tsar -i1 检查对应时间点的 Load 值是否正常,如果该值非常高,可能导致 election 模块无主。
[root@hostname home]# tsar -i1也可以通过以下命令搜索 election.log 日志判断 Load 值是否过高从而引起无主。
[admin@hostname log]$ grep 'run time out of range' election.log8. 判断是否为 Clog 盘满。
对于分区数多、写入压力大的数据库集群,如果转储慢、或者租户 Unit 规格异构,那么可能导致部分副本的 Clog 回收不及时,从而导致盘空间达到 95%,此时 observer 进程会自动停止写 Clog,从而导致这台机器上有大量副本不同步,从而导致无主。 您可以通过在服务器上执行 df -h 查看当前 Clog 盘的空间使用占比,如果 Use% 列达到了 clog_disk_usage_limit_percentage 设置的阈值,则需要进行处理。
[root@hostname /]# df -h
...
/dev/mapper/vglog-ob_log 196G 177G 9G 95% /observer/clog
...有关 Clog 盘满的解决方式,请参见 节点日志盘(Clog)空间满。




