使用shell自动化诊断性能问题(一)(r11笔记第41天)

一直以来要做性能分析的自动化工作,但是久久没有动笔,今天索性来更新一版。

首先我希望得到的一个基本效果就是后台去扫描数据库的DB time,如果超出了阈值,比如这里我设置的为400(即DB time为400%),则会开启自动诊断的任务。时间范围是提前一个小时和当前时间。我对已有的脚本做了一些改动,加了一些逻辑,后续还会不断完善。

DBTIME_THRESHOLD=400
DATE=`date '+%Y%m%d'`
BEGIN_HOUR=`date -d"1 hour ago" +"%H"`
END_HOUR=`date  +"%H"`

下面的函数会得到快照级别的DB time情况

function showsnap
{
sqlplus -s $DB_CONN_STR@$SH_DB_SID <<EOF
break on db_name
set pages 0
set feedback off
set linesize 100
col snapdate format a20
select
begin_snap
,end_snap
,snapdate
,round(((END_INTERVAL_TIME+0)-(BEGIN_INTERVAL_TIME+0 ))*24*60) duration_mins
,round((select round((sum(e.value) -
                        sum(b.value)) / 1000000 /60,2) dbtime
                        FROM DBA_HIST_SYS_TIME_MODEL e, DBA_HIST_SYS_TIME_MODEL b
                        WHERE
                         e.STAT_NAME = 'DB time'
                         and b.snap_id=begin_snap
                        and e.snap_id =end_snap
                        AND b.STAT_NAME = 'DB time'
                        group by e.snap_id,b.snap_id)) dbtime
from
(       
select
      di.db_name                                        db_name
     , s.snap_id                                         begin_snap
     ,lead(s.snap_id ,1,s.snap_id ) over(order by s.end_interval_time ) end_snap
     , to_char(s.end_interval_time,'dd Mon YYYY HH24:mi') snapdate
     , s.snap_level                                      lvl     
     ,s.end_interval_time
     ,s.begin_interval_time
  from dba_hist_snapshot s
     , dba_hist_database_instance di
 where
  ( di.dbid,di.instance_number) in
 (select d.dbid            dbid
     , i.instance_number inst_num
  from v\$database d,
       v\$instance i)
   and di.dbid             = s.dbid
   and di.instance_number  = s.instance_number
   and di.startup_time     = s.startup_time
   and to_char(END_INTERVAL_TIME,'yyyymmdd')='$1'
   and EXTRACT(HOUR FROM END_INTERVAL_TIME) between $2-1 and $3+1
 order by  instance_name, snap_id
 );  
EOF
}下面的函数会得到快照级别SQL的DB time占比图。
function showsnapsql
{
sqlplus -s $DB_CONN_STR@$SH_DB_SID <<EOF
break on db_name
set pages 50
set linesize 100
col elapsed_time format a10
col per_total format a10
select snap_id,sql_id,EXECUTIONS_DELTA,max_elapsed elapsed_time,per_total||'%' per_total from
(select
distinct snap_id,sql_id,EXECUTIONS_DELTA,trunc(max(ELAPSED_TIME_DELTA)
OVER (PARTITION BY snap_id,sql_id )/1000000,0)||'s' max_elapsed,
 trunc((max(ELAPSED_TIME_DELTA)
OVER (PARTITION BY snap_id,sql_id))/(SUM(ELAPSED_TIME_DELTA) OVER
(PARTITION BY snap_id )),2)*100 per_total
 from dba_hist_sqlstat where snap_id=$1
 order by 5 desc
) where rownum<=5;

EOF
}下面的函数会基于快照生成AWR报告。
function genawrhtml
{
awr_inputs=`sqlplus -s ${DB_CONN_STR}@${SH_DB_SID} <<EOF
SET FEEDBACK OFF
SET HEAD OFF
SET PAGES 0
select d.dbid||','||i.instance_number||','||$1||','||$2||',0' text
from v\\\$database d,
v\\\$instance i ;
EOF`
sqlplus -s ${DB_CONN_STR}@${SH_DB_SID} <<EOF
set pages 0
set linesize 1500
set termout on;
spool awrrpt_$1_$2.lst
select output from table(dbms_workload_repository.awr_report_html( ${awr_inputs}));
#select output from table(dbms_workload_repository.awr_report_html( `cat awr_inputs.lst`));
spool off;
set termout off;
clear columns sql;
EOF
}下面的是执行的主方法,当然还有待完善。
#MAIN 主方法

tmp_dbtime_snap=`showsnap $DATE $BEGIN_HOUR $END_HOUR|awk -v dbtime=$DBTIME_THRESHOLD '{if($8>=dbtime) print $0}' |tail -1`
echo $tmp_dbtime_snap

dbtime_snap=`echo $tmp_dbtime_snap|awk '{print $1" " $2}'`
echo $dbtime_snap
#得到快照级别的SQL占用DB time情况showsnapsql $dbtime_snap#生成基于DB time的AWR报告genawrhtml  $dbtime_snap上面的脚本执行很简单,无需输入任何参数。就会得到一个完整的数据报告。后续会通过邮件的形式来发送。后面会继续补充完善。

时间: 2024-10-26 10:14:48

使用shell自动化诊断性能问题(一)(r11笔记第41天)的相关文章

闪回区报警引发的性能问题分析(r11笔记第11天)

自从有了Zabbix+Orabbix,很多监控都有了一种可控的方式,当然对于报警处理来说,报警是表象,很可能通过表象暴露出来的是一些更深层次的问题.这不又来一个,不看不知道,一看让自己着实吓了一跳. 首先是一个报警信息,可以看到是闪回区超过了报警的阈值,为了尽可能提前发现问题,我把阈值设置为了70%,和Oracle默认的80%有一些差别. ZABBIX-监控系统: ------------------------------------ 报警内容: archive_area_usage ----

百倍性能的PL/SQL优化案例(r11笔记第13天)

我相信你是被百倍性能的字样吸引了,不过我所想侧重的是优化的思路,这个比优化技巧更重要,而结果嘛,其实我不希望说成是百倍提升,""自黑""一下.     有一个真实想法和大家讨论一下,就是一个SQL语句如果原本运行20秒,优化到了1秒,性能提升该说是20倍还是提高了95%.当然还见过一种说法,一条SQL语句每次运行20秒,每天运行100次,优化后每次运行1秒,运行还是100次,那么性能提升是说成优化累计时间为100*20-100=1990秒? 好了,我们来看看PL/S

使用Shell自动化管理脚本清理Nginx的proxy_cache缓存

Nginx的Web缓存服务主要由proxy_cache相关指令集和fastcgi_cache相关指令集构成,前者用于反向代理时,对后端内容源服务器进行缓存,后者主要用于对FastCGI的动态程序进行缓存.两者的功能基本上一样. 在功能上,Nginx已经具备Squid所拥有的Web缓存加速功能.清除指定URL缓存的功能.而在性能上,Nginx对多核CPU的利用,胜过Squid不少.另外,在反向代理.http://www.aliyun.com/zixun/aggregation/13996.html

复杂SQL性能优化的剖析(二)(r11笔记第37天)

    昨天的一篇文章复杂SQL性能优化的剖析(一)(r11笔记第36天) 分析了一个SQL语句导致的性能问题,问题也算暂时告一段落,因为这个语句的执行频率是10分钟左右,所以优化后(大概是2秒左右,需要下周再次确认)的提升很大.    对于优化是一个持续的改进,我们碰到的问题,最终的原因可能五花八门,但是正如柯南所说,真相只有一个.我把这个问题和前几天处理的一个问题结合起来,前几天处理了一个紧急问题,也是有一个SQL语句的执行计划发生改变,这个语句的业务比较关键,触发频率是每分钟一次,如果一旦

一个SQL性能问题的优化探索(二)(r11笔记第38天)

继续前几天的一个案例一个SQL性能问题的优化探索(一)(r11笔记第33天) 如下的SQL语句存在索引字段CARD_NO,但是执行的时候却走了全表扫描,因为这是一个核心表,数据量很大,导致数据库负载很高. SQL_FULLTEXT ---------------------------------------------------------------------------------------------------- SELECT ID,CN,CARD_NO,TO_CHAR(CHAR

insert导致的性能问题大排查(r11笔记第26天)

今天开发的同学小窗口消息给我,向我咨询一个ORA错误的问题. 错误代码是ORA-30036,使用oerr ora 30036查看,由于是undo空间无法扩展导致. 这是一个统计业务的数据库,而且平时的负载其实并不高,确实有一些奇怪.首先排除了大事务导致的原因,查看数据库日志,和开发同学沟通,没有发现相关的错误信息. 所以第一感觉这是一个偶然发生的情况,不过开发的这位同学貌似碰到了问题,他说从应用端抛出了ORA-30036的错误. java.sql.BatchUpdateException:ORA

用Oracle的眼光来学习MySQL 5.7的sys(下)(r11笔记第25天)

昨天写了篇分析sys的文章,用Oracle的眼光来学习MySQL 5.7的sys(上)(r11笔记第24天)收到了一些朋友的反馈,还不错,今天继续努力,再整理一篇. sys还是很有借鉴意义     今天还和同事偶然聊起sys schema的事情,我觉得有几个地方要值得借鉴. 1)原本需要结合information_schema,performance_schema查询的方式,现在有了视图的方式,显示更加直观 2)sys schema的有些功能在早期版本可能无从查起,或者很难查询,现在这些因为新版

Data Guard实现故障自动切换(二)(r11笔记第39天)

   今天下午我的一个朋友碰到了一个Data Guard的问题,大体是主备网络出现问题,因为环境中配置了自动切换,结果备库就自动切换为了主库,这样就成了"双主",我帮忙看了下,对备库做了闪回,然后直接转换主库为备库角色,一个看似繁琐的修复工作就完成了.    在一个一主多备的环境中,的确需要一个强大的工具来支持,所以最后朋友说DG Broker真是个好东西,我回了句 用好了DG Broker,手工管理Data Guard就是小米加步枪啊.    就如同我昨天文章Data Guard故障

MySQL Online DDL(二)(r11笔记第88天)

对于Online DDL,之前简单分析了一些场景MySQL中的Online DDL(第一篇)(r11笔记第3天),其实有一个很关键的点没提到,那就是online DDL的算法,目前有三个操作选项,default,inplace,copy可选 具体可以参考  https://dev.mysql.com/doc/refman/5.6/en/innodb-online-ddl.html > select count(*) from newtest; +----------+ | count(*) |