自动收集统计信息没有执行,如何诊断-凯发app官方网站

凯发app官方网站-凯发k8官网下载客户端中心 | | 凯发app官方网站-凯发k8官网下载客户端中心
  • 博客访问: 3502484
  • 博文数量: 718
  • 博客积分: 1860
  • 博客等级: 上尉
  • 技术积分: 7790
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-07 08:51
个人简介

偶尔有空上来看看

文章分类

全部博文(718)

文章存档

2024年(4)

2023年(74)

2022年(134)

2021年(238)

2020年(115)

2019年(11)

2018年(9)

2017年(9)

2016年(17)

2015年(7)

2014年(4)

2013年(1)

2012年(11)

2011年(27)

2010年(35)

2009年(11)

2008年(11)

最近访客
相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: oracle

2022-02-27 22:28:18

都19c年代了,有些数据库还是没有自动收集统计信息。
如何诊断?

先确认一下库里业务表的统计信息是否是新的:

  1. col owner for a20
  2. col table_name for a30
  3. col last_analyzed for a20
  4. set lin 200 pages 200
  5. --19c
  6. select * from (select owner,t.table_name,t.num_rows,t.blocks,to_char(t.last_analyzed,'yyyy-mm-dd hh24:mi:ss')last_analyzed  from dba_tables t where owner not in (select username from dba_users where oracle_maintained='y') and num_rows>100 and last_analyzed is not null order by last_analyzed desc ) where rownum<101;

 --11g num_rows为0说明可能trunc
  1. select * from (select owner,t.table_name,t.num_rows,t.blocks,to_char(t.last_analyzed,'yyyy-mm-dd hh24:mi:ss')last_analyzed  from dba_tables t where owner not in (select username from dba_users where trunc(created)=(select trunc(created) from dba_users where username='sys')) and num_rows>100 and last_analyzed is not null order by last_analyzed desc ) where rownum<101;;
看看last_analyzed 列是否是最新日期,通常应该是昨天22:00,如果太旧说明没有更新。

统计信息收集是使用自动优化器统计信息收集维护任务实现的。任务的名称是“自动优化器统计集合”。该任务计划在维护窗口期间运行,并且应该收集有关具有过时或缺少统计信息的对象的统计信息。

自动收集统计信息受以下因素影响:
参数、任务、窗口、过程、表统计信息锁定属性、数据变化量、采样百分比、数据加载自动更新、imp导入元数据导致锁定、其他(最大进程数、最大游标数、os打开文件数、内存不足、空间不足等)

  1. 参数检查
  2. col name for a32
  3. col value for a10
  4. select name,value from v$parameter where name in ('job_queue_processes','aq_tm_processes','statistics_level');

job_queue_processes 应该大于100
statistics_level  应该是 typical 或者 all
aq_tm_processes  应该是1

  1. 隐含参数 _optimizer_autostats_job
  2. col name for a28
  3. col descript for a42
  4.  select a.ksppinm name,b.ksppstvl value,a.ksppdesc descript
  5.   from x$ksppi a,x$ksppcv b where a.indx=b.indx and a.ksppinm like '%_optimizer_autostats_job%';

应该是 true ,如果是 false ,那么修改
alter system set "_optimizer_autostats_job"=true scope=spfile; 
然后重启实例

  1. 基线维护作业状态
  2. col owner for a8
  3. col job_name for a25
  4. col program_name for a30
  5. col state for a12
  6. select owner,job_name,program_name,enabled,state from dba_scheduler_jobs where job_name='bsln_maintain_stats_job';
enabled列应该是true,如果不是用以下方法激活:
exec dbms_scheduler.enable('bsln_maintain_stats_job') 

  1. 维护作业组状态
  2. col group_name for a32
    select group_name, enabled from dba_scheduler_groups;

enabled列应该都是true,如果不是的话,禁用、启用方法:

  1. begin
  2.   dbms_scheduler.disable(
  3.     name => 'sys.maintenance_window_group',
  4.     force => true);

  5.   dbms_scheduler.enable(
  6.     name => 'sys.maintenance_window_group');
  7. end;
  8. /

  1. 自动任务窗口(非常重要)

  2. col window_next_time for a20
  3. col window_name for a20
  4. select window_name,to_char(window_next_time,'yyyy-mm-dd hh24:mi:ss')window_next_time,window_active,autotask_status,optimizer_stats,segment_advisor,sql_tune_advisor from dba_autotask_window_clients;

如果autotask_status不是enabled 那么需要执行exec dbms_auto_task_admin.enable。

  1. exec dbms_auto_task_admin.enable (client_name => 'auto optimizer stats collection',operation => null,window_name => null)


如果optimizer_stats 列
不是enabled 那么需要执行:
  1. begin
  2.        dbms_auto_task_admin.disable(
  3.        client_name => 'auto optimizer stats collection',
  4.        operation => null,
  5.        window_name => null);
  6. end;
  7. /
这里的client_name 参数可以通过dba_autotask_client得到。

  1. 调度窗口

  2. col repeat_interval for a55
  3. col next_start_date for a22
  4. col last_start_date for a22
  5. col window_name for a20
  6. col duration for a20
  7. select window_name,repeat_interval,duration,to_char(next_start_date,'yyyy-mm-dd hh24:mi:ss')next_start_date,to_char(last_start_date,'yyyy-mm-dd hh24:mi:ss')last_start_date,enabled from dba_scheduler_windows where window_name not like 'week%';
enabled列应该都是true,并且平时22点开始4小时,周末6点开始20小时,如果不是,则修改:

  1. --将周一窗口延长为6小时
  2. begin
  3.   dbms_scheduler.disable(
  4.     name => 'monday_window');
  5.   dbms_scheduler.set_attribute(
  6.     name => 'monday_window',
  7.     attribute => 'duration',
  8.     value => numtodsinterval(6, 'hour'));
  9.   dbms_scheduler.enable(
  10.     name => 'monday_window');
  11. end;
  12. /

  1. 将周五的窗口改为23点开始,持续8小时
  2. begin
  3.   dbms_scheduler.disable (name => '"sys"."friday_window"', force => true);
  4.   
  5.   dbms_scheduler.set_attribute (name => '"sys"."friday_window"',attribute => 'repeat_interval',value=> 'freq=weekly;byday=fri;byhour=23;byminute=0;bysecond=0');
  6.   dbms_scheduler.set_attribute (name => '"sys"."friday_window"',attribute => 'duration',value=> '0 08:00:00');

  7.   dbms_scheduler.enable (name => '"sys"."friday_window"');
  8. end;
  9. /

  1. 控制不同的任务在不同的窗口执行
  2. begin
  3.   dbms_auto_task_admin.disable(
  4.     client_name => 'auto optimizer stats collection',
  5.     operation => null,
  6.     window_name => 'monday_window');

  7.   dbms_auto_task_admin.disable(
  8.     client_name => 'auto space advisor',
  9.     operation => null,
  10.     window_name => 'monday_window');

  11.   dbms_auto_task_admin.disable(
  12.     client_name => 'sql tuning advisor',
  13.     operation => null,
  14.     window_name => 'monday_window');
  15. end;
  16. /

  1. 手工关闭或打开窗口
  2. execute dbms_scheduler.close_window ('thursday_window');
  3. 打开窗口
  4. execute dbms_scheduler.open_window ('monday_window','');
检查自动任务执行历史
  1. select client_name,window_name,jobs_created,jobs_started,jobs_completed from dba_autotask_client_history where client_name like '%stats%';


查看调度作业历史
  1. set lin 200 pages 100
  2. col owner for a4
  3. col log_date for a20
  4. col job_name for a23
  5. col operation for a15
  6. col status for a12
  7. select *
  8.   from (select log_id,
  9.              to_char(log_date, 'yyyy-mm-dd hh24:mi:ss') log_date,
  10.                owner,
  11.                job_name,
  12.                operation,
  13.                status
  14.           from dba_scheduler_job_log
  15.          where job_name like 'ora$at_os_opt%'
  16.          order by log_id desc)
  17.  where rownum < 21
  18.  order by log_id;


看收集统计信息作业执行细节
  1. col run_duration for a15
  2. col job_name for a23
  3. col error# for 99
  4. col status for a10
  5. col inst_id for 9
  6. col actual_start_date for a20
  7. col cpu_used for a16
  8.  select *
  9.    from (select log_id,
  10.                 owner,
  11.                 job_name,
  12.                 status,
  13.                 error#,
  14.                 to_char(actual_start_date, 'yyyy-mm-dd hh24:mi:ss') actual_start_date,
  15.                 run_duration,
  16.                 instance_id inst_id,
  17.                 cpu_used
  18.            from dba_scheduler_job_run_details
  19.           where job_name like 'ora$at_os_opt%'
  20.           order by log_id desc)
  21.   where rownum < 11
  22.   order by log_id;

看状态应该都是succeeded,执行时间不太长,没有错误。

如果这些维护作业或任务有问题了可以考虑重新初始化(
 1945512.1
  1. 重新初始化 maintenance jobs/tasks
  2. @?/rdbms/admin/catmwin.sql

  1. 自动任务
  2. col client_name for a32
  3. select client_name , status from dba_autotask_client order by 1;

至少第一个status应该是enabled,如果是禁止的,则启用

  1. begin
  2.   dbms_auto_task_admin.enable(
  3.     client_name => 'auto optimizer stats collection',
  4.     operation => null,
  5.     window_name => null);
  6. end;
  7. /



下一个方向是统计信息本身

  1. 查表统计信息历史
  2. select table_name,to_char(stats_update_time,'yyyy-mm-dd hh24:mi:ss') stats_update_time from dba_tab_stats_history where owner='scott' and table_name='emp';
  3. 可能没有,那就比较一下
  4. set long 2000000
  5. set pagesize 1000

  6. select * from table(dbms_stats.diff_table_stats_in_history(
  7.                     ownname => 'scott',
  8.                     tabname => 'emp',
  9.                     time1 => systimestamp,
  10.                     time2 => to_timestamp('2022-02-27 17:47:19 pm','yyyy-mm-dd hh12:mi:ss am'),
  11.                     pctthreshold => 0));
  12. 看看历史记录
  13. col savtime for a25
  14. select to_char(savtime,'yyyy-mm-dd hh24:mi:ss') savtime, rowcnt, blkcnt, avgrln,samplesize
  15. from wri$_optstat_tab_history
  16. where obj#=(select object_id from dba_objects where owner='scott' and object_name='emp')order by 1;

  1. 检查对象当前统计信息
  2. --表
  3. col owner for a25
  4. col last_analyzed  for a25
  5. select owner,table_name,num_rows,blocks,avg_space,avg_row_len,sample_size,to_char(last_analyzed,'yyyy-mm-dd hh24:mi:ss') last_analyzed from dba_tables where table_name='&table_name' and owner='&owner';

  6. --索引
  7. select owner,table_name,index_name,blevel,leaf_blocks,distinct_keys,num_rows,sample_size,last_analyzed from dba_indexes where table_name='&table_name' and owner='&owner';

  8. --分区
  9. select table_owner,table_name,partition_name,num_rows,blocks,avg_space,avg_row_len,sample_size,last_analyzed from dba_tab_partitions where table_name= '&table_name' and owner='&owner';

  10. --数据变化量
  11. col table_owner for a25
  12. col partition_name for a22
  13. col subpartition_name for a22
  14. alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
  15. select * from (select * from dba_tab_modifications where table_owner='&owner' order by timestamp desc) where rownum<21;

  1. --统计信息历史
  2. col object_name for a25
  3. col subobject_name for a25
  4. col object_type for a15
  5. select ob.owner,ob.object_name,ob.subobject_name,
  6.      ob.object_type,obj#,
  7.      to_char(savtime,'yyyy-mm-dd hh24:mi:ss') savtime,
  8.     flags,rowcnt,
  9.      blkcnt,avgrln,samplesize,analyzetime,
  10.      cachedblk,cachehit,logicalread
  11. from sys.wri$_optstat_tab_history, dba_objects ob
  12. where owner = upper('&owner')
  13.  and object_name = upper('&table_name')
  14.  and object_type in ('table')
  15.  and object_id = obj#;
  16.  
  17. 抓取索引历史索引统计信息
  18. select * from wri$_optstat_ind_history where obj#=&obj_id;

手工刷新,验证是否能够正常
exec dbms_stats.flush_database_monitoring_info

检查dba_tab_modifications 中是否有变化数据
检查表的统计信息是否锁定
select owner,table_name,stattype_locked from dba_tab_statistics
where table_name='%table_name';



如果关注的是非业务用户对象统计信息,那么如下逐个检查:
  1. 系统统计信息收集 
  2. exec dbms_stats.gather_system_stats

  3. select * from sys.aux_stats$;

  4. 数据字典统计信息 
  5. exec dbms_stats.gather_dictionary_stats

  6. select * from (
  7. select table_name, last_analyzed from dba_tables where owner='sys' order by last_analyzed, table_name) where rownum<21;

  8. 固定对象的 
  9. exec dbms_stats.gather_fixed_objects_stats

  10. select table_name,last_analyzed
  11. from dba_tab_statistics
  12. where owner = 'sys' and table_name like 'x$%' order by last_analyzed asc;

检查cjq0、mmon进程的trc日志和数据库告警日志中22点是否有异常信息。




下一个方向是bug

  1. ora$autotask_clean job执行'sys.ora$age_autotask_data'程序,底层调用dbms_autotask_prvt.age包清理了31天以前的ket$_client_tasks
  2. 如果窗口和作业都正常,在22点后会自动填充dba_autotask_task


  3. 窗口设置太短,可能导致dba_autotask_task为空 (doc id 1610257.1)

  4. mmon 参与填充 dba_autotask_client_job 和 dba_autotask_task
  5. 如果mmon异常(例如ora-1000达到最大游标数)可能导致这两个视图空 (doc id 2097721.1)

  6. 如果task名有问题,例如数据库alert中出现如下报错:
  7. ora-12012: error on auto execute of job "sys"."ora$at_os_opt_sy_936"
  8. ora-20001: statistics advisor: invalid task name for the current user
  9. ora-06512: at "sys.dbms_stats", line 47207
  10. ora-06512: at "sys.dbms_stats_advisor", line 882
  11. ora-06512: at "sys.dbms_stats_internal", line 20059
  12. ora-06512: at "sys.dbms_stats_internal", line 22201
  13. ora-06512: at "sys.dbms_stats", line 47197
  14. 就需要考虑初始化相关对象 (doc id 2420581.1)
  15. exec dbms_stats.init_package() 

  16. 确认方法:
  17. select name, ctime, how_created from sys.wri$_adv_tasks
  18. where owner_name = 'sys' and name in ('auto_stats_advisor_task','individual_stats_advisor_task');


  19. imp 时 rows=n先导入metadata,然后导入数据
  20. if rows=n, then statistics for all imported tables will be locked after the import operation is finished.


  21. 参考: 
  22. 新的 11g 默认作业(doc id 755838.1)
  23. 11g:调度程序维护任务或自动任务(doc id 1526120.1)
  24. 常见问题解答:自动收集统计信息(doc id 1233203.1)
  25. dba_autotask_client_job和dba_autotask_task为空(doc id 2097721.1) 
  26. 为什么自动统计信息收集可能显示为"卡住"且无法运行(doc id 1320246.1)
  27. 如何收集系统统计信息(doc id 149560.1)





以下不用执行

  1. 查看task状态(可能为空或与dba_autotask_client不一致)
  2. col client_name for a32
  3. col task_name for a25
  4. select client_name,task_name, status from dba_autotask_task;

  1. 自动收集任务与程序关联关系

  2. col client_name for a32
  3. col task_name for a25
  4. col program_action for a42
  5. col status for a10
  6. select client_name, task_name, status, program_action
  7. from dba_autotask_task, dba_scheduler_programs
  8. where upper(task_name)=upper(program_name)
  9. and client_name='auto optimizer stats collection';
应该是如果没有,那么有可能是dba_autotask_task内容不正常。

阅读(1781) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~
")); function link(t){ var href= $(t).attr('href'); href ="?url=" encodeuricomponent(location.href); $(t).attr('href',href); //setcookie("returnouturl", location.href, 60, "/"); }
网站地图