通過DBMS_LOCK.SLEEP實現SQL對V$檢視進行持續取樣
V$檢視基於X$表,是記憶體實時資料,其沒有UNDO,也就是說沒有一致性讀
那麼可以通過一個SQL語句,取2個時間點的差值,直接取樣
為了實現取樣中間的時間停頓,需要使用dbms_lock.sleep寫一個func,睡眠指定時間
CREATE OR REPLACE FUNCTION F_SLEEP(AN_SEC NUMBER)
RETURN NUMBER
AS
BEGIN
dbms_lock.sleep(AN_SEC);
RETURN AN_SEC;
END;
/
下面是2個例子,一個是9i對ash取樣,獲得TOP SQL/WAIT/PROGRAM
--------------------------------------------------------------------------------
--
-- File name: ash_top9i.sql
-- Author : zhangqiao
-- Copyright: zhangqiaoc@olm.com.cn
-- Warning : Execution plan must use B for drive table,
-- and A must be connected by nested loop
--------------------------------------------------------------------------------
-- CREATE OR REPLACE FUNCTION F_SLEEP(AN_SEC NUMBER)
-- RETURN NUMBER
-- AS
-- BEGIN
-- dbms_lock.sleep(AN_SEC);
-- RETURN AN_SEC;
-- END;
-- /
SET pagesize 999 linesize 130
break on ID
col info for a50
set timing on
WITH SAMPLE AS (
select /*+MATERIALIZE*/* from(
-- **************************************************************************
select /*+leading(b) use_nl(a)*/* FROM
-- view a beg -------------------------------------------------------------
(SELECT S.SID,S.USERNAME,S.COMMAND,S.OSUSER,
S.PROCESS,S.MACHINE,S.TERMINAL,S.PROGRAM,S.SQL_HASH_VALUE,
W.SEQ#,decode(W.STATE,'WAITING',W.EVENT,'ON CPU') EVENT,
W.STATE,dbms_utility.get_time sample_id
FROM V$SESSION S,V$SESSION_WAIT W
WHERE S.SID = W.SID
AND S.USERNAME IS NOT NULL
AND S.STATUS = 'ACTIVE'
AND s.SID <> (SELECT SID FROM V$MYSTAT WHERE ROWNUM=1)
UNION ALL
SELECT (0-F_SLEEP(1)) s1,null s2,null s3,null s4,null s5,null s6,
null s7,null s8,null s9,null s10,null s11,null s12,null s13
FROM dual ) a,
-- view b beg -------------------------------------------------------------
(select * from dual connect by rownum<=&&1) b
-- **************************************************************************
) where SID>0)
SELECT '[1] TOPSQL' id,to_char(SQL_HASH_VALUE) INFO ,
substr(DECODE(COMMAND,1,'DDL',2,'INSERT',3,'Query',6,'UPDATE',7,'DELETE',
47,'PL/SQL_package_call',50,'Explain Plan',170,'CALL',189,
'MERGE',TO_CHAR(COMMAND)),1,8) OPCODE,COUNT(*)
FROM SAMPLE
GROUP BY SQL_HASH_VALUE,
substr(DECODE(COMMAND,1,'DDL',2,'INSERT',3,'Query',6,'UPDATE',7,'DELETE',
47,'PL/SQL_package_call',50,'Explain Plan',170,'CALL',189,
'MERGE',TO_CHAR(COMMAND)),1,8)
HAVING count(*) > &1/10
UNION ALL
SELECT '[2] TOPEET' ID,event,NULL,COUNT(*) FROM SAMPLE GROUP BY event
UNION ALL
SELECT '[3] TOPPGM' id,substr(PROGRAM,1,INSTR(program,'@')-1) PROGRAM,NULL,COUNT(*)
FROM SAMPLE GROUP BY substr(PROGRAM,1,INSTR(program,'@')-1) HAVING count(*) > &1/10
ORDER BY 1,4 DESC;
undefine 1;
另一個是對v$sesstat取樣,獲得指定指標最高的會話
是另外一種實現topsess的方法。
以前用表函式實現的,參見
http://space.itpub.net/?uid-8242091-action-viewspace-itemid-720509
--------------------------------------------------------------------------------
--
-- File name: tops.sql
-- Author: zhangqiao
-- Copyright: zhangqiaoc@olm.com.cn
--
--------------------------------------------------------------------------------
-- CREATE OR REPLACE FUNCTION F_SLEEP(AN_SEC NUMBER)
-- RETURN NUMBER
-- AS
-- BEGIN
-- dbms_lock.sleep(AN_SEC);
-- RETURN AN_SEC;
-- END;
-- /
SET pagesize 9999 linesize 100
SET VERIFY OFF TIMING ON
col statistic# FOR 999999
col NAME FOR a60
-- 3:statistic name
SELECT statistic#,NAME FROM v$statname WHERE NAME LIKE '%&&3%' and '&3' is not null
-- 1:statistic#
-- 2:sleep second
SELECT * FROM (
WITH
a AS (SELECT /*+MATERIALIZE*/SID,VALUE FROM v$sesstat WHERE statistic#=&&1),
b AS (SELECT /*+MATERIALIZE*/F_SLEEP(&&2) s1 FROM dual),
c AS (SELECT /*+MATERIALIZE*/SID,VALUE FROM v$sesstat WHERE statistic#=&1)
SELECT c.sid,c.value - NVL(a.value,0) VALUE,round((c.value - NVL(a.value,0))/&2,0) rate
FROM a,b,c
WHERE c.sid = a.sid(+)
AND c.value - NVL(a.value,0) > 0
ORDER BY 2 DESC
) WHERE ROWNUM<=10;
undefine 1
undefine 2
undefine 3
使用以前的一個指令碼runsql.sh,可以實現對指令碼的迴圈呼叫
while (( 1<2 ))
do
sqlplus -s "/ as sysdba" <
set pagesize 9999 linesize 170
@$1
exit
EOF
sleep 10
done
那麼可以通過一個SQL語句,取2個時間點的差值,直接取樣
為了實現取樣中間的時間停頓,需要使用dbms_lock.sleep寫一個func,睡眠指定時間
CREATE OR REPLACE FUNCTION F_SLEEP(AN_SEC NUMBER)
RETURN NUMBER
AS
BEGIN
dbms_lock.sleep(AN_SEC);
RETURN AN_SEC;
END;
/
下面是2個例子,一個是9i對ash取樣,獲得TOP SQL/WAIT/PROGRAM
--------------------------------------------------------------------------------
--
-- File name: ash_top9i.sql
-- Author : zhangqiao
-- Copyright: zhangqiaoc@olm.com.cn
-- Warning : Execution plan must use B for drive table,
-- and A must be connected by nested loop
--------------------------------------------------------------------------------
-- CREATE OR REPLACE FUNCTION F_SLEEP(AN_SEC NUMBER)
-- RETURN NUMBER
-- AS
-- BEGIN
-- dbms_lock.sleep(AN_SEC);
-- RETURN AN_SEC;
-- END;
-- /
SET pagesize 999 linesize 130
break on ID
col info for a50
set timing on
WITH SAMPLE AS (
select /*+MATERIALIZE*/* from(
-- **************************************************************************
select /*+leading(b) use_nl(a)*/* FROM
-- view a beg -------------------------------------------------------------
(SELECT S.SID,S.USERNAME,S.COMMAND,S.OSUSER,
S.PROCESS,S.MACHINE,S.TERMINAL,S.PROGRAM,S.SQL_HASH_VALUE,
W.SEQ#,decode(W.STATE,'WAITING',W.EVENT,'ON CPU') EVENT,
W.STATE,dbms_utility.get_time sample_id
FROM V$SESSION S,V$SESSION_WAIT W
WHERE S.SID = W.SID
AND S.USERNAME IS NOT NULL
AND S.STATUS = 'ACTIVE'
AND s.SID <> (SELECT SID FROM V$MYSTAT WHERE ROWNUM=1)
UNION ALL
SELECT (0-F_SLEEP(1)) s1,null s2,null s3,null s4,null s5,null s6,
null s7,null s8,null s9,null s10,null s11,null s12,null s13
FROM dual ) a,
-- view b beg -------------------------------------------------------------
(select * from dual connect by rownum<=&&1) b
-- **************************************************************************
) where SID>0)
SELECT '[1] TOPSQL' id,to_char(SQL_HASH_VALUE) INFO ,
substr(DECODE(COMMAND,1,'DDL',2,'INSERT',3,'Query',6,'UPDATE',7,'DELETE',
47,'PL/SQL_package_call',50,'Explain Plan',170,'CALL',189,
'MERGE',TO_CHAR(COMMAND)),1,8) OPCODE,COUNT(*)
FROM SAMPLE
GROUP BY SQL_HASH_VALUE,
substr(DECODE(COMMAND,1,'DDL',2,'INSERT',3,'Query',6,'UPDATE',7,'DELETE',
47,'PL/SQL_package_call',50,'Explain Plan',170,'CALL',189,
'MERGE',TO_CHAR(COMMAND)),1,8)
HAVING count(*) > &1/10
UNION ALL
SELECT '[2] TOPEET' ID,event,NULL,COUNT(*) FROM SAMPLE GROUP BY event
UNION ALL
SELECT '[3] TOPPGM' id,substr(PROGRAM,1,INSTR(program,'@')-1) PROGRAM,NULL,COUNT(*)
FROM SAMPLE GROUP BY substr(PROGRAM,1,INSTR(program,'@')-1) HAVING count(*) > &1/10
ORDER BY 1,4 DESC;
undefine 1;
另一個是對v$sesstat取樣,獲得指定指標最高的會話
是另外一種實現topsess的方法。
以前用表函式實現的,參見
http://space.itpub.net/?uid-8242091-action-viewspace-itemid-720509
--------------------------------------------------------------------------------
--
-- File name: tops.sql
-- Author: zhangqiao
-- Copyright: zhangqiaoc@olm.com.cn
--
--------------------------------------------------------------------------------
-- CREATE OR REPLACE FUNCTION F_SLEEP(AN_SEC NUMBER)
-- RETURN NUMBER
-- AS
-- BEGIN
-- dbms_lock.sleep(AN_SEC);
-- RETURN AN_SEC;
-- END;
-- /
SET pagesize 9999 linesize 100
SET VERIFY OFF TIMING ON
col statistic# FOR 999999
col NAME FOR a60
-- 3:statistic name
SELECT statistic#,NAME FROM v$statname WHERE NAME LIKE '%&&3%' and '&3' is not null
-- 1:statistic#
-- 2:sleep second
SELECT * FROM (
WITH
a AS (SELECT /*+MATERIALIZE*/SID,VALUE FROM v$sesstat WHERE statistic#=&&1),
b AS (SELECT /*+MATERIALIZE*/F_SLEEP(&&2) s1 FROM dual),
c AS (SELECT /*+MATERIALIZE*/SID,VALUE FROM v$sesstat WHERE statistic#=&1)
SELECT c.sid,c.value - NVL(a.value,0) VALUE,round((c.value - NVL(a.value,0))/&2,0) rate
FROM a,b,c
WHERE c.sid = a.sid(+)
AND c.value - NVL(a.value,0) > 0
ORDER BY 2 DESC
) WHERE ROWNUM<=10;
undefine 1
undefine 2
undefine 3
使用以前的一個指令碼runsql.sh,可以實現對指令碼的迴圈呼叫
while (( 1<2 ))
do
sqlplus -s "/ as sysdba" <
set pagesize 9999 linesize 170
@$1
exit
EOF
sleep 10
done
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8242091/viewspace-746380/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 通過Docker容器執行持續整合/持續部署Docker
- 【檢視】使用V$SQL_PLAN檢視獲取曾經執行過的SQL語句執行計劃SQL
- 通過v$sql_bind_capture 檢視繫結變數。SQLAPT變數
- 通過SQL_ID檢視SQL歷史執行資訊SQL
- 通過v$access檢視正在執行的儲存過程procedure儲存過程
- 在SQL Server中對檢視進行增刪改SQLServer
- 通過持續Ping來檢測網路質量
- 持續更新,檢視dump oracle資料塊檢視Oracle
- 通過日誌檢視mysql正在執行的SQL語句MySql
- 通過 HTTP 頭進行 SQL 注入HTTPSQL
- 如何檢視哪些SQL使用了動態取樣?SQL
- eBay透過事件溯源實現持續交付事件
- v$sql檢視和v$sqlarea檢視的構建SQL
- 檢視v$sql_shared_cursor檢視獲取sql語句為什麼不能共享?SQL
- 通過ADDM進行SQL調優SQL
- C#實現通過Gzip來對資料進行壓縮和解壓C#
- Windows 檢視系統資訊及持續執行時間 - systeminfoWindows
- 通過SQL Server對上傳檔案內容進行查詢SQLServer
- MySQL_通過binlog檢視原始SQL語句MySql
- 使用V$SQL_PLAN檢視SQL
- V$SQLAREA 檢視TOP_SQLSQL
- v$sql_plan 檢視解析SQL
- 透過v$sql_bind_capture 檢視繫結變數。SQLAPT變數
- 使用流水線外掛實現持續整合、持續部署
- 通過JNI對C++進行封裝C++封裝
- 對持續整合、 持續交付、持續部署和持續釋出的介紹
- 透過SQL_ID檢視SQL歷史執行資訊SQL
- 通過 v$sqlarea 查詢disk read嚴重(I/O)的SQL-- Oracle效能檢視SQLOracle
- 使用開源工具進行持續整合開源工具
- 不可錯過的「持續整合」進階指南
- 持續更新關於ORACLE X$檢視彙總Oracle
- 同事反饋環:如何實現持續改進的文化
- 透過查詢檢視sql執行計劃SQL
- 僅4步,就可通過SQL進行分散式死鎖的檢測與消除SQL分散式
- 通過與Quickbuild和Mist.io的持續整合實現雲管理和使用監控UI
- 金融理財行業通過企微SCRM系統,低成本實現私域使用者持續復購行業
- go-ums 從設計到實現( v0.1.0 )-持續更新Go
- 軟體測試過程的持續改進