问题现象
OceanBase 数据库 OMS 到 V4.x 之后或者数据导入到 V4.x之后,SQL 执行变慢,不能选择正确的索引或者连接算法等,查询发现统计信息缺失或者统计信息收集失败。
关键诊断信息
触发条件
OceanBase 数据库 OMS 到 V4.x 之后或者数据导入到 V4.x 之后,每日统计信息收集在收集一些大表的统计信息时候失败,造成系统中大部分表不存在统计信息。
事前巡检
-- sys 租户执行
### 检查最近一天的自动收任务是否正常调度。如果返回结果不为空,说明存在未正常调度的自动统计信息收集任务。
SELECT t.tenant_id,
t.tenant_name,
job.job_name
FROM oceanbase.__all_tenant t,
oceanbase.__all_virtual_tenant_scheduler_job job
WHERE job.tenant_id = t.tenant_id
AND job.job_name = concat(dayname(date_sub(now(), interval 1 day)),'_WINDOW')
AND job.job > 0
AND job.enabled = 1
AND NOT EXISTS (SELECT 1
FROM oceanbase.__all_virtual_task_opt_stat_gather_history task
WHERE task.tenant_id = t.tenant_id
AND task.type = 1
AND task.start_time > date(date_sub(now(), interval 1 day)));
### 检查是否存在统计信息长期未更新的表。因为可能存在误告(dml stat 超过 10% 才会认为统计信息过期,才会触发每天的定时任务重新收集,如果表的 dml stat 没有超过该默认值,可能一个月也不会触发统计信息的重新收集)
SELECT t.tenant_id, t.table_name, last_analyzed
FROM __all_virtual_table t
JOIN __all_virtual_table_stat ts
ON t.tenant_id = ts.tenant_id
and t.table_id = ts.table_id
where ts.partition_id = case when t.part_level = 0 then t.table_id else -1 end
and ts.stattype_locked = 0
and ts.last_analyzed < date(date_sub(now(), interval 30 day))
and t.table_id > 200000
and t.table_type = 3;
### 检查是否存在可能打高 IO 的列。返回结果表示当前集群中可能导致统计信息收集期间打高集群 IO 的列,此时需决定是否需要锁定统计信息。
select c.tenant_id, database_name, table_name, column_name
FROM oceanbase.__all_virtual_column c
JOIN oceanbase.__all_virtual_table t
ON c.tenant_id = t.tenant_id
AND c.table_id = t.table_id
JOIN oceanbase.__all_virtual_database d
ON c.tenant_id = d.tenant_id
AND t.database_id = d.database_id
JOIN oceanbase.__all_virtual_table_stat ts
ON ts.tenant_id = t.tenant_id
AND ts.table_id = t.table_id
and ts.partition_id = case when t.part_level = 0 then t.table_id else -1 end
and ts.row_cnt / ts.macro_blk_cnt < 10000
and ts.macro_blk_cnt > 10000
where c.data_type in (28,29,30,46,47,48,49)
and c.table_id > 200000;
事后诊断
通过上述方法判断统计信息是否收集成功,了解统计信息收集条件是否触发,以及收集统计信息是否会带系统资源的影响。
问题原因
从 OceanBase 数据库 V4.x 开始,不再依赖每日合并收集统计信息,优化器通过 MAINTENANCE WINDOW 来进行每日自动统计信息收集,从而保证统计信息能够迭代更新。OceanBase 数据库优化器定义周一到周日 7 个自动统计信息收集任务,周一到周五的任务默认开始时间为 22:00,最大收集时长 4 小时,周六周日的默认开始时间为 6:00,最大收集时长为 20 小时。 但是直方图、大表或者大字段的统计信息的收集比较耗时,在规定的时间窗口内,并不能收集成功。目前统计信息的收集是串行的,这样会出现一张大表的统计信息在规定时间内没有收集成功,从而导致其它表不能获得收集机会,进而造成系统中多数表缺失统计信息的情况。
问题的风险及影响
缺失统计信息会导致优化器不能选择正确的索引、连接算法等,从而导致业务执行速度慢。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
适用版本
OceanBase 数据库 V4.x 版本。
解决方法
对于统计信息执行失败的大表,可以考虑关闭直方图收集,不收集 json 等类型的大字段或者只收集索引字段以及经常用来做 join 的字段。 另外,可以考虑适当增加并行度,加速统计信息的收集,需要注意的是,修改并行度为n之后,并不是可以同时并行收集n张表,而是收集一张表的时候使用并行度n。 具体命令,参数可以参见:SQL调优-统计信息运维手册。
规避方式
OMS 到 OceanBase 数据库 V4.x 之后或者数据导入到 V4.x 之后,密切关注统计信息是否收集成功。 统计信息收集失败的情况下,可以考虑修改统计信息收集策略或者手动执行统计信息收集。