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