Using SQL Script Get Information about ASM

当诊断ASM问题时,如果知道ASM磁盘组名,磁盘组类型,磁盘状态,ASM实例初始化参数,与是否有rebalance操作在执行,对于诊断都是有帮助的。在这些情况下,通常会生成一个html格式的报告,通过在ASM实例中运行SQL脚本来生成。该脚本如下:

[grid@jyrac1 ~]$ cat asm_report.sql

spool /home/grid/ASM_report.html
set markup html on
set echo off
set feedback off
set pages 10000
break on INST_ID on GROUP_NUMBER
prompt ASM report
select to_char(SYSDATE, 'DD-Mon-YYYY HH24:MI:SS') "Time" from dual;
prompt Version
select * from V$VERSION where BANNER like '%Database%' order by 1;
prompt Cluster wide operations
select * from GV$ASM_OPERATION order by 1;
prompt
prompt Disk groups, including the dismounted disk groups
select * from V$ASM_DISKGROUP order by 1, 2, 3;
prompt All disks, including the candidate disks
select GROUP_NUMBER, DISK_NUMBER, FAILGROUP, NAME, LABEL, PATH, MOUNT_STATUS, HEADER_STATUS, STATE, OS_MB, TOTAL_MB, FREE_MB, CREATE_DATE, MOUNT_DATE, SECTOR_SIZE, VOTING_FILE, FAILGROUP_TYPE
from V$ASM_DISK
where MODE_STATUS='ONLINE'
order by 1, 2;
prompt Offline disks
select GROUP_NUMBER, DISK_NUMBER, FAILGROUP, NAME, MOUNT_STATUS, HEADER_STATUS, STATE, REPAIR_TIMER
from V$ASM_DISK
where MODE_STATUS='OFFLINE'
order by 1, 2;
prompt Disk group attributes
select GROUP_NUMBER, NAME, VALUE from V$ASM_ATTRIBUTE where NAME not like 'template%' order by 1;
prompt Connected clients
select * from V$ASM_CLIENT order by 1, 2;
prompt Non-default ASM specific initialisation parameters, including the hidden ones
select KSPPINM "Parameter", KSPFTCTXVL "Value"
from X$KSPPI a, X$KSPPCV2 b
where a.INDX + 1 = KSPFTCTXPN and (KSPPINM like '%asm%' or KSPPINM like '%balance%' or KSPPINM like '%auto_manage%') and kspftctxdf = 'FALSE'
order by 1 desc;
prompt Memory, cluster and instance specific initialisation parameters
select NAME "Parameter", VALUE "Value", ISDEFAULT "Default"
from V$PARAMETER
where NAME like '%target%' or NAME like '%pool%' or NAME like 'cluster%' or NAME like 'instance%'
order by 1;
prompt Disk group imbalance
select g.NAME "Diskgroup",
100*(max((d.TOTAL_MB-d.FREE_MB + (128*g.ALLOCATION_UNIT_SIZE/1048576))/(d.TOTAL_MB + (128*g.ALLOCATION_UNIT_SIZE/1048576)))-min((d.TOTAL_MB-d.FREE_MB + (128*g.ALLOCATION_UNIT_SIZE/1048576))/(d.TOTAL_MB + (128*g.ALLOCATION_UNIT_SIZE/1048576))))/max((d.TOTAL_MB-d.FREE_MB + (128*g.ALLOCATION_UNIT_SIZE/1048576))/(d.TOTAL_MB + (128*g.ALLOCATION_UNIT_SIZE/1048576))) "Imbalance",
count(*) "Disk count",
g.TYPE "Type"
from V$ASM_DISK_STAT d , V$ASM_DISKGROUP_STAT g
where d.GROUP_NUMBER = g.GROUP_NUMBER and d.STATE = 'NORMAL' and d.MOUNT_STATUS = 'CACHED'
group by g.NAME, g.TYPE;
prompt End of ASM report
set markup html off
set echo on
set feedback on
exit

为了生成报告并保存为/home/grid/ASM_report.html,以Grid Infrastructure用户(通常为grid或oracle)来执行

[grid@jyrac1 ~]$ sqlplus / as sysasm @asm_report.sql

SQL*Plus: Release 11.2.0.4.0 Production on Thu Jan 12 09:44:24 2017

Copyright (c) 1982, 2013, Oracle.  All rights reserved.


Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Real Application Clusters and Automatic Storage Management options

ASM report

 

 

Time
12-Jan-2017 09:44:24

 

Version

 

 

BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 – 64bit Production

…..

NORMAL

 

End of ASM report
SQL> set feedback on SQL> exit Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 – 64bit Production With the Real Application Clusters and Automatic Storage Management options

报告内容
报告首先显示了报告生成的时间与ASM的版本。

如果存在执行的任何ASM操作将会显示,我这里没有正在执行的ASM操作。所以Cluster wide operations下面没有内容。

接下来可以看到所有磁盘组,包含dismounted磁盘组。

接下来可以看到磁盘,也会包含那些状态为candidate的磁盘

接下来是关于脱机磁盘的信息,因为我这里没有脱机磁盘,所以该部分内容为空

再接下来就是磁盘组属性

接下来是连接到ASM的客户端

ASM初始化参数包含隐含参数与一些Exadata特定参数(_auto_manage)

内存,集群与实例特定参数

最后是磁盘组不平衡信息

小结:
使用这个报告可以快速查看ASM相关信息,它也可以作为ASM设置的一种备份。

查询缓冲区缓存忙等待

set pages 9999;
column buffer_busy_wait format 999,999,999;
column mydate heading ‘yr. mo dy Hr.’

select
to_char(snap_time,’yyyy-mm-dd HH24′) mydate,
new.name,
new.buffer_busy_wait-old.buffer_busy_wait buffer_busy_wait
from
perfstat.stats$buffer_pool_statistics old,
perfstat.stats$buffer_pool_statistics new,
perfstat.stats$snapshot sn
where
new.name=old.name
and new.snap_id=sn.snap_id
and old.snap_id=sn.snap_id-1
and new.buffer_busy_wait-old.buffer_busy_wait>1
group by to_char(snap_time,’yyyy-mm-dd HH24′),
new.name,
new.buffer_busy_wait-old.buffer_busy_wait;

通过脚本来查看alert.log

create or replace directory data_dir as ‘/oracle/diag/rdbms/develop/develop/trace’;

CREATE TABLE alert_log
(
text_line varchar2(2000)
)
ORGANIZATION EXTERNAL
(
TYPE ORACLE_LOADER
DEFAULT DIRECTORY data_dir
ACCESS PARAMETERS
(
records delimited by newline
fields
REJECT ROWS WITH ALL NULL FIELDS
)
LOCATION
(
‘alert_develop.log’
)
)
REJECT LIMIT unlimited;

select to_char(last_time,’dd-mon-yyyy hh24:mi’) shutdown,
to_char(start_time,’dd-mon-yyyy hh24:mi’) startup,
round((start_time-last_time)*24*60,2) mins_down,
round((last_time-lag(start_time) over (order by r)),2) days_up,
case when (lead(r) over (order by r) is null )
then round((sysdate-start_time),2)
end days_still_up
from (
select r,
to_date(last_time, ‘Dy Mon DD HH24:MI:SS YYYY’) last_time,
to_date(start_time,’Dy Mon DD HH24:MI:SS YYYY’) start_time
from (
select r,
text_line,
lag(text_line,1) over (order by r) start_time,
lag(text_line,2) over (order by r) last_time
from (
select rownum r, text_line
from alert_log
where text_line like ‘___ ___ __ __:__:__ 20__’
or text_line like ‘Starting ORACLE instance %’
)
)
where text_line like ‘Starting ORACLE instance %’
and start_time not like ‘Starting ORACLE instance %’ and last_time not like ‘Starting ORACLE instance %’

)

select to_char(‘Fri Mar 09 11:20:21 2012′,’dd-mon-yyyy hh24:mi’) from dual

获取latch信息

DEF _lhp_what=”&1″
DEF _lhp_sid=”&2″
DEF _lhp_name=”&3″
DEF _lhp_samples=”&4″

COL name FOR A35 TRUNCATE
COL latchprof_total_ms HEAD “Held ms” FOR 999999.999
COL latchprof_pct_total_samples head “Held %” format 999.99
COL latchprof_avg_ms HEAD “Avg hold ms” FOR 999.999
COL dist_samples HEAD Gets
COL total_samples HEAD Held

BREAK ON lhp_name SKIP 1

DEF _IF_ORA_10_OR_HIGHER=”–”

PROMPT
PROMPT — LatchProf 2.00 by Tanel Poder ( http://www.tanelpoder.com )

COL latchprof_oraversion NOPRINT NEW_VALUE _IF_ORA_10_OR_HIGHER

SET TERMOUT OFF
SELECT DECODE(SUBSTR(BANNER, INSTR(BANNER, ‘Release ‘)+8,1), 1, ”, ‘–‘) latchprof_oraversion
FROM v$version WHERE ROWNUM=1;
SET TERMOUT ON

WITH
t1 AS (SELECT hsecs FROM v$timer),
samples AS (
SELECT /*+ ORDERED USE_NL(l) USE_NL(s) USE_NL(l.gv$latchholder.x$ksuprlat) NO_TRANSFORM_DISTINCT_AGG */
&_lhp_what
&_IF_ORA_10_OR_HIGHER , COUNT(DISTINCT gets) dist_samples
, COUNT(*) total_samples
, COUNT(*) / &_lhp_samples total_samples_pct
FROM
(SELECT /*+ NO_MERGE */ 1 FROM DUAL CONNECT BY LEVEL <= &_lhp_samples) s,
v$latchholder l,
(SELECT
sid indx
, sql_hash_value sqlhash
, sql_address sqladdr
&_IF_ORA_10_OR_HIGHER , sql_child_number sqlchild
&_IF_ORA_10_OR_HIGHER , sql_id sqlid
FROM v$session) s
WHERE
l.sid LIKE ‘&_lhp_sid’
AND (LOWER(l.name) LIKE LOWER(‘%&_lhp_name%’) OR LOWER(RAWTOHEX(l.laddr)) LIKE LOWER(‘%&_lhp_name%’))
AND l.sid = s.indx
GROUP BY
&_lhp_what
ORDER BY
total_samples DESC
),
t2 AS (SELECT hsecs FROM v$timer)
SELECT /*+ ORDERED */
&_lhp_what
, s.total_samples
&_IF_ORA_10_OR_HIGHER , s.dist_samples
— , s.total_samples_pct
, s.total_samples / &_lhp_samples * 100 latchprof_pct_total_samples
, (t2.hsecs – t1.hsecs) * 10 * s.total_samples / &_lhp_samples latchprof_total_ms
— s.dist_events,
&_IF_ORA_10_OR_HIGHER , (t2.hsecs – t1.hsecs) * 10 * s.total_samples / dist_samples / &_lhp_samples latchprof_avg_ms
FROM
t1,
samples s,
t2
WHERE ROWNUM <= 30
/

获取当前所有会话等待事件信息

select s.sid,s.username,s.event,s.wait_time,s.state,s.seconds_in_wait,p.PROGRAM,s.MACHINE,
(select c.SQL_FULLTEXT from v$sqlarea c where c.SQL_ID=s.SQL_ID) sql_fulltext,
(select c.BIND_DATA from v$sqlarea c where c.SQL_ID=s.SQL_ID) BIND_DATA,s.SQL_ID,
s.P1TEXT,s.p1,s.p1raw,s.P2TEXT,s.p2,s.P2RAW,s.P3TEXT,s.P3,s.P3RAW
from v$session s,v$process p
where s.username is not null and s.PADDR=p.ADDR
and s.event not like’%SQL*Net%’
order by s.wait_time desc

获取数据库每天的排序统计数据脚本

set pages 9999;
column sorts_memory format 999,999,999
column sorts_disk format 999,999,999
column ratio format .9999

select
to_char(sn.snap_time,’day’) DAY,
avg(newmem.value-oldmem.value) sorts_memory,
avg(newdsk.value-olddsk.value) sorts_dsk
from
stats$sysstat oldmem,
stats$sysstat newmem,
stats$sysstat newdsk,
stats$sysstat olddsk,
stats$snapshot sn
where
newdsk.snap_id=sn.snap_id
and olddsk.snap_id=sn.snap_id-1
and newmem.snap_id=sn.snap_id
and oldmem.snap_id=sn.snap_id-1
and oldmem.name=’sorts (memory)’
and newmem.name=’sorts (memory)’
and olddsk.name=’sorts (disk)’
and newdsk.name=’sorts (disk)’
and newmem.value-oldmem.value>0
and newdsk.value-olddsk.value>0
group by to_char(sn.snap_time,’day’);

select
to_char(sn.begin_interval_time,’day’) DAY,
avg(newmem.value-oldmem.value) sorts_memory,
avg(newdsk.value-olddsk.value) sorts_dsk
from
dba_hist_sysstat oldmem,
dba_hist_sysstat newmem,
dba_hist_sysstat newdsk,
dba_hist_sysstat olddsk,
dba_hist_snapshot sn
where
newdsk.snap_id=sn.snap_id
and olddsk.snap_id=sn.snap_id-1
and newmem.snap_id=sn.snap_id
and oldmem.snap_id=sn.snap_id-1
and oldmem.stat_name=’sorts (memory)’
and newmem.stat_name=’sorts (memory)’
and olddsk.stat_name=’sorts (disk)’
and newdsk.stat_name=’sorts (disk)’
and newmem.value-oldmem.value>0
and newdsk.value-olddsk.value>0
group by to_char(sn.begin_interval_time,’day’);

获取数据库缓冲区缓存丢失统计数据

set lines 80;
set pages 999;
column mydate heading ‘Yr. Mo Dy Hr.’ format a16
column c1 heading “execs” format 9,999,999
column c2 heading “Cache Misses|While Executing” format 9,999,999
column c3 heading “Library Cache|Miss Ratio” format 999,99999

break on mydate skip 2;
select
to_char(sn.snap_time,’yyyy-mm-dd HH24′) mydate,
sum(new.pins-old.pins) c1,
sum(new.reloads-old.reloads) c2,
sum(new.reloads-old.reloads)/
sum(new.pins-old.pins) c3
from
stats$librarycache old,
stats$librarycache new,
stats$snapshot sn
where new.snap_id=sn.snap_id
and old.snap_id=new.snap_id-1
and old.namespace=new.namespace
group by to_char(sn.snap_time,’yyyy-mm-dd HH24′);

select
to_char(sn.begin_interval_time,’yyyy-mm-dd HH24′) mydate,
sum(new.pins-old.pins) c1,
sum(new.reloads-old.reloads) c2,
sum(new.reloads-old.reloads)/
sum(new.pins-old.pins) c3
from
dba_hist_librarycache old,
dba_hist_librarycache new,
dba_hist_snapshot sn
where new.snap_id=sn.snap_id
and old.snap_id=new.snap_id-1
and old.namespace=new.namespace
group by to_char(sn.begin_interval_time,’yyyy-mm-dd HH24′);

查询内存与磁盘排序统计数据

set pages 9999;
column mydate heading ‘Yr. Mo Dy Hr.’ format a16
column sorts_memory format 999,999,999
column sorts_disk format 999,999,999
column ratio format .99999

select
to_char(sn.snap_time,’yyyy-mm-dd HH24′) mydate,
newmem.value-oldmem.value sorts_memory,
newdsk.value-olddsk.value sorts_disk,
((newdsk.value-olddsk.value)/(newmem.value-oldmem.value)) ratio
from
stats$sysstat oldmem,
stats$sysstat newmem,
stats$sysstat olddsk,
stats$sysstat newdsk,
stats$snapshot sn
where
newdsk.snap_id=sn.snap_id
and olddsk.snap_id=sn.snap_id-1
and newmem.snap_id=sn.snap_id
and oldmem.snap_id=sn.snap_id-1
and oldmem.name=’sorts (memory)’
and newmem.name=’sorts (memory)’
and olddsk.name=’sorts (disk)’
and newdsk.name=’sorts (disk)’
and newmem.value-oldmem.value>0
and newdsk.value-olddsk.value>0;

select
to_char(sn.begin_interval_time,’yyyy-mm-dd HH24′) mydate,
newmem.value-oldmem.value sorts_memory,
newdsk.value-olddsk.value sorts_disk,
((newdsk.value-olddsk.value)/(newmem.value-oldmem.value)) ratio
from
dba_hist_sysstat oldmem,
dba_hist_sysstat newmem,
dba_hist_sysstat olddsk,
dba_hist_sysstat newdsk,
dba_hist_snapshot sn
where
newdsk.snap_id=sn.snap_id
and olddsk.snap_id=sn.snap_id-1
and newmem.snap_id=sn.snap_id
and oldmem.snap_id=sn.snap_id-1
and oldmem.stat_name=’sorts (memory)’
and newmem.stat_name=’sorts (memory)’
and olddsk.stat_name=’sorts (disk)’
and newdsk.stat_name=’sorts (disk)’
and newmem.value-oldmem.value>0
and newdsk.value-olddsk.value>0;

获取热点对象

select tch,
file#,
dbablk,
case
when obj = 4294967295 then
‘rbs/compat segment’
else
(select max(‘(‘ || object_type || ‘) ‘ || owner || ‘.’ ||
object_name) || decode(count(*), 1, ”, ‘ maybe!’)
from dba_objects
where data_object_id = X.OBJ)
end what
from (select tch, file#, dbablk, obj
from x$bh
where state <> 0
order by tch desc) x
where rownum < = 5;

select * from dba_extents z,
(select tch, file#, dbablk, obj
from x$bh
where state <> 0
and rownum < = 5
order by tch desc) y
where z.file_id=y.file# and z.block_id<=y.dbablk and z.block_id+z.blocks-1>=y.dbablk;

select * from dba_extents where file_id = FILE# and block_id < = DBABLK and block_id+blocks-1 >= DBABLK。