本文主要介绍慢合并问题的排查方法。
1、首先确定合并慢的是哪一台 OBServer。
a.执行以下 SQL 确定未完成合并的 Zone。
如果
merge_status
不为 IDLE,则表示该 Zone 未完成合并。
obclient> SELECT * FROM __all_zone;
b.根据上述查询得到未完成合并的 Zone,检查其中 OBServer 的合并进度。
执行以下 SQL,查询结果中的
merge_process
字段表示该 Zone 的合并进度。
obclient> SELECT * FROM __all_virtual_partition_sstable_image_info;
2、登录到未完成合并的 OBServer,查看是否存在磁盘 I/O 瓶颈。
在 Shell 中执行
io_stat
命令查看服务器的合并状态,如果使用率 100%,并且
await
值偏高,那么很有可能硬件出现了异常,需要检查硬件状况。
[root@hostname /]# io_stat -x 1 -k
3、如果
io_stat
命令检查的
await
值偏低,但整体的 I/O 带宽不高,可以在 Shell 中执行以下命令查看是否存在限速。
[admin@hostname log]$ grep “io stat” observer.log
通过以上命令得到 OBServer 的 I/O 统计信息中,有
sys_io_percent
与
sys_iops_up_limit
两个字段。其中
sys_io_percent
表示当前系统 I/O 的使用百分比,
sys_iops_up_limit
表示系统 2M I/O 能力的上限。
a.如果
sys_iops_up_limit
大于
io_stat
的带宽使用量,则说明 I/O 余量充足,但 CPU 存在瓶颈,无法使用更多的带宽。
b.如果
sys_iops_up_limit
小于
io_stat
的带宽使用量,则说明 I/O 可能被限速了,需要调整最大允许使用的 I/O。OceanBase 数据库的 I/O 速度限制由
sys_bkgd_io_low_percentage
与
sys_bkgd_io_high_percentage
控制,分别表示
sys_io_percent
的下限与上限。如果下限过低,则可能导致合并过慢,可以适当调整这个配置项调大 I/O 限制。
有关以上配置项的详细信息,请参见《OceanBase 数据库 参考指南》中的 系统配置项 章节。
c.如果上述步骤中,发现性能瓶颈为 CPU,可以调整
merge_thread_count
配置项调整合并的线程数。
merge_thread_count
用于设置每日合并工作的线程数,默认为
0
,表示线程数由系统决定,取值范围为
[0,64]
。
有关该配置项的详细信息,请参见《OceanBase 数据库 参考指南》中的 系统配置项 章节。
4、如果以上排查后,仍不能解决问题,则还有可能是以下场景中写入的数据量太大导致的合并时间过长:
a.由于积攒了过多的转储,新增的数据过多,此时可以适当调小
minor_freeze_times
来更频繁的触发合并。
minor_freeze_times
用于设置多少次 Minor Freeze 后触发一次全局合并,默认为
5
,取值范围为
[0,65535]
。设置为
0
时,表示关闭 Minor Freeze。
有关该配置项的详细信息,请参见《OceanBase 数据库 参考指南》中的 系统配置项 章节。
b.写入放大过大,由于合并的时候需要将基线和转储的数据合起来,如果基线的宏块和增量数据有交集,就需要打开重写;如果增量数据的写入非常离散那么就会导致写入放大很多。这种情况可以适当调大
merge_thread_count
来缓解。
注意
业务上应尽量避免放大过大,主键尽量不要使用写入会非常随机的字段。例如在使用 OceanBase 数据库时需要避免使用 UUID 做主键。