×
技术社区 >  技术博客 >  OceanBase SPM 无用基线堆积?教你手动配置自动清理任务

OceanBase SPM 无用基线堆积?教你手动配置自动清理任务

问题背景

在 OceanBase 数据库中,对于开启 SPM(SQL Plan Management)功能的租户,随着业务变更、动态查询等原因可能保留了大量已经不再使用的基线,这些基线的数量会随着时间积累而增长。 在某些低版本中 OceanBase 不会自动清理这些无用基线,随着时间推移出现磁盘水位飙高、内部sql查询基线表导致io飙高等衍生问题。

而 OceanBase 在421、425、435的新版本文档中已经修复了这个问题,但实际当前由于421版本生命周期管理原因,从4.2.1 BP11 hotfix10之前的版本升级至421BP11hotfix10 及以上版本后,SPM的历史数据清理任务不会自动配置(仅对已存在的租户,升级后新建租户还是会自动配置定时清理任务),需要人工配置定时任务。人工配置的步骤如下:

确认并升级系统包

1. 确认系统包是否存在

升级完毕以后,利用以下SQL确认相关的系统包是否存在

【在sys租户或者业务租户执行均可】

select DBMS_SPM.AUTO_PURGE_SQL_PLAN_BASELINE() from dual;

2. 手动升级系统包(若执行报错)

如果上面的语句执行报错(一般是显示FUNCTION DBMS_SPM.AUTO_PURGE_SQL_PLAN_BASELINE does not exist),那需要手动升级系统包。

升级命令如下:

需要直连到集群中某个server,然后在sys租户下执行。

mysql -uroot@sys -h127.0.0.1 -P2881 -A -c -p

低峰期操作,然后操作前确认一下这期间是否有一些DDL的定时任务(比如增删分区),如果有尽量错开,以免DDL执行失败。

alter system set enable_upgrade_mode =true; 
set ob_compatibility_mode='oracle';
set ob_query_timeout = 300000000;
CALL "__DBMS_UPGRADE".UPGRADE_ALL();
set ob_compatibility_mode='mysql';
alter system set enable_upgrade_mode = false;

确认定时任务是否存在

模式一:Oracle 兼容模式

业务租户执行

-- 确认定时任务是否存在
select * from oceanbase.DBA_SCHEDULER_JOBS where JOB_NAME = 'SPM_STATS_MANAGER'\G

检查是否存在清理基线的定时任务,如果不存在,需要手动创建定时任务

在业务租户下创建定时任务

-- 手动创建定时任务
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
    job_name        => 'SPM_STATS_MANAGER',
    job_type        => 'STORED_PROCEDURE',
    job_action      => 'DBMS_SPM.HANDLE_SPM_STATS_JOB_PROC()',
    start_date      => '2025-09-20 01:00:00.000000',	-- 设置为次日 1:00, 创建时需要调整该值
    repeat_interval => 'FREQ=DAYLY; INTERVAL=1',
    end_date        => '4000-01-01 00:00:00.000000',
    enabled         => true,
    auto_drop       => false,
    comments        => 'used to handle spm stats',
    max_run_duration => 3600);
END;
/

修改历史记录保留时间

-- 查看保留时间配置
select * from oceanbase.DBA_SQL_MANAGEMENT_CONFIG where PARAMETER_NAME = 'PLAN_RETENTION_WEEKS';
-- 修改
call DBMS_SPM.CONFIGURE('plan_retention_weeks', 7);
-- 确认配置是否生效
select * from oceanbase.DBA_SQL_MANAGEMENT_CONFIG where PARAMETER_NAME = 'PLAN_RETENTION_WEEKS';

再次确认定时任务是否创建成功

select * from oceanbase.DBA_SCHEDULER_JOBS where JOB_NAME = 'SPM_STATS_MANAGER'\G;

模式一:MySQL 兼容模式

在系统租户下,为业务租户创建定时任务

-- 在sys租户下切换操作业务租户的内部表
alter system change tenant tenant_id = 100x;
-- 确认定时任务是否存在
select * from __all_tenant_scheduler_job where job_name = "SPM_STATS_MANAGER"\G

手动创建定时任务

-- 获取需要添加的 job 号
select max(job) + 1 into @next_job from __all_tenant_scheduler_job;

-- 设置 job 开始时间, 后续每天这个时刻自动执行任务
-- 设置为每日 1:00, 创建时需要调整该值
set @start_time = '2025-09-25 01:00:00';

-- 在内部表创建 job
INSERT INTO __all_tenant_scheduler_job( tenant_id, job_name, job, lowner, powner, cowner, next_date,total,`interval#`,flag,what,nlsenv,field1,exec_env,job_style,program_name,job_type,job_action,number_of_argument,start_date,repeat_interval,end_date,job_class,enabled,auto_drop,comments,credential_name,destination_name,interval_ts,max_run_duration)
VALUES
(0, "SPM_STATS_MANAGER", @next_job, "root@%", "root@%", "oceanbase", @start_time, 0, "FREQ=DAYLY; INTERVAL=1", 0, "DBMS_SPM.HANDLE_SPM_STATS_JOB_PROC()", "", "", "281018368,45,45,45,2,", "REGULER", "", "STORED_PROCEDURE", "DBMS_SPM.HANDLE_SPM_STATS_JOB_PROC()", 0, @start_time, "FREQ=DAYLY; INTERVAL=1", usec_to_time(64060560000000000), "DEFAULT_JOB_CLASS", 1, 0, "used to handle spm stats", "", "", 86400000000, 3600),
(0, "SPM_STATS_MANAGER", 0, "root@%", "root@%", "oceanbase", @start_time, 0, "FREQ=DAYLY; INTERVAL=1", 0, "DBMS_SPM.HANDLE_SPM_STATS_JOB_PROC()", "", "", "281018368,45,45,45,2,", "REGULER", "", "STORED_PROCEDURE", "DBMS_SPM.HANDLE_SPM_STATS_JOB_PROC()", 0, @start_time, "FREQ=DAYLY; INTERVAL=1", usec_to_time(64060560000000000), "DEFAULT_JOB_CLASS", 1, 0, "used to handle spm stats", "", "", 86400000000, 3600);
select * from __all_tenant_scheduler_job where job_name = "SPM_STATS_MANAGER"\G

再次确认任务创建是否成功

select * from __all_tenant_scheduler_job where job_name = "SPM_STATS_MANAGER"\G;

修改历史记录保留时间

-- 查看保留时间配置
select * from oceanbase.DBA_SQL_MANAGEMENT_CONFIG where PARAMETER_NAME = 'PLAN_RETENTION_WEEKS';
-- 修改保留时间
call DBMS_SPM.CONFIGURE('zjtx_dwglc_db', 'plan_retention_weeks', 7);
-- 查看是否生效
select * from oceanbase.DBA_SQL_MANAGEMENT_CONFIG where PARAMETER_NAME = 'PLAN_RETENTION_WEEKS';

确认定时任务执行结果

sys租户下执行

-- 确认job是否存在
select tenant_id,job_name,job,enabled,last_date,next_date,failures,flag,state,what,repeat_interval,max_run_duration from oceanbase.__all_virtual_tenant_scheduler_job where job > 0 and tenant_id = xxx order by tenant_id,job;
-- 确认job的执行状态
select * from CDB_SCHEDULER_JOB_RUN_DETAILS where tenant_id = xxx and job_name = 'SPM_STATS_MANAGER' order by time limit 10;

适用版本

本次配置方案适用于以下 OceanBase 数据库版本,操作前请先确认集群版本是否匹配:

  • V4.2.1 BP11 Hotfix10(oceanbase-4.2.1.11-111100012025092309)及之后版本
  • V4.2.5 BP4(oceanbase-4.2.5.4-104000082025052817)及之后版本
  • V4.3.5 BP2 Hotfix9(oceanbase-4.3.5.2-102090012025082611)及之后版本
  • V4.3.5 BP3 Hotfix2(oceanbase-4.3.5.3-103020012025082017)及之后版本
  • V4.3.5 BP4(oceanbase-4.3.5.4-104000052025090918)及之后版本
  • V4.4.1(oceanbase-4.4.1.0-100000242025092415)及之后版本

参考文档

https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000003982847

以上就是 OceanBase SPM 无用基线自动清理任务的完整配置实操,后续我们还会带来更多 OceanBase 性能优化、故障排查的技术干货,如果你在实际操作中遇到了问题,或者有其他优化的见解,欢迎在评论区留言交流,下次见~

精选推荐