某一日(11月开头第一天,大家都在开始保障双11了),下午18点,业务突然缓慢,发现数据库有大量GC,业务开始积压,查看redo量巨大。业务反馈,当时没有大量业务,属于正常业务量,最后做awr找到是异步全局索引维护问题,详细处理过程就不说了,直接说原因。
ORACLE 12C(以后个版本)新增了异步全局索引维护功能,该功能的主要作用是将分区表的truncat操作与全局索引立即失效分离,用户truncate分区后,全局索引不会立即失效,而是将全局索引设置为游离状态(orphaned_entries),这时候,全局索引仍然可以使用,不影响用户业务。
这个功能太好了,尽管我们不赞成在分区表上建全局索引,但总是不可避免。
1、先来说说这个异步全局索引维护
上面已经简单介绍了,下面贴图大家看的真切:
create table MYTEST3 ( task_id INTEGER not null, create_date DATE ) create index ABC_TEST on MYTEST3 (TASK_ID) tablespace USERS
复制
在MYTEST3 这个表上,有个全局索引ABC_TEST ,这个表示是分区表,那些冗余的分区表sql,我就不粘贴了。
partition(P_3)这个分区上有100001条数据:
现在我把这个分区truncate掉:
alter table nxsoft_yg.MYTEST3 truncATE PARTITION(P_3) update global indexes;
复制
注:update global indexes;一定要加,这是异步维护的关键。
在dba_indexes试图中,查询不到任何失效索引,用户可以继续使用该索引,但是,这个索引的的游离状态发了变化:
orphaned_entries变更为YES,表示这个索引需要异步维护了。
2、异步维护索引调度
负责进行这个异步索引维护的,是SYS.PMO_DEFERRED_GIDX_MAINT_JOB这个调度:
select a.owner,a.job_name, a.REPEAT_INTERVAL,a.last_start_date,a.LAST_RUN_DURATION,a.next_run_date from dba_scheduler_jobs a where a.job_name='PMO_DEFERRED_GIDX_MAINT_JOB' ;
复制
这个调度会规定时间发起,对异步索引进行自动在线重建。
先不说太平洋时间,也不说这个调度的好处(好处那太明显了),说说有什么问题:
1、会产生大量归档日志
2、全局索引维护,会引发gc问题
3、引起其它锁问题
不过,2、3都不太严重,1对io的压力比较明显,还可能导致归档目录预警,因此,这个调度,一定要放在夜间非繁忙时段进行(跳过后台跑批时间)。
3、调度发起时间:居然用的是PST时间
什么是PST时间,可以访问该网站了解:
http://www.timebie.com/cn/stdpacific.php
简单一句话,就是太平洋时间,太平洋时间,与北京时间有16小时差距。例如,太平洋时间的当天2点,是我们北京时间当天的18点,换算表如下:
实际上,在我国安装操作系统,我们都选择北京时间,也就是linux上的那个亚洲上海时间,用timestatctl status 也可以查看,所以我们很多时候,我们配置了ntp(或者用date看时间也对),无法发现时间方面的问题,但是我们仔细看调度试图的输出:
有PST输出的,就是太平洋时间,如上图,太平洋时间上午00:38,实际上对应北京时间,当天下午的16:38,如果这样设置,发生在白天时段自动维护索引,对业务,必定有影响。
当然,上面的时间是笔者改过的,这个调度的原始时间为PST时间上午2:00,也就是北京时间下午18:00,其实在国内,这个时候还属于业务敏感期,仍有不少的影响。
因此,最好的方法是调整这个调度的时间,改成PST时间的其它时段,对应北京时间的非繁忙时段。
修改方法也很简单:
exec DBMS_SCHEDULER.SET_ATTRIBUTE('SYS.PMO_DEFERRED_GIDX_MAINT_SCHED','repeat_interval','FREQ=DAILY; BYHOUR=0; BYMINUTE=38; BYSECOND=0');
复制
请注意:时间一定要根据业务,自定义,修改完成后,仍然是PST时间,不是北京时间,需要自行转换。