【SQL监控】SQL完全监控的脚本
有网友询问我的这篇blog http://blog.itpub.net/26736162/viewspace-1218671/ 中的视图 vw_sql_rubbish_monitor_lhr 的内容,我在这里列举一下,大家共同学习吧。
SET SQLBLANKLINES ON--------------------------------- 历史SQL记录
DROP TABLE XB_SQL_MONITOR_LHR PURGE;
CREATE TABLE XB_SQL_MONITOR_LHR
(ID INTEGER PRIMARY KEY,INST_ID NUMBER,SID NUMBER,SERIAL# NUMBER,SPID NUMBER,SQL_ID VARCHAR2(13),SQL_TEXT VARCHAR2(4000),SQL_FULLTEXT CLOB,SQL_EXEC_START DATE, SQL_EXEC_ID NUMBER,COMMAND_TYPE VARCHAR2(20),ELAPSED_TIME NUMBER,ELAPSED_TIME2 VARCHAR2(30),STATUS VARCHAR2(19),USERNAME VARCHAR2(30),OS_USER VARCHAR2(30),SESSION_TYPES VARCHAR2(4000), LAST_LOAD_TIME DATE, LAST_ACTIVE_TIME DATE,EXECUTIONS NUMBER ,PX_QCSID NUMBER,CPU_TIME NUMBER,FETCHES NUMBER,BUFFER_GETS NUMBER,DISK_READS NUMBER,DIRECT_WRITES NUMBER,BINDS_XML CLOB,USER_IO_WAIT_TIME NUMBER,CONCURRENCY_WAIT_TIME NUMBER,PHYSICAL_READ_BYTES NUMBER,PHYSICAL_WRITE_BYTES NUMBER, KEY NUMBER,PLAN_OBJECT_OWNER VARCHAR2(50),PLAN_OBJECT_NAME VARCHAR2(50),IN_DATE DATE
) NOLOGGING
PARTITION BY RANGE(IN_DATE)INTERVAL(NUMTOYMINTERVAL(1,'MONTH')) (PARTITION P201704 VALUES LESS THAN(TO_DATE('201705','YYYYMM')));DROP SEQUENCE S_XB_SQL_MONITOR_LHR;
CREATE SEQUENCE S_XB_SQL_MONITOR_LHR START WITH 1 INCREMENT BY 1 CACHE 1000;
SELECT S_XB_SQL_MONITOR_LHR.NEXTVAL FROM DUAL;CREATE INDEX IND_SQL_MONITOR_SQLID ON XB_SQL_MONITOR_LHR(SQL_ID) LOCAL NOLOGGING;
CREATE INDEX IND_SQL_MONITOR_SID ON XB_SQL_MONITOR_LHR(SID,SERIAL#,SPID) LOCAL NOLOGGING;
CREATE INDEX IND_SQL_MONITOR_IN_DATE ON XB_SQL_MONITOR_LHR(IN_DATE,COMMAND_TYPE,PLAN_OBJECT_NAME) LOCAL NOLOGGING;COMMENT ON TABLE XB_SQL_MONITOR_LHR IS '历史SQL监控';
COMMENT ON COLUMN XB_SQL_MONITOR_LHR.SQL_EXEC_START IS 'SQL语句开始执行时间';
COMMENT ON COLUMN XB_SQL_MONITOR_LHR.ELAPSED_TIME IS 'SQL语句执行时间(微秒)';
COMMENT ON COLUMN XB_SQL_MONITOR_LHR.EXECUTIONS IS 'SQL语句执行次数';GRANT SELECT ON XB_SQL_MONITOR_LHR TO PUBLIC; --------------------------------- 历史SQL执行计划记录
DROP TABLE XB_SQL_PLAN_MONITOR_LHR PURGE;
CREATE TABLE XB_SQL_PLAN_MONITOR_LHR (ID NUMBER PRIMARY KEY, INST_ID NUMBER,SQL_MONITOR_ID NUMBER,KEY NUMBER, STATUS VARCHAR2(25),SID NUMBER,SERIAL# NUMBER,SPID NUMBER,SQL_ID VARCHAR2(25),SQL_EXEC_START DATE, SQL_EXEC_ID NUMBER, SQL_PLAN_HASH_VALUE NUMBER , SQL_CHILD_ADDRESS RAW(8), CHILD_NUMBER NUMBER,PLAN_PARENT_ID NUMBER,PLAN_LINE_ID NUMBER, PLAN_OPERATION VARCHAR2(30), PLAN_OPTIONS VARCHAR2(30), OPTIMIZER VARCHAR2(80), OBJECT# NUMBER,PLAN_OBJECT_OWNER VARCHAR2(30), PLAN_OBJECT_NAME VARCHAR2(30), PLAN_OBJECT_TYPE VARCHAR2(40), OBJECT_ALIAS VARCHAR2(80),PLAN_DEPTH NUMBER, PLAN_POSITION NUMBER, PLAN_COST NUMBER, PLAN_CARDINALITY NUMBER,PLAN_BYTES NUMBER, PLAN_TIME NUMBER, PLAN_PARTITION_START VARCHAR2(255) ,PLAN_PARTITION_STOP VARCHAR2(255), PLAN_CPU_COST NUMBER, PLAN_IO_COST NUMBER, PLAN_TEMP_SPACE NUMBER, STARTS NUMBER,OUTPUT_ROWS NUMBER, IO_INTERCONNECT_BYTES NUMBER,PHYSICAL_READ_REQUESTS NUMBER,PHYSICAL_READ_BYTES NUMBER, PHYSICAL_WRITE_REQUESTS NUMBER,PHYSICAL_WRITE_BYTES NUMBER, SEARCH_COLUMNS NUMBER, FILTER_PREDICATES VARCHAR2(4000) ,ACCESS_PREDICATES VARCHAR2(4000) ,PROJECTION VARCHAR2(4000) ,OTHER_XML CLOB,IN_DATE DATE
) NOLOGGING
PARTITION BY RANGE(IN_DATE)INTERVAL(NUMTOYMINTERVAL(1,'MONTH') ) (PARTITION P201704 VALUES LESS THAN (TO_DATE('201705', 'YYYYMM'))
);DROP SEQUENCE S_XB_SQL_PLAN_MONITOR_LHR;
CREATE SEQUENCE S_XB_SQL_PLAN_MONITOR_LHR START WITH 1 INCREMENT BY 1 CACHE 1000;
SELECT S_XB_SQL_PLAN_MONITOR_LHR.NEXTVAL FROM DUAL;CREATE INDEX IND_SQL_MONITOR_ID ON XB_SQL_PLAN_MONITOR_LHR(SQL_MONITOR_ID) NOLOGGING;
CREATE INDEX IND_SQL_PLAN_MONITOR_IN_DATE ON XB_SQL_PLAN_MONITOR_LHR(IN_DATE) LOCAL NOLOGGING;
CREATE INDEX IND_SMONITOR_SQLIDSIDKEY ON XB_SQL_PLAN_MONITOR_LHR(SQL_ID,SID,SERIAL#,SPID,KEY) LOCAL NOLOGGING;--------监控正在运行的SQL语句
DROP TABLE XB_SQL_MONITOR_PP_LHR;
-- Create table
CREATE TABLE XB_SQL_MONITOR_PP_LHR
(ID NUMBER NOT NULL,INST_ID NUMBER,SID NUMBER,SERIAL# NUMBER,SPID VARCHAR2(24),OSUSER VARCHAR2(30),USERNAME VARCHAR2(30),SQL_TEXT VARCHAR2(4000),SQL_FULLTEXT CLOB,PLAN_OPERATION VARCHAR2(61),STARTS NUMBER,PLAN_PARTITION_START VARCHAR2(128),PLAN_PARTITION_STOP VARCHAR2(128),EXECUTIONS NUMBER,SQL_ID VARCHAR2(13),SQL_EXEC_START DATE,LOGON_TIME DATE,LAST_LOAD_TIME DATE,LAST_ACTIVE_TIME DATE,ELAPSED_TIME VARCHAR2(500),ELAPSED_TIME1 NUMBER,MONITOR_TYPES VARCHAR2(500),MONITOR_TYPES1 NUMBER,MONITOR_VALUE NUMBER,TUNING_RESULT CLOB,TUNING_TIME DATE,SESSION_INFO VARCHAR2(4000),SESSION_STATE VARCHAR2(30),EVENT VARCHAR2(4000),CPU_TIME NUMBER,BUFFER_GETS NUMBER,PHYSICAL_READ_BYTES NUMBER,PHYSICAL_WRITE_BYTES NUMBER,USER_IO_WAIT_TIME NUMBER,BLOCKING_INSTANCE NUMBER,BLOCKING_SESSION NUMBER,LAST_CALL_ET NUMBER,ASH_COUNTS NUMBER,IN_DATE DATE
) NOLOGGING
PARTITION BY RANGE (IN_DATE) INTERVAL(NUMTOYMINTERVAL(1,'MONTH'))
(PARTITION P201704 VALUES LESS THAN (TO_DATE('201705', 'YYYYMM'))
); CREATE INDEX IND_SQL_MONITOR_PPID ON XB_SQL_MONITOR_PP_LHR(SQL_ID) LOCAL NOLOGGING;
CREATE INDEX IND_SQL_MONITOR_PP_DATE ON XB_SQL_MONITOR_PP_LHR(IN_DATE) LOCAL NOLOGGING;DROP SEQUENCE S_XB_SQL_MONITOR_PP_LHR;
CREATE SEQUENCE S_XB_SQL_MONITOR_PP_LHR START WITH 1 INCREMENT BY 1 CACHE 1000;DROP TABLE XB_SQL_PARAMETERS_LHR;
CREATE TABLE XB_SQL_PARAMETERS_LHR
( ID NUMBER PRIMARY KEY, CN_NAME VARCHAR2(100) NOT NULL,PARAM_NAME VARCHAR2(50) NOT NULL,PARAM_TYPE VARCHAR2(50) ,PARAM_VALUE VARCHAR2(50) ,PARAM_UNIT VARCHAR2(50) ,COMMENTS VARCHAR2(500)
) NOLOGGING CACHE ;INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (1, 'SQL占用UNDO表空间过大', 'V_UNDOSIZE', 'NUMBER', '52428800', 'BYTES', '单条SQL占用的UNDO表空间大小');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (2, 'SQL占用TMP表空间过大', 'V_TMPSIZE', 'NUMBER', '15204352', 'BYTES', '单条SQL占用的临时表空间大小');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (3, '执行计划COST花费过大', 'V_PLAN_COST', 'NUMBER', '114', NULL, 'SQL执行计划中的COST花费,参照值,无单位');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (4, '执行计划预估行数过大', 'V_PLAN_CARDINALITY', 'NUMBER', '1426', '行', 'SQL执行计划中的预估行数');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (5, 'SQL执行时间过大', 'V_ELAPSED_TIME', 'NUMBER', '29', '秒', 'SQL执行时间,单位为秒,1秒等于1000000微秒');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (6, 'SQL执行次数过大', 'V_EXECUTIONS', 'NUMBER', '7616', '次', 'SQL执行次数');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (7, 'SQL监控时间间隔', 'V_INTERVALTIME', 'NUMBER', '30', '秒', 'SQL监控时间间隔,最小值20秒,最大值120秒,默认30秒,推荐30秒');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (8, '笛卡尔积SQL监控', 'V_MERGEJOIN', NULL, NULL, NULL, 'SQL形成笛卡尔积');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (9, '分区表全分区扫描', 'V_PARTTABLESCAN', NULL, NULL, NULL, '分区表全分区扫描');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (13, 'SQL并行个数过大', 'V_PARALLEL', 'NUMBER', 8, '', 'SQL开并行的最大并行个数');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (14, '系统预估的剩余执行时间过长', 'V_ESTIMATE_TIME', 'NUMBER', 900, '秒', '系统预估的剩余执行时间过长');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (15, '逻辑读过大', 'V_LOGICAL_READS', 'NUMBER', 1510407, '', '逻辑读过大');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (16, '物理读过大', 'V_DISK_READS', 'NUMBER', 1510407, '', '物理读过大');
INSERT INTO XB_SQL_PARAMETERS_LHR (ID, CN_NAME, PARAM_NAME, PARAM_TYPE, PARAM_VALUE, PARAM_UNIT, COMMENTS)
VALUES (17, '等待事件异常', 'V_WAIT_EVENT', '', '', '', '等待事件异常的SQL语句');
COMMIT;--@@PKG_SQL_MONITOR_LHR.PCK
--------------------------------------------------------------
CREATE OR REPLACE PACKAGE PKG_SQL_MONITOR_LHR AUTHID CURRENT_USER AS------------------------------------------------------------------------------------- CREATED ON 2014-07-15 12:19:12 BY LHR--CHANGED ON 2013-07-1512:19:12 BY LHR-- FUNCTION: 该包记录所有历史SQL语句---主要采用了 V$SQL_MONITOR 和 V$SQL_PLAN_MONITOR 2个视图----------------------------------------------------------------------------------------------------------------存过----------------------------------------已经执行完毕的SQLPROCEDURE P_SQL_DONE_LHR;-- EXECUTING POOR PERFORMANCE 正在执行的性能差的SQLPROCEDURE P_SQL_EPP_LHR;PROCEDURE P_SQL_EPP2_LHR;PROCEDURE P_TUNING_SQL;PROCEDURE P_GET_PPSQL_PARAMETER;------------------------------函数-------------------------------------FUNCTION F_GET_RIGHT_SIZE_LHR(P_SIZE IN VARCHAR2) RETURN VARCHAR2;FUNCTION F_GET_TOTAL_TIME_LHR(P_TOTAL_SECONDS NUMBER,P_FLAG VARCHAR2 DEFAULT 'S')RETURN VARCHAR2 DETERMINISTIC;---得到当前SQL语句操作的对象FUNCTION F_GET_SQL_OBJECT_LHR(P_SQL VARCHAR2,P_COMMAND VARCHAR2 DEFAULT 'INTO',PFLAG NUMBER DEFAULT 1) RETURN VARCHAR2;-----得到当前SQL语句的命令类型FUNCTION F_GET_SQL_COMMAND_LHR(P_SQL VARCHAR2) RETURN VARCHAR2;END PKG_SQL_MONITOR_LHR;
/
CREATE OR REPLACE PACKAGE BODY PKG_SQL_MONITOR_LHR ASPROCEDURE P_SQL_DONE_LHR ASV_DATE DATE := SYSDATE;V_COMMAND VARCHAR2(50);V_SQL VARCHAR2(32767);V_OSUSER VARCHAR2(255);V_SPID NUMBER;BEGINFOR CUR IN (SELECT S_XB_SQL_MONITOR_LHR.NEXTVAL ID,A.SID,A.SESSION_SERIAL# SERIAL#,A.SQL_ID,NVL(A.SQL_TEXT, NS.SQL_TEXT) SQL_TEXT,DECODE(A.IS_FULL_SQLTEXT,'N',NS.SQL_FULLTEXT,A.SQL_TEXT) SQL_FULLTEXT,A.SQL_EXEC_START,A.ELAPSED_TIME,A.STATUS,A.USERNAME,CASEWHEN A.ERROR_MESSAGE IS NOT NULL THEN(A.MODULE || '--' || A.ACTION || '--' || A.PROGRAM || '--' ||A.PROCESS_NAME || '--' || A.CLIENT_IDENTIFIER || '--' ||A.CLIENT_INFO || '--' || A.SERVICE_NAME) || '----【' ||A.ERROR_MESSAGE || '】'ELSE(A.MODULE || '--' || A.ACTION || '--' || A.PROGRAM || '--' ||A.PROCESS_NAME || '--' || A.CLIENT_IDENTIFIER || '--' ||A.CLIENT_INFO || '--' || A.SERVICE_NAME)END AS SESSION_TYPES,CASEWHEN A.PX_QCSID IS NOT NULL THENA.PX_QCSIDWHEN A.PX_QCSID IS NULL ANDA.PX_SERVERS_ALLOCATED IS NOT NULL THENA.SIDEND AS PX_QCSID,(SELECT NC.COMMAND_NAMEFROM V$SQLCOMMAND NCWHERE NS.COMMAND_TYPE = NC.COMMAND_TYPE) COMMAND_TYPE,A.SQL_EXEC_ID,F_GET_TOTAL_TIME_LHR(A.ELAPSED_TIME / 1000000) ELAPSED_TIME2,A.PROCESS_NAME,A.MODULE,A.CPU_TIME,A.FETCHES,A.BUFFER_GETS,A.DISK_READS,A.DIRECT_WRITES,A.BINDS_XML,A.USER_IO_WAIT_TIME,A.CONCURRENCY_WAIT_TIME,A.PHYSICAL_READ_BYTES,A.PHYSICAL_WRITE_BYTES,A.KEY,C.PLAN_OBJECT_OWNER,C.PLAN_OBJECT_NAME,A.INST_ID,NS.EXECUTIONS EXECUTIONS,NS.LAST_LOAD_TIME,NS.LAST_ACTIVE_TIMEFROM (SELECT *FROM GV$SQL_MONITOR NAWHERE NA.STATUS LIKE 'DONE%'AND NA.LAST_REFRESH_TIME >= SYSDATE - 1AND NOT EXISTS(SELECT 1FROM XB_SQL_MONITOR_LHR BWHERE NA.SID = B.SIDAND NA.SESSION_SERIAL# = B.SERIAL#AND NA.SQL_ID = B.SQL_IDAND NA.SQL_EXEC_ID = B.SQL_EXEC_IDAND B.IN_DATE BETWEEN SYSDATE - 1 ANDSYSDATEAND B.INST_ID = NA.INST_ID)) ALEFT OUTER JOIN GV$SQL_PLAN_MONITOR CON (A.KEY = C.KEY AND A.SQL_ID = C.SQL_ID ANDC.PLAN_LINE_ID = 1 AND A.SQL_EXEC_ID = C.SQL_EXEC_ID ANDC.PLAN_OBJECT_OWNER IS NOT NULL ANDC.PLAN_OBJECT_NAME IS NOT NULL ANDC.PLAN_OPERATION IN ('UPDATE', 'DELETE', 'MERGE') ANDA.INST_ID = C.INST_ID)LEFT OUTER JOIN GV$SQLAREA NSON (NS.SQL_ID = A.SQL_ID AND NS.INST_ID = A.INST_ID)) LOOPV_SQL := SUBSTR(NVL(DBMS_LOB.SUBSTR(CUR.SQL_FULLTEXT, 3900, 1),CUR.SQL_TEXT),1,3900);------ SQL语句的命令类型IF CUR.COMMAND_TYPE IS NULL AND V_SQL IS NOT NULL THENBEGINCUR.COMMAND_TYPE := F_GET_SQL_COMMAND_LHR(V_SQL);EXCEPTIONWHEN OTHERS THENNULL;END;END IF;---- 找出正在操作的对象IF (CUR.COMMAND_TYPE IN ('INSERT','MERGE INTO','CREATE TABLE','CREATE INDEX','ALTER TABLE','ALTER INDEX')) AND(CUR.PLAN_OBJECT_OWNER IS NULL AND CUR.PLAN_OBJECT_NAME IS NULL) ANDV_SQL IS NOT NULL THENV_COMMAND := CASEWHEN CUR.COMMAND_TYPE IN ('INSERT', 'MERGE INTO') THEN'INTO'WHEN CUR.COMMAND_TYPE IN ('CREATE TABLE', 'ALTER TABLE') THEN'TABLE'WHEN CUR.COMMAND_TYPE IN ('CREATE INDEX', 'ALTER INDEX') THEN'INDEX'END;BEGINCUR.PLAN_OBJECT_OWNER := NVL(F_GET_SQL_OBJECT_LHR(V_SQL,V_COMMAND,2),CUR.USERNAME);CUR.PLAN_OBJECT_NAME := F_GET_SQL_OBJECT_LHR(V_SQL, V_COMMAND);EXCEPTIONWHEN OTHERS THENNULL;END;END IF;INSERT INTO XB_SQL_MONITOR_LHR(ID,INST_ID,SID,SERIAL#,SQL_ID,SQL_TEXT,SQL_FULLTEXT,SQL_EXEC_START,ELAPSED_TIME,STATUS,USERNAME,SESSION_TYPES,EXECUTIONS,IN_DATE,PX_QCSID,COMMAND_TYPE,SQL_EXEC_ID,ELAPSED_TIME2,OS_USER,CPU_TIME,FETCHES,BUFFER_GETS,DISK_READS,DIRECT_WRITES,BINDS_XML,USER_IO_WAIT_TIME,CONCURRENCY_WAIT_TIME,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,KEY,PLAN_OBJECT_OWNER,PLAN_OBJECT_NAME,SPID,LAST_LOAD_TIME,LAST_ACTIVE_TIME)VALUES(CUR.ID,CUR.INST_ID,CUR.SID,CUR.SERIAL#,CUR.SQL_ID,CUR.SQL_TEXT,CUR.SQL_FULLTEXT,CUR.SQL_EXEC_START,CUR.ELAPSED_TIME,CUR.STATUS,CUR.USERNAME,CUR.SESSION_TYPES,CUR.EXECUTIONS,V_DATE,CUR.PX_QCSID,CUR.COMMAND_TYPE,CUR.SQL_EXEC_ID,CUR.ELAPSED_TIME2,V_OSUSER,CUR.CPU_TIME,CUR.FETCHES,CUR.BUFFER_GETS,CUR.DISK_READS,CUR.DIRECT_WRITES,CUR.BINDS_XML,CUR.USER_IO_WAIT_TIME,CUR.CONCURRENCY_WAIT_TIME,CUR.PHYSICAL_READ_BYTES,CUR.PHYSICAL_WRITE_BYTES,CUR.KEY,CUR.PLAN_OBJECT_OWNER,CUR.PLAN_OBJECT_NAME,V_SPID,CUR.LAST_LOAD_TIME,CUR.LAST_ACTIVE_TIME);INSERT INTO XB_SQL_PLAN_MONITOR_LHR(ID,INST_ID,SQL_MONITOR_ID,KEY,STATUS,SID,SQL_ID,SQL_EXEC_START,SQL_EXEC_ID,SQL_PLAN_HASH_VALUE,SQL_CHILD_ADDRESS,PLAN_PARENT_ID,PLAN_LINE_ID,PLAN_OPERATION,PLAN_OPTIONS,PLAN_OBJECT_OWNER,PLAN_OBJECT_NAME,PLAN_OBJECT_TYPE,PLAN_DEPTH,PLAN_POSITION,PLAN_COST,PLAN_CARDINALITY,PLAN_BYTES,PLAN_TIME,PLAN_PARTITION_START,PLAN_PARTITION_STOP,PLAN_CPU_COST,PLAN_IO_COST,PLAN_TEMP_SPACE,STARTS,OUTPUT_ROWS,IO_INTERCONNECT_BYTES,PHYSICAL_READ_REQUESTS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_REQUESTS,PHYSICAL_WRITE_BYTES,IN_DATE,CHILD_NUMBER,OBJECT#,OBJECT_ALIAS,OPTIMIZER,SEARCH_COLUMNS,FILTER_PREDICATES,ACCESS_PREDICATES,PROJECTION,OTHER_XML,SERIAL#,SPID)SELECT S_XB_SQL_PLAN_MONITOR_LHR.NEXTVAL ID,CUR.INST_ID,(SELECT NB.IDFROM XB_SQL_MONITOR_LHR NBWHERE NB.KEY = A.KEYAND NB.SID = CUR.SIDAND NB.SQL_EXEC_ID = NB.SQL_EXEC_IDAND NB.IN_DATE = V_DATEAND NB.SQL_ID = CUR.SQL_IDAND NB.INST_ID = CUR.INST_ID) SQL_MONITOR_ID,KEY,STATUS,SID,A.SQL_ID,SQL_EXEC_START,SQL_EXEC_ID,SQL_PLAN_HASH_VALUE,SQL_CHILD_ADDRESS,PLAN_PARENT_ID,PLAN_LINE_ID,PLAN_OPERATION,PLAN_OPTIONS,PLAN_OBJECT_OWNER,PLAN_OBJECT_NAME,PLAN_OBJECT_TYPE,PLAN_DEPTH,PLAN_POSITION,NVL(A.PLAN_COST, B.COST) COST,PLAN_CARDINALITY,PLAN_BYTES,PLAN_TIME,PLAN_PARTITION_START,PLAN_PARTITION_STOP,PLAN_CPU_COST,PLAN_IO_COST,PLAN_TEMP_SPACE,STARTS,OUTPUT_ROWS,IO_INTERCONNECT_BYTES,PHYSICAL_READ_REQUESTS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_REQUESTS,PHYSICAL_WRITE_BYTES,V_DATE IN_DATE,B.CHILD_NUMBER,B.OBJECT#,B.OBJECT_ALIAS,B.OPTIMIZER,B.SEARCH_COLUMNS,B.FILTER_PREDICATES,B.ACCESS_PREDICATES,B.PROJECTION,B.OTHER_XML,CUR.SERIAL#,V_SPIDFROM GV$SQL_PLAN_MONITOR ALEFT OUTER JOIN GV$SQL_PLAN BON (A.SQL_ID = B.SQL_ID ANDA.SQL_PLAN_HASH_VALUE = B.PLAN_HASH_VALUE ANDA.SQL_CHILD_ADDRESS = B.CHILD_ADDRESS ANDA.PLAN_LINE_ID = B.ID AND B.SQL_ID = CUR.SQL_ID ANDA.INST_ID = B.INST_ID)WHERE A.STATUS LIKE 'DONE%'AND A.SQL_ID NOT IN(SELECT BB.SQL_IDFROM XB_SQL_PLAN_MONITOR_LHR BBWHERE BB.SID = CUR.SIDAND BB.KEY = CUR.KEYAND BB.SQL_ID = CUR.SQL_IDAND BB.SQL_EXEC_ID = CUR.SQL_EXEC_IDAND BB.IN_DATE BETWEEN SYSDATE - 1 AND SYSDATEAND BB.INST_ID = A.INST_ID)AND A.SQL_ID = CUR.SQL_IDAND A.KEY = CUR.KEYAND A.SID = CUR.SIDAND A.SQL_EXEC_ID = CUR.SQL_EXEC_IDAND A.INST_ID = CUR.INST_ID;END LOOP;COMMIT;EXCEPTIONWHEN OTHERS THENNULL;END P_SQL_DONE_LHR;----------------------------------------------------------------------------------------------PROCEDURE P_SQL_EPP_LHR AS------------------------------------------------------------------------------------- Created on 2015/11/21 16:49:28 by lhr--Changed on 2017/04/03 16:49:28 by lhr-- function: 监控正在执行的SQL-----------------------------------------------------------------------------------V_TMPSIZE NUMBER := 5368709120; --BYTESV_UNDOSIZE NUMBER := 5368709120; --BYTESV_PLAN_COST NUMBER := 3107523095; --COST 花费V_PLAN_CARDINALITY NUMBER := 30748908521460; --预估行数V_ELAPSED_TIME NUMBER := 10000000; ---执行时间,单位:微秒,例执行时间设置5小时,则: 5H*60*60*1000000 ,1秒等于1000000微秒V_EXECUTIONS NUMBER := 1000; --执行次数V_PARALLEL NUMBER := 4; --SQL开并行的个数V_ESTIMATE_TIME NUMBER := 900; --系统预估的剩余执行时间过长BEGINSELECT SUM(CASE T.PARAM_NAMEWHEN 'V_UNDOSIZE' THENT.PARAM_VALUEEND) V_UNDOSIZE,SUM(CASE T.PARAM_NAMEWHEN 'V_TMPSIZE' THENT.PARAM_VALUEEND) V_TMPSIZE,SUM(CASE T.PARAM_NAMEWHEN 'V_PLAN_COST' THENT.PARAM_VALUEEND) V_PLAN_COST,SUM(CASE T.PARAM_NAMEWHEN 'V_PLAN_CARDINALITY' THENT.PARAM_VALUEEND) V_PLAN_CARDINALITY,SUM(CASE T.PARAM_NAMEWHEN 'V_ELAPSED_TIME' THENT.PARAM_VALUEEND) V_ELAPSED_TIME,SUM(CASE T.PARAM_NAMEWHEN 'V_EXECUTIONS' THENT.PARAM_VALUEEND) V_EXECUTIONS,SUM(CASE T.PARAM_NAMEWHEN 'V_PARALLEL' THENT.PARAM_VALUEEND) V_PARALLEL,SUM(CASE T.PARAM_NAMEWHEN 'V_ESTIMATE_TIME' THENT.PARAM_VALUEEND) V_ESTIMATE_TIMEINTO V_UNDOSIZE,V_TMPSIZE,V_PLAN_COST,V_PLAN_CARDINALITY,V_ELAPSED_TIME,V_EXECUTIONS,V_PARALLEL,V_ESTIMATE_TIMEFROM XB_SQL_PARAMETERS_LHR TWHERE T.PARAM_NAME IN ('V_UNDOSIZE','V_TMPSIZE','V_PLAN_COST','V_PLAN_CARDINALITY','V_ELAPSED_TIME','V_EXECUTIONS','V_PARALLEL','V_ESTIMATE_TIME');--------------------------------------------- 垃圾SQL监控INSERT INTO XB_SQL_MONITOR_PP_LHR(ID,INST_ID,SID,SERIAL#,SPID,OSUSER,USERNAME,SQL_TEXT,SQL_FULLTEXT,PLAN_OPERATION,STARTS,PLAN_PARTITION_START,PLAN_PARTITION_STOP,EXECUTIONS,SQL_ID,SQL_EXEC_START,LOGON_TIME,LAST_LOAD_TIME,LAST_ACTIVE_TIME,ELAPSED_TIME,ELAPSED_TIME1,MONITOR_TYPES,MONITOR_TYPES1,MONITOR_VALUE,SESSION_INFO,SESSION_STATE,EVENT,CPU_TIME,BUFFER_GETS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,USER_IO_WAIT_TIME,BLOCKING_INSTANCE,BLOCKING_SESSION,LAST_CALL_ET,ASH_COUNTS,IN_DATE)SELECT S_XB_SQL_MONITOR_PP_LHR.NEXTVAL,INST_ID,SID,SERIAL#,SPID,OSUSER,USERNAME,SQL_TEXT,(SELECT NB.SQL_FULLTEXTFROM GV$SQLAREA NBWHERE NB.INST_ID = T.INST_IDAND T.SQL_ID = NB.SQL_ID) SQL_FULLTEXT,PLAN_OPERATION,STARTS,PLAN_PARTITION_START,PLAN_PARTITION_STOP,EXECUTIONS,SQL_ID,SQL_EXEC_START,LOGON_TIME,'' LAST_LOAD_TIME,'' LAST_ACTIVE_TIME,F_GET_TOTAL_TIME_LHR(ELAPSED_TIME_S),ELAPSED_TIME_S,MONITOR_TYPES,'' MONITOR_TYPES1,'' MONITOR_VALUE,SESSION_INFO,SESSION_STATE,EVENT,CPU_TIME,BUFFER_GETS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,USER_IO_WAIT_TIME,BLOCKING_INSTANCE,BLOCKING_SESSION,LAST_CALL_ET,ASH_COUNTS,SYSDATE IN_DATEFROM (--记录所有正在运行中的性能差的SQL语句WITH TMPS AS (SELECT WB.INST_ID INST_ID,WB.SID SID,WB.SERIAL#,WB.SPID,WB.OSUSER,WB.USERNAME,WA.PLAN_DEPTH,WA.PLAN_OPERATION PLAN_OPERATION,WA.PLAN_OPTIONS,WA.PLAN_PARTITION_START,WA.PLAN_PARTITION_STOP,WA.STARTS,WA.PLAN_COST,WA.PLAN_CARDINALITY,NVL(WB.SQL_ID, WA.SQL_ID) SQL_ID,WB.SQL_EXEC_START,WA.PX_SERVERS_REQUESTED,WA.PX_SERVERS_ALLOCATED,WA.PX_MAXDOP,WA.ELAPSED_TIME_S ELAPSED_TIME_S,WA.CPU_TIME CPU_TIME,WA.BUFFER_GETS,WA.PHYSICAL_READ_BYTES,WA.PHYSICAL_WRITE_BYTES,WA.USER_IO_WAIT_TIME USER_IO_WAIT_TIME,NVL((SELECT NS.SQL_TEXTFROM GV$SQLAREA NSWHERE NS.SQL_ID = WB.SQL_IDAND NS.INST_ID = WB.INST_ID),WA.SQL_TEXT) SQL_TEXT,WB.LOGON_TIME,WB.SQL_EXEC_ID,WB.EVENT,WB.BLOCKING_INSTANCE BLOCKING_INSTANCE,WB.BLOCKING_SESSION BLOCKING_SESSION,WB.BLOCKING_SESSION_SERIAL# BLOCKING_SESSION_SERIAL#,WB.TADDR,WB.SADDR,WB.LAST_CALL_ET,(WB.SESSION_INFO || '--' || WB.SESSION_TYPE || '--' ||WB.MACHINE) SESSION_INFO,(SELECT NS.EXECUTIONSFROM GV$SQLAREA NSWHERE NS.SQL_ID = WB.SQL_IDAND NS.INST_ID = WB.INST_ID) EXECUTIONS,'SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(''' ||WB.SQL_ID || ''',' || WB.SQL_CHILD_NUMBER ||',''advanced''));' SQL_PLAN,WB.ASH_COUNTS,WB.SESSION_STATEFROM (SELECT A.INST_ID,A.SID,A.PLAN_DEPTH,A.PLAN_OPERATION PLAN_OPERATION,A.PLAN_OPTIONS,A.PLAN_PARTITION_START,A.PLAN_PARTITION_STOP,A.STARTS,MAX(A.PLAN_COST) OVER(PARTITION BY A.INST_ID, A.SID, A.KEY, A.SQL_EXEC_ID, A.SQL_ID) AS PLAN_COST,MAX(A.PLAN_CARDINALITY) OVER(PARTITION BY A.INST_ID, A.SID, A.KEY, A.SQL_EXEC_ID, A.SQL_ID) AS PLAN_CARDINALITY,A.SQL_ID,A.SQL_EXEC_START,B.PX_SERVERS_REQUESTED,B.PX_SERVERS_ALLOCATED,B.PX_MAXDOP,(B.ELAPSED_TIME / 1000000) ELAPSED_TIME_S,(B.CPU_TIME / 1000000) CPU_TIME,B.BUFFER_GETS,B.PHYSICAL_READ_BYTES,B.PHYSICAL_WRITE_BYTES,(B.USER_IO_WAIT_TIME / 1000000) USER_IO_WAIT_TIME,B.SQL_TEXT SQL_TEXT,(B.MODULE || '--' || B.ACTION || '--' ||B.PROGRAM || '--' || B.PROCESS_NAME || '--' ||B.CLIENT_IDENTIFIER || '--' ||B.CLIENT_INFO || '--' ||B.SERVICE_NAME) SESSION_INFO,A.SQL_EXEC_IDFROM GV$SQL_PLAN_MONITOR A,GV$SQL_MONITOR BWHERE A.SID = B.SIDAND A.KEY = B.KEYAND A.INST_ID = B.INST_IDAND A.SQL_EXEC_ID = B.SQL_EXEC_IDAND A.STATUS IN('EXECUTING', 'DONE(ERROR)')AND B.STATUS IN('EXECUTING', 'DONE(ERROR)')AND B.PROCESS_NAME NOT LIKE 'p%') WARIGHT OUTER JOIN (SELECT ASH.INST_ID,ASH.SESSION_ID SID,ASH.SESSION_SERIAL# SERIAL#,(SELECT PR.SPIDFROM GV$PROCESS PRWHERE GVS.PADDR =PR.ADDRAND PR.INST_ID =ASH.INST_ID) SPID,ASH.SESSION_TYPE,ASH.USER_ID,ASH.SQL_ID,ASH.SQL_CHILD_NUMBER,ASH.SQL_OPNAME,ASH.SQL_EXEC_ID,NVL(ASH.EVENT, GVS.EVENT) EVENT,ASH.SESSION_STATE,ASH.BLOCKING_SESSION,ASH.BLOCKING_SESSION_SERIAL#,ASH.BLOCKING_INST_ID BLOCKING_INSTANCE,ASH.CLIENT_ID,ASH.MACHINE,GVS.LAST_CALL_ET,GVS.TADDR,GVS.SADDR,GVS.LOGON_TIME,GVS.USERNAME,GVS.OSUSER,GVS.SQL_EXEC_START,(GVS.MODULE || '--' ||GVS.ACTION || '--' ||GVS.PROGRAM || '--' ||GVS.PROCESS || '--' ||GVS.CLIENT_IDENTIFIER || '--' ||GVS.CLIENT_INFO || '--' ||GVS.SERVICE_NAME) SESSION_INFO,COUNT(*) ASH_COUNTSFROM GV$ACTIVE_SESSION_HISTORY ASH,GV$SESSION GVSWHERE ASH.INST_ID = GVS.INST_IDAND GVS.SQL_ID = ASH.SQL_IDAND GVS.SQL_EXEC_ID =ASH.SQL_EXEC_IDAND ASH.SESSION_ID = GVS.SIDAND ASH.SESSION_SERIAL# =GVS.SERIAL#AND GVS.STATUS = 'ACTIVE'AND ASH.SQL_ID IS NOT NULLGROUP BY ASH.INST_ID,ASH.SESSION_ID,ASH.SESSION_SERIAL#,ASH.SESSION_TYPE,ASH.USER_ID,ASH.SQL_ID,ASH.SQL_CHILD_NUMBER,ASH.SQL_OPNAME,ASH.SQL_EXEC_ID,NVL(ASH.EVENT,GVS.EVENT),ASH.SESSION_STATE,ASH.BLOCKING_SESSION,ASH.BLOCKING_SESSION_SERIAL#,ASH.BLOCKING_INST_ID,ASH.CLIENT_ID,ASH.MACHINE,GVS.LAST_CALL_ET,GVS.TADDR,GVS.SADDR,GVS.LOGON_TIME,GVS.USERNAME,GVS.OSUSER,GVS.PADDR,(GVS.MODULE || '--' ||GVS.ACTION || '--' ||GVS.PROGRAM || '--' ||GVS.PROCESS || '--' ||GVS.CLIENT_IDENTIFIER || '--' ||GVS.CLIENT_INFO || '--' ||GVS.SERVICE_NAME),GVS.SQL_EXEC_STARTHAVING COUNT(*) > 6) WBON (WB.SID = WA.SID ANDWB.INST_ID = WA.INST_ID ANDWB.SQL_ID = WA.SQL_ID ANDWB.SQL_EXEC_ID = WA.SQL_EXEC_ID))------------------------------------------ 笛卡尔积SELECT DISTINCT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'笛卡尔积【' || COUNT(*) OVER(PARTITION BY T.INST_ID, T.SID, T.SERIAL#, T.SQL_ID) || '】个' MONITOR_TYPESFROM TMPS TWHERE T.PLAN_OPERATION = 'MERGE JOIN'AND T.PLAN_OPTIONS = 'CARTESIAN'AND T.USERNAME NOT IN ('SYS')UNION ALL------------------------------------------ SQL执行时间过大SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'执行时间过大' MONITOR_TYPESFROM TMPS TWHERE T.ELAPSED_TIME_S > V_ELAPSED_TIME --5 * 60 * 60AND (NVL(PLAN_DEPTH, 1) = 1)UNION ALL------------------------------------------ 分区表全分区扫描SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'分区表全分区扫描' MONITOR_TYPESFROM TMPS TWHERE T.PLAN_OPERATION LIKE 'PARTITION%'AND T.PLAN_OPTIONS = 'ALL'-- AND T.ELAPSED_TIME_S >= 0.5 * 60 * 60UNION ALL------------------------------------------ 执行计划中COST花费超大SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'执行计划中COST花费超大【' || T.PLAN_COST || '】' MONITOR_TYPESFROM TMPS TWHERE T.PLAN_COST >= V_PLAN_COSTAND (NVL(PLAN_DEPTH, 1) = 1)UNION ALL------------------------------------------ 执行计划中预估行数超大SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'执行计划中预估行数超大【' || T.PLAN_CARDINALITY || '】' MONITOR_TYPESFROM TMPS TWHERE T.PLAN_CARDINALITY > V_PLAN_CARDINALITYAND (NVL(PLAN_DEPTH, 1) = 1)UNION ALL------------------------------------------ SQL请求并行数过多SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'SQL请求并行数过多【' || PX_MAXDOP || '】' MONITOR_TYPESFROM TMPS TWHERE T.PX_MAXDOP >= V_PARALLELAND (NVL(PLAN_DEPTH, 1) = 1)UNION ALL------------------------------------------ 系统预估的剩余执行时间过长SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'系统预估的剩余执行时间过长【' || ROUND(D.TIME_REMAINING) || '】' MONITOR_TYPESFROM TMPS T, GV$SESSION_LONGOPS DWHERE T.SQL_EXEC_ID = D.SQL_EXEC_IDAND T.SID = D.SIDAND T.SERIAL# = D.SERIAL#AND D.TIME_REMAINING > V_ESTIMATE_TIMEAND T.INST_ID = D.INST_IDAND D.TIME_REMAINING > 0AND (NVL(PLAN_DEPTH, 1) = 1)UNION ALL------------------------------------------ 等待事件异常SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'等待事件异常【' || T.EVENT || '】' MONITOR_TYPESFROM TMPS TWHERE T.EVENT NOT IN('db file sequential read','db file scattered read','db file parallel write','db file parallel read')AND (NVL(PLAN_DEPTH, 1) = 1)UNION ALL------------------------------------------ TMP表空间占用过大SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'SQL占用TMP表空间过大【' || C.BYTES || '】Bytes' MONITOR_TYPESFROM TMPS T,(SELECT A.INST_ID,A.SESSION_ADDR,SUM(A.BLOCKS) * 8 * 1024 BYTESFROM GV$TEMPSEG_USAGE AGROUP BY A.INST_ID, A.SESSION_ADDR) CWHERE C.SESSION_ADDR = T.SADDRAND C.INST_ID = T.INST_IDAND C.BYTES > V_TMPSIZE --50 * 1024 * 1024 * 1024AND (NVL(PLAN_DEPTH, 1) = 1) UNION ALL----------------------------------------- SQL占用UNDO过大,INACTIVE的会话也可能占用UNDO,但是这里只记录正在运行的SQL语句SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'SQL占用UNDO过大【' || USED_SIZE_BYTES || '】Bytes' MONITOR_TYPESFROM TMPS T,(SELECT ST.ADDR,ST.INST_ID,(ST.USED_UBLK * 8 * 1024) USED_SIZE_BYTESFROM GV$TRANSACTION ST, V$ROLLNAME R, GV$ROLLSTAT GWHERE ST.XIDUSN = R.USNAND R.USN = G.USNAND G.INST_ID = ST.INST_ID) V1WHERE V1.ADDR = T.TADDRAND T.INST_ID = V1.INST_IDAND USED_SIZE_BYTES > V_UNDOSIZE -- 50 * 1024 * 1024 * 1024UNION ALL----------------------------------------- 耗费性能SQLSELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'ASH捕获的次数【' || T.ASH_COUNTS || '】【' || SESSION_STATE || '】' MONITOR_TYPESFROM TMPS TWHERE T.ASH_COUNTS >= 4AND (NVL(PLAN_DEPTH, 1) = 1)) T;COMMIT;/*EXCEPTIONWHEN OTHERS THENCOMMIT;*/END P_SQL_EPP_LHR;PROCEDURE P_SQL_EPP2_LHR AS------------------------------------------------------------------------------------- Created on 2015/11/21 16:49:28 by lhr--Changed on 2017/04/03 16:49:28 by lhr-- function: 监控已经执行完毕的SQL-----------------------------------------------------------------------------------V_TMPSIZE NUMBER := 5368709120; --bytesV_UNDOSIZE NUMBER := 5368709120; --bytesV_PLAN_COST NUMBER := 3107523095; --cost 花费V_PLAN_CARDINALITY NUMBER := 30748908521460; --预估行数V_ELAPSED_TIME NUMBER := 10000000; ---执行时间,单位:微秒,例执行时间设置5小时,则: 5h*60*60*1000000 ,1秒等于1000000微秒V_EXECUTIONS NUMBER := 1000; --执行次数V_PARALLEL NUMBER := 4; --SQL开并行的个数V_ESTIMATE_TIME NUMBER := 900; --系统预估的执行时间V_LOGICAL_READS NUMBER := 5368709120; --bytesV_DISK_READS NUMBER := 5368709120; --bytesBEGINSELECT SUM(CASE T.PARAM_NAMEWHEN 'V_UNDOSIZE' THENT.PARAM_VALUEEND) V_UNDOSIZE,SUM(CASE T.PARAM_NAMEWHEN 'V_TMPSIZE' THENT.PARAM_VALUEEND) V_TMPSIZE,SUM(CASE T.PARAM_NAMEWHEN 'V_PLAN_COST' THENT.PARAM_VALUEEND) V_PLAN_COST,SUM(CASE T.PARAM_NAMEWHEN 'V_PLAN_CARDINALITY' THENT.PARAM_VALUEEND) V_PLAN_CARDINALITY,SUM(CASE T.PARAM_NAMEWHEN 'V_ELAPSED_TIME' THENT.PARAM_VALUEEND) V_ELAPSED_TIME,SUM(CASE T.PARAM_NAMEWHEN 'V_EXECUTIONS' THENT.PARAM_VALUEEND) V_EXECUTIONS,SUM(CASE T.PARAM_NAMEWHEN 'V_PARALLEL' THENT.PARAM_VALUEEND) V_PARALLEL,SUM(CASE T.PARAM_NAMEWHEN 'V_ESTIMATE_TIME' THENT.PARAM_VALUEEND) V_ESTIMATE_TIME,SUM(CASE T.PARAM_NAMEWHEN 'V_LOGICAL_READS' THENT.PARAM_VALUEEND) V_UNDOSIZE,SUM(CASE T.PARAM_NAMEWHEN 'V_DISK_READS' THENT.PARAM_VALUEEND) V_DISK_READSINTO V_UNDOSIZE,V_TMPSIZE,V_PLAN_COST,V_PLAN_CARDINALITY,V_ELAPSED_TIME,V_EXECUTIONS,V_PARALLEL,V_ESTIMATE_TIME,V_LOGICAL_READS,V_DISK_READSFROM XB_SQL_PARAMETERS_LHR TWHERE T.PARAM_NAME IN ('V_LOGICAL_READS','V_DISK_READS','V_UNDOSIZE','V_TMPSIZE','V_PLAN_COST','V_PLAN_CARDINALITY','V_ELAPSED_TIME','V_EXECUTIONS','V_PARALLEL','V_ESTIMATE_TIME');INSERT INTO XB_SQL_MONITOR_PP_LHR(ID,INST_ID,SID,SERIAL#,USERNAME,SQL_TEXT,EXECUTIONS,SQL_ID,SQL_EXEC_START,LAST_LOAD_TIME,LAST_ACTIVE_TIME,ELAPSED_TIME,ELAPSED_TIME1,MONITOR_TYPES,MONITOR_TYPES1,MONITOR_VALUE,SESSION_INFO,SESSION_STATE,EVENT,CPU_TIME,BUFFER_GETS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,BLOCKING_INSTANCE,BLOCKING_SESSION,ASH_COUNTS,IN_DATE)SELECT S_XB_SQL_MONITOR_PP_LHR.NEXTVAL,INST_ID,SID,SERIAL#,USERNAME,SQL_TEXT,EXECUTIONS,SQL_ID,SQL_EXEC_START,'' LAST_LOAD_TIME,'' LAST_ACTIVE_TIME,F_GET_TOTAL_TIME_LHR(ELAPSED_TIME_S),ELAPSED_TIME_S,MONITOR_TYPES,'' MONITOR_TYPES1,'' MONITOR_VALUE,SESSION_INFO,SESSION_STATE,EVENT,CPU_TIME,BUFFER_GETS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,BLOCKING_INSTANCE,BLOCKING_SESSION,ASH_COUNTS,SYSDATE IN_DATEFROM (WITH TMPA AS (SELECT ASH.INST_ID,ASH.SESSION_ID SID,ASH.SESSION_SERIAL# SERIAL#,ASH.SESSION_TYPE,ASH.USER_ID,ASH.SQL_ID,ASH.SQL_CHILD_NUMBER,ASH.SQL_OPNAME,ASH.SQL_EXEC_ID,ASH.EVENT,ASH.SESSION_STATE,ASH.BLOCKING_SESSION,ASH.BLOCKING_SESSION_SERIAL#,ASH.BLOCKING_INST_ID BLOCKING_INSTANCE,ASH.CLIENT_ID,ASH.MACHINE,GVS.PARSING_SCHEMA_NAME USERNAME,ASH.SQL_EXEC_START,(ASH.MODULE || '--' || ASH.ACTION || '--' ||ASH.PROGRAM || '--' || ASH.MACHINE || '--' ||ASH.CLIENT_ID || '--' || ASH.SESSION_TYPE) SESSION_INFO,COUNT(*) ASH_COUNTS,(GVS.ELAPSED_TIME / 1000000) ELAPSED_TIME_S,(GVS.CPU_TIME / 1000000) CPU_TIME,GVS.EXECUTIONS,GVS.DISK_READS,GVS.BUFFER_GETS,GVS.LAST_ACTIVE_TIME,GVS.LAST_LOAD_TIME,GVS.PHYSICAL_READ_BYTES,GVS.PHYSICAL_WRITE_BYTES,GVS.SQL_TEXTFROM GV$ACTIVE_SESSION_HISTORY ASH, GV$SQL GVSWHERE ASH.INST_ID = GVS.INST_IDAND GVS.SQL_ID = ASH.SQL_IDAND ASH.SQL_ID IS NOT NULLAND ASH.SAMPLE_TIME > SYSDATE - 30 / 1440GROUP BY ASH.INST_ID,ASH.SESSION_ID,ASH.SESSION_SERIAL#,ASH.SESSION_TYPE,ASH.USER_ID,ASH.SQL_ID,ASH.SQL_CHILD_NUMBER,ASH.SQL_OPNAME,ASH.SQL_EXEC_ID,ASH.EVENT,ASH.SESSION_STATE,ASH.BLOCKING_SESSION,ASH.BLOCKING_SESSION_SERIAL#,ASH.BLOCKING_INST_ID,ASH.CLIENT_ID,ASH.MACHINE,GVS.PARSING_SCHEMA_NAME,ASH.SQL_EXEC_START,(ASH.MODULE || '--' || ASH.ACTION || '--' ||ASH.PROGRAM || '--' || ASH.MACHINE || '--' ||ASH.CLIENT_ID || '--' ||ASH.SESSION_TYPE),(GVS.ELAPSED_TIME / 1000000),(GVS.CPU_TIME / 1000000),GVS.EXECUTIONS,GVS.DISK_READS,GVS.BUFFER_GETS,GVS.LAST_ACTIVE_TIME,GVS.LAST_LOAD_TIME,GVS.PHYSICAL_READ_BYTES,GVS.PHYSICAL_WRITE_BYTES,GVS.SQL_TEXTHAVING COUNT(*) > 6)------------------------------------------ 物理读过大SELECT INST_ID,SID,SERIAL#,USERNAME,SQL_TEXT,EXECUTIONS,SQL_ID,SQL_EXEC_START,LAST_LOAD_TIME,LAST_ACTIVE_TIME,ELAPSED_TIME_S,SESSION_INFO,SESSION_STATE,EVENT,CPU_TIME,DISK_READS,BUFFER_GETS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,BLOCKING_INSTANCE,BLOCKING_SESSION,ASH_COUNTS,'物理读过大' MONITOR_TYPESFROM TMPA TWHERE T.DISK_READS > V_DISK_READSUNION ALL------------------------------------------ 逻辑读过大SELECT INST_ID,SID,SERIAL#,USERNAME,SQL_TEXT,EXECUTIONS,SQL_ID,SQL_EXEC_START,LAST_LOAD_TIME,LAST_ACTIVE_TIME,ELAPSED_TIME_S,SESSION_INFO,SESSION_STATE,EVENT,CPU_TIME,DISK_READS,BUFFER_GETS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,BLOCKING_INSTANCE,BLOCKING_SESSION,ASH_COUNTS,'逻辑读过大' MONITOR_TYPESFROM TMPA TWHERE T.BUFFER_GETS > V_LOGICAL_READSUNION ALL------------------------------------------ 执行次数过大SELECT INST_ID,SID,SERIAL#,USERNAME,SQL_TEXT,EXECUTIONS,SQL_ID,SQL_EXEC_START,LAST_LOAD_TIME,LAST_ACTIVE_TIME,ELAPSED_TIME_S,SESSION_INFO,SESSION_STATE,EVENT,CPU_TIME,DISK_READS,BUFFER_GETS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,BLOCKING_INSTANCE,BLOCKING_SESSION,ASH_COUNTS,'执行次数过大' MONITOR_TYPESFROM TMPA TWHERE T.EXECUTIONS > V_EXECUTIONSUNION ALL------------------------------------------ SQL总执行时间过大SELECT INST_ID,SID,SERIAL#,USERNAME,SQL_TEXT,EXECUTIONS,SQL_ID,SQL_EXEC_START,LAST_LOAD_TIME,LAST_ACTIVE_TIME,ELAPSED_TIME_S,SESSION_INFO,SESSION_STATE,EVENT,CPU_TIME,DISK_READS,BUFFER_GETS,PHYSICAL_READ_BYTES,PHYSICAL_WRITE_BYTES,BLOCKING_INSTANCE,BLOCKING_SESSION,ASH_COUNTS,'SQL总执行时间过大' MONITOR_TYPESFROM TMPA TWHERE T.ELAPSED_TIME_S > V_ELAPSED_TIME);COMMIT;END P_SQL_EPP2_LHR;PROCEDURE P_TUNING_SQL ASMY_TASK_NAME VARCHAR2(255);BEGIN---- 调优捕捉到的垃圾SQLFOR CUR IN (SELECT DISTINCT A.USERNAME, A.SQL_ID, A.SQL_TEXTFROM XB_SQL_MONITOR_PP_LHR AWHERE A.TUNING_RESULT IS NULLAND A.IN_DATE >= SYSDATE - 1) LOOPMY_TASK_NAME := DBMS_SQLTUNE.CREATE_TUNING_TASK(SQL_TEXT => CUR.SQL_TEXT,USER_NAME => CUR.USERNAME);DBMS_SQLTUNE.EXECUTE_TUNING_TASK(TASK_NAME => MY_TASK_NAME);UPDATE XB_SQL_MONITOR_PP_LHR TSET T.TUNING_RESULT = DBMS_SQLTUNE.REPORT_TUNING_TASK(MY_TASK_NAME),T.TUNING_TIME = SYSDATEWHERE T.SQL_ID = CUR.SQL_ID;COMMIT;END LOOP;/*EXCEPTIONWHEN OTHERS THENdbms_output.put_line('error:' || SQLCODE || ',' || SQLERRM);*/END P_TUNING_SQL;PROCEDURE P_GET_PPSQL_PARAMETER ASV_TMPSIZE NUMBER := 5368709120; --bytesV_UNDOSIZE NUMBER := 5368709120; --bytesV_PLAN_COST NUMBER := 3107523095; --cost 花费V_PLAN_CARDINALITY NUMBER := 30748908521460; --预估行数V_ELAPSED_TIME NUMBER := 10000000; ---执行时间,例执行时间设置5小时,则: 5h*60*60*1000000V_EXECUTIONS NUMBER := 1000; --执行次数V_LOGICAL_READS NUMBER := 1000; --逻辑读V_DISK_READS NUMBER := 1000; --物理读BEGINSELECT ROUND(SUM(BYTES) / 2)INTO V_TMPSIZEFROM V$TEMPFILE DWHERE D.STATUS = 'ONLINE';SELECT ROUND(SUM(BYTES) / 2)INTO V_UNDOSIZEFROM DBA_DATA_FILES D, DBA_TABLESPACES DTWHERE DT.TABLESPACE_NAME = D.TABLESPACE_NAMEAND DT.CONTENTS = 'UNDO'AND DT.STATUS = 'ONLINE'GROUP BY D.TABLESPACE_NAME;SELECT ROUND(MAX(A.COST) * 0.8), ROUND(MAX(A.CARDINALITY) * 0.8)INTO V_PLAN_COST, V_PLAN_CARDINALITYFROM GV$SQL_PLAN AWHERE A.OPERATION <> 'MERGE JOIN'AND A.OPTIONS <> 'CARTESIAN'AND NOT EXISTS(SELECT 1FROM GV$SQLAREA BWHERE B.SQL_ID = A.SQL_IDAND B.INST_ID = A.INST_IDAND B.PARSING_SCHEMA_NAME LIKE '%SYS%');SELECT ROUND(MAX(A.ELAPSED_TIME /(DECODE(A.EXECUTIONS, 0, 1, A.EXECUTIONS)) / 1000000) * 0.8),ROUND(MAX(A.EXECUTIONS) * 0.8),ROUND(MAX(A.BUFFER_GETS /(DECODE(A.EXECUTIONS, 0, 1, A.EXECUTIONS))) * 0.9),ROUND(MAX(A.DISK_READS /(DECODE(A.EXECUTIONS, 0, 1, A.EXECUTIONS))) * 0.9)INTO V_ELAPSED_TIME, V_EXECUTIONS, V_LOGICAL_READS, V_DISK_READSFROM GV$SQLAREA AWHERE NOT EXISTS (SELECT 1FROM GV$SQL_PLAN AAWHERE A.SQL_ID = AA.SQL_IDAND AA.OPERATION = 'MERGE JOIN'AND AA.OPTIONS = 'CARTESIAN'AND AA.INST_ID = A.INST_ID)AND A.PARSING_SCHEMA_NAME NOT LIKE '%SYS%';UPDATE XB_SQL_PARAMETERS_LHR TSET T.PARAM_VALUE = V_TMPSIZEWHERE UPPER(T.PARAM_NAME) = UPPER('v_tmpsize');UPDATE XB_SQL_PARAMETERS_LHR TSET T.PARAM_VALUE = V_UNDOSIZEWHERE UPPER(T.PARAM_NAME) = UPPER('v_undosize');UPDATE XB_SQL_PARAMETERS_LHR TSET T.PARAM_VALUE = V_PLAN_COSTWHERE UPPER(T.PARAM_NAME) = UPPER('v_plan_cost');UPDATE XB_SQL_PARAMETERS_LHR TSET T.PARAM_VALUE = V_PLAN_CARDINALITYWHERE UPPER(T.PARAM_NAME) = UPPER('v_PLAN_CARDINALITY');UPDATE XB_SQL_PARAMETERS_LHR TSET T.PARAM_VALUE = V_ELAPSED_TIMEWHERE UPPER(T.PARAM_NAME) IN(UPPER('v_ELAPSED_TIME'), UPPER('V_ESTIMATE_TIME'));UPDATE XB_SQL_PARAMETERS_LHR TSET T.PARAM_VALUE = V_EXECUTIONSWHERE UPPER(T.PARAM_NAME) = UPPER('v_EXECUTIONS');UPDATE XB_SQL_PARAMETERS_LHR TSET T.PARAM_VALUE = V_EXECUTIONSWHERE UPPER(T.PARAM_NAME) = UPPER('V_LOGICAL_READS');UPDATE XB_SQL_PARAMETERS_LHR TSET T.PARAM_VALUE = V_EXECUTIONSWHERE UPPER(T.PARAM_NAME) = UPPER('V_DISK_READS');COMMIT;EXCEPTIONWHEN OTHERS THENDBMS_OUTPUT.PUT_LINE('error:' || SQLCODE || ',' || SQLERRM);END P_GET_PPSQL_PARAMETER;FUNCTION F_GET_RIGHT_SIZE_LHR(P_SIZE IN VARCHAR2) RETURN VARCHAR2 ASV_RESULTS VARCHAR2(255);BEGINSELECT CASEWHEN P_SIZE = 0 THEN0 || ''WHEN P_SIZE < 1024 AND P_SIZE > 0 THENP_SIZE || 'BYTES'WHEN P_SIZE >= 1024 AND P_SIZE < 1048576 THENROUND(P_SIZE / 1024, 3) || 'KB'WHEN P_SIZE >= 1048576 AND P_SIZE < 1073741824 THENROUND(P_SIZE / 1048576, 3) || 'M'WHEN P_SIZE >= 1073741824 AND P_SIZE < 1099511627776 THENROUND(P_SIZE / 1073741824, 3) || 'G'WHEN P_SIZE >= 1099511627776 AND P_SIZE < 1125899906842624 THENROUND(P_SIZE / 1099511627776, 3) || 'T'END AS SIZESINTO V_RESULTSFROM DUAL;RETURN V_RESULTS;EXCEPTIONWHEN OTHERS THENNULL;RETURN P_SIZE;END;FUNCTION F_GET_TOTAL_TIME_LHR(P_TOTAL_SECONDS NUMBER,P_FLAG VARCHAR2 DEFAULT 'S')RETURN VARCHAR2 DETERMINISTIC IS------------------------------------------------------------------------------------- Created on 2012/10/18 16:49:28 by lhr--Changed on 2015/9/3 16:49:28 by lhr-- function: 该函数 返回一个秒转换为标准时间-----------------------------------------------------------------------------------V_TMP FLOAT(18);V_RETURNS VARCHAR2(200);V_TOTAL_SECONDS NUMBER := P_TOTAL_SECONDS;BEGINIF P_TOTAL_SECONDS IS NULL OR P_TOTAL_SECONDS = 0 THENRETURN 0 || '秒';END IF;---传入的为天转换为秒IF UPPER(P_FLAG) = 'D' THENV_TOTAL_SECONDS := P_TOTAL_SECONDS * 24 * 60 * 60;END IF;-- 首先处理日期--年V_TMP := TRUNC(V_TOTAL_SECONDS / (12 * 30 * 24 * 3600));IF V_TMP > 0 THENV_RETURNS := V_TMP || '年';END IF;---月V_TMP := TRUNC(MOD(V_TOTAL_SECONDS, (12 * 30 * 24 * 3600)) /(3600 * 24 * 30));IF V_TMP > 0 THENV_RETURNS := V_RETURNS || V_TMP || '月';END IF;--天V_TMP := TRUNC(MOD(V_TOTAL_SECONDS, (3600 * 24 * 30)) / (3600 * 24));IF V_TMP > 0 THENV_RETURNS := V_RETURNS || V_TMP || '天';END IF;--处理小时V_TMP := TRUNC(MOD(V_TOTAL_SECONDS, 3600 * 24) / 3600);IF V_TMP > 0 THENV_RETURNS := V_RETURNS || V_TMP || '时';END IF;--处理分钟V_TMP := TRUNC(MOD(V_TOTAL_SECONDS, 3600) / 60);IF V_TMP > 0 THENV_RETURNS := V_RETURNS || V_TMP || '分';END IF;--处理秒钟V_TMP := TRUNC(MOD(V_TOTAL_SECONDS, 60), 3);IF V_TMP > 0 AND V_TMP < 1 THENV_RETURNS := V_RETURNS || '0' || V_TMP || '秒';ELSIF V_TMP >= 1 THENV_RETURNS := V_RETURNS || V_TMP || '秒';ELSIF V_TMP = 0 AND V_RETURNS IS NULL THENV_RETURNS := '0' || TRUNC(V_TOTAL_SECONDS, 6) || '秒';END IF;RETURN V_RETURNS;END F_GET_TOTAL_TIME_LHR;------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------FUNCTION F_GET_SQL_OBJECT_LHR(P_SQL VARCHAR2,P_COMMAND VARCHAR2 DEFAULT 'INTO',PFLAG NUMBER DEFAULT 1) RETURN VARCHAR2 IS------------------------------------------------------------------------------------- CREATED ON 2012/8/20 11:33:07 BY LHR--CHANGED ON 2012/8/20 11:33:07 BY LHR-- FUNCTION: 该函数返回-------------------------------------------------------------------------------------- 1、 回车--》 空格 2、 取前1500个字母 3、多空格--》单空格V_SQL VARCHAR2(32767) := TRIM(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REPLACE(REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(UPPER(P_SQL),'/\*.*?\*/'),'--.*+'),CHR(10),' '),CHR(13),' '),'[ ]+',' '),'/\*.*?\*/'),'[ ]+',' '));V_OBJECT_NAME VARCHAR2(4000);V_OBJECT_OWNER VARCHAR2(4000);V_L_INTO NUMBER;V_L_TABR NUMBER;BEGIN---从第一个INSERT位置开始截取50个字符V_SQL := REPLACE(SUBSTR(V_SQL, INSTR(V_SQL, P_COMMAND), 1000), '(', ' ');--INTO的位置 表名前的空格V_L_INTO := INSTR(V_SQL, P_COMMAND) + LENGTH(P_COMMAND) + 1;--I表名后的空格位置V_L_TABR := INSTR(V_SQL,' ',INSTR(V_SQL, P_COMMAND) + LENGTH(P_COMMAND) + 1,1);----- 表名V_OBJECT_NAME := SUBSTR(V_SQL, V_L_INTO, V_L_TABR - V_L_INTO);IF V_OBJECT_NAME LIKE '%.%' THENV_OBJECT_OWNER := SUBSTR(V_OBJECT_NAME,1,INSTR(V_OBJECT_NAME, '.') - 1); --表名前的OWNERV_OBJECT_NAME := SUBSTR(V_OBJECT_NAME, INSTR(V_OBJECT_NAME, '.') + 1); -- 去掉表名前的OWNEREND IF;IF PFLAG = 1 THENRETURN V_OBJECT_NAME;ELSERETURN V_OBJECT_OWNER;END IF;EXCEPTIONWHEN OTHERS THENNULL;END F_GET_SQL_OBJECT_LHR;FUNCTION F_GET_SQL_COMMAND_LHR(P_SQL VARCHAR2) RETURN VARCHAR2 IS------------------------------------------------------------------------------------- CREATED ON 2012/8/20 11:33:07 BY LHR--CHANGED ON 2012/8/20 11:33:07 BY LHR-- FUNCTION: 该函数返回SQL语句的类型-------------------------------------------------------------------------------------- 1、 回车--》 空格 2、 取前1500个字母 3、多空格--》单空格V_SQL VARCHAR2(32767) := TRIM(REPLACE(REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REPLACE(REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(UPPER(P_SQL),'/\*.*?\*/'),'--.*+'),CHR(10),' '),CHR(13),' '),'[ ]+',' '),'/\*.*?\*/'),'[ ]+',' '),'SELECT','SELECT '),'('));V_COMMAND VARCHAR2(255);BEGINIF P_SQL IS NULL THENRETURN '';ELSIF V_SQL IS NULL THENSELECT CASEWHEN UPPER(P_SQL) LIKE '%BEGIN%' THEN'PL/SQL EXECUTE'WHEN UPPER(P_SQL) LIKE '%MERGE%' THEN'MERGE'WHEN (REPLACE(UPPER(P_SQL), ' ', '') LIKE '%CREATEINDEX%' ORREPLACE(UPPER(P_SQL), ' ', '') LIKE'%CREATEUNIQUEINDEX%' OR REPLACE(UPPER(P_SQL), ' ', '') LIKE'%CREATEBITMAPINDEX%' ORUPPER(P_SQL) LIKE '%CREATE%INDEX%') THEN'CREATE INDEX'WHEN REPLACE(UPPER(P_SQL), ' ', '') LIKE '%CREATETABLE%' THEN'CREATE TABLE'WHEN UPPER(P_SQL) LIKE '%INSERT%' THEN'INSERT'WHEN UPPER(P_SQL) LIKE '%UPDATE%' THEN'UPDATE'WHEN UPPER(P_SQL) LIKE '%DELETE%' THEN'DELETE'WHEN UPPER(P_SQL) LIKE '%WITH%' THEN'WITH'WHEN UPPER(P_SQL) LIKE '%SELECT%' THEN'SELECT'WHEN REPLACE(UPPER(P_SQL), ' ', '') LIKE '%ALTERTABLE%' THEN'ALTER TABLE'WHEN REPLACE(UPPER(P_SQL), ' ', '') LIKE '%ALTERINDEX%' THEN'ALTER INDEX'ENDINTO V_COMMANDFROM DUAL;ELSEV_COMMAND := SUBSTR(V_SQL, 1, INSTR(V_SQL, ' ', 4) - 1);IF TRIM(V_COMMAND) IN ('ALTER', 'CREATE') THENV_SQL := REGEXP_REPLACE(REPLACE(REPLACE(V_SQL, 'UNIQUE'), 'BITMAP'),'[ ]+',' ');V_COMMAND := SUBSTR(V_SQL, 1, INSTR(V_SQL, ' ', 2, 2) - 1);ELSIF TRIM(V_COMMAND) IN ('DECLARE', 'BEGIN') THENV_COMMAND := 'PL/SQL EXECUTE';ELSIF TRIM(V_COMMAND) = 'MERGE' THENV_COMMAND := 'MERGE INTO';ELSIF TRIM(V_COMMAND) IS NULL THENSELECT CASEWHEN UPPER(P_SQL) LIKE '%BEGIN%' THEN'PL/SQL EXECUTE'WHEN UPPER(P_SQL) LIKE '%MERGE%' THEN'MERGE'WHEN (REPLACE(UPPER(P_SQL), ' ', '') LIKE '%CREATEINDEX%' ORREPLACE(UPPER(P_SQL), ' ', '') LIKE'%CREATEUNIQUEINDEX%' ORREPLACE(UPPER(P_SQL), ' ', '') LIKE'%CREATEBITMAPINDEX%' ORUPPER(P_SQL) LIKE '%CREATE%INDEX%') THEN'CREATE INDEX'WHEN REPLACE(UPPER(P_SQL), ' ', '') LIKE '%CREATETABLE%' THEN'CREATE TABLE'WHEN UPPER(P_SQL) LIKE '%INSERT%' THEN'INSERT'WHEN UPPER(P_SQL) LIKE '%UPDATE%' THEN'UPDATE'WHEN UPPER(P_SQL) LIKE '%DELETE%' THEN'DELETE'WHEN UPPER(P_SQL) LIKE '%WITH%' THEN'WITH'WHEN UPPER(P_SQL) LIKE '%SELECT%' THEN'SELECT'WHEN REPLACE(UPPER(P_SQL), ' ', '') LIKE '%ALTERTABLE%' THEN'ALTER TABLE'WHEN REPLACE(UPPER(P_SQL), ' ', '') LIKE '%ALTERINDEX%' THEN'ALTER INDEX'ENDINTO V_COMMANDFROM DUAL;END IF;END IF;V_COMMAND := REPLACE(REPLACE(REPLACE(TRIM(V_COMMAND), '(('), '('), '*');IF V_COMMAND NOT IN ('ALTER INDEX','ALTER TABLE','CREATE INDEX','CREATE TABLE','DELETE','INSERT','MERGE INTO','PL/SQL EXECUTE','SELECT','WITH','UPDATE') THENRETURN '';END IF;RETURN V_COMMAND;EXCEPTIONWHEN OTHERS THENNULL;END;END PKG_SQL_MONITOR_LHR;
/--------------------------------------------------------------EXEC PKG_SQL_MONITOR_LHR.P_GET_PPSQL_PARAMETER;-------------------------
EXEC DBMS_SCHEDULER.DROP_PROGRAM('PROG_SQL_DONE_LHR',TRUE);
EXEC DBMS_SCHEDULER.DROP_JOB(JOB_NAME => 'JOB_SQL_DONE_LHR' );BEGINDBMS_SCHEDULER.CREATE_PROGRAM(PROGRAM_NAME => 'PROG_SQL_DONE_LHR',PROGRAM_ACTION => 'PKG_SQL_MONITOR_LHR.P_SQL_DONE_LHR',PROGRAM_TYPE => 'STORED_PROCEDURE',ENABLED => TRUE);
END;
/BEGINDBMS_SCHEDULER.CREATE_JOB(JOB_NAME => 'JOB_SQL_DONE_LHR',PROGRAM_NAME => 'PROG_SQL_DONE_LHR',REPEAT_INTERVAL=> 'FREQ=SECONDLY;INTERVAL=30', JOB_STYLE => 'LIGHTWEIGHT',ENABLED=>TRUE,COMMENTS =>'监控已经执行完毕的SQL语句(V$SQL_MONITOR)');END;
/------------------------
EXEC DBMS_SCHEDULER.DROP_PROGRAM('PROG_SQL_EPP_LHR',TRUE);
EXEC DBMS_SCHEDULER.DROP_JOB(JOB_NAME => 'JOB_SQL_EPP_LHR' );
BEGINDBMS_SCHEDULER.create_program(program_name => 'PROG_SQL_EPP_LHR',program_action => 'PKG_SQL_MONITOR_LHR.P_SQL_EPP_LHR',program_type => 'STORED_PROCEDURE',enabled => TRUE);
END;
/BEGINDBMS_SCHEDULER.CREATE_JOB(JOB_NAME => 'JOB_SQL_EPP_LHR',PROGRAM_NAME => 'PROG_SQL_EPP_LHR',REPEAT_INTERVAL=> 'FREQ=SECONDLY;INTERVAL=30', JOB_STYLE => 'LIGHTWEIGHT',ENABLED=>TRUE,COMMENTS =>'记录性能低下的SQL语句');
END;
/EXEC DBMS_SCHEDULER.DROP_JOB(JOB_NAME => 'JOB_AUTO_TUNING_SQL_LHR' );
BEGIN--DBMS_SCHEDULER.drop_job('JOB_AUTO_TUNING_SQL_LHR');DBMS_SCHEDULER.CREATE_JOB(JOB_NAME => 'JOB_AUTO_TUNING_SQL_LHR',JOB_TYPE => 'STORED_PROCEDURE',JOB_ACTION => 'PKG_SQL_MONITOR_LHR.P_TUNING_SQL',repeat_interval => 'FREQ=MINUTELY;INTERVAL=50',ENABLED => TRUE,START_DATE => SYSDATE,COMMENTS => '每隔50分钟优化一次SQL');
END;
/EXEC DBMS_SCHEDULER.DROP_JOB(JOB_NAME => 'JOB_SQL_EPP2_LHR' );
BEGIN--DBMS_SCHEDULER.DROP_JOB('JOB_SQL_EPP2_LHR');DBMS_SCHEDULER.CREATE_JOB(JOB_NAME => 'JOB_SQL_EPP2_LHR',JOB_TYPE => 'STORED_PROCEDURE',JOB_ACTION => 'PKG_SQL_MONITOR_LHR.P_SQL_EPP2_LHR',REPEAT_INTERVAL => 'FREQ=MINUTELY;INTERVAL=28',ENABLED => TRUE,START_DATE => SYSDATE,COMMENTS => 'GV$SQL检查性能低下的SQL');
END;
/------------------------- 视图 ------------------------------
CREATE OR REPLACE VIEW VW_SQL_PP_LHR AS
--记录所有正在运行中的性能差的SQL语句
WITH TMPS AS(SELECT WB.INST_ID INST_ID,WB.SID SID,WB.SERIAL#,WB.SPID,WB.OSUSER,WB.USERNAME,WA.PLAN_DEPTH,WA.PLAN_OPERATION PLAN_OPERATION,WA.PLAN_OPTIONS,WA.PLAN_PARTITION_START,WA.PLAN_PARTITION_STOP,WA.STARTS,WA.PLAN_COST,WA.PLAN_CARDINALITY,NVL(WB.SQL_ID, WA.SQL_ID) SQL_ID,WB.SQL_EXEC_START,WA.PX_SERVERS_REQUESTED,WA.PX_SERVERS_ALLOCATED,WA.PX_MAXDOP,WA.ELAPSED_TIME_S ELAPSED_TIME_S,WA.CPU_TIME CPU_TIME,WA.BUFFER_GETS,WA.PHYSICAL_READ_BYTES,WA.PHYSICAL_WRITE_BYTES,WA.USER_IO_WAIT_TIME USER_IO_WAIT_TIME,NVL((SELECT NS.SQL_TEXTFROM GV$SQLAREA NSWHERE NS.SQL_ID = WB.SQL_IDAND NS.INST_ID = WB.INST_ID),WA.SQL_TEXT) SQL_TEXT,WB.LOGON_TIME,WB.SQL_EXEC_ID,WB.EVENT,WB.BLOCKING_INSTANCE BLOCKING_INSTANCE,WB.BLOCKING_SESSION BLOCKING_SESSION,WB.BLOCKING_SESSION_SERIAL# BLOCKING_SESSION_SERIAL#,WB.TADDR,WB.SADDR,WB.LAST_CALL_ET,(WB.SESSION_INFO || '--' || WB.SESSION_TYPE || '--' || WB.MACHINE) SESSION_INFO,(SELECT NS.EXECUTIONSFROM GV$SQLAREA NSWHERE NS.SQL_ID = WB.SQL_IDAND NS.INST_ID = WB.INST_ID) EXECUTIONS,'SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(''' || WB.SQL_ID ||''',' || WB.SQL_CHILD_NUMBER || ',''advanced''));' SQL_PLAN,WB.ASH_COUNTS,WB.SESSION_STATEFROM (SELECT A.INST_ID,A.SID,A.PLAN_DEPTH,A.PLAN_OPERATION PLAN_OPERATION,A.PLAN_OPTIONS,A.PLAN_PARTITION_START,A.PLAN_PARTITION_STOP,A.STARTS,MAX(A.PLAN_COST) OVER(PARTITION BY A.INST_ID, A.SID, A.KEY, A.SQL_EXEC_ID, A.SQL_ID) AS PLAN_COST,MAX(A.PLAN_CARDINALITY) OVER(PARTITION BY A.INST_ID, A.SID, A.KEY, A.SQL_EXEC_ID, A.SQL_ID) AS PLAN_CARDINALITY,A.SQL_ID,A.SQL_EXEC_START,B.PX_SERVERS_REQUESTED,B.PX_SERVERS_ALLOCATED,B.PX_MAXDOP,(B.ELAPSED_TIME / 1000000) ELAPSED_TIME_S,(B.CPU_TIME / 1000000) CPU_TIME,B.BUFFER_GETS,B.PHYSICAL_READ_BYTES,B.PHYSICAL_WRITE_BYTES,(B.USER_IO_WAIT_TIME / 1000000) USER_IO_WAIT_TIME,B.SQL_TEXT SQL_TEXT,(B.MODULE || '--' || B.ACTION || '--' || B.PROGRAM || '--' ||B.PROCESS_NAME || '--' || B.CLIENT_IDENTIFIER || '--' ||B.CLIENT_INFO || '--' || B.SERVICE_NAME) SESSION_INFO,A.SQL_EXEC_IDFROM GV$SQL_PLAN_MONITOR A, GV$SQL_MONITOR BWHERE A.SID = B.SIDAND A.KEY = B.KEYAND A.INST_ID = B.INST_IDAND A.SQL_EXEC_ID = B.SQL_EXEC_IDAND A.STATUS IN ('EXECUTING', 'DONE(ERROR)')AND B.STATUS IN ('EXECUTING', 'DONE(ERROR)')AND B.PROCESS_NAME NOT LIKE 'p%') WARIGHT OUTER JOIN (SELECT ASH.INST_ID,ASH.SESSION_ID SID,ASH.SESSION_SERIAL# SERIAL#,(SELECT PR.SPIDFROM GV$PROCESS PRWHERE GVS.PADDR = PR.ADDRAND PR.INST_ID = ASH.INST_ID) SPID,ASH.SESSION_TYPE,ASH.USER_ID,ASH.SQL_ID,ASH.SQL_CHILD_NUMBER,ASH.SQL_OPNAME,ASH.SQL_EXEC_ID,NVL(ASH.EVENT, GVS.EVENT) EVENT,ASH.SESSION_STATE,ASH.BLOCKING_SESSION,ASH.BLOCKING_SESSION_SERIAL#,ASH.BLOCKING_INST_ID BLOCKING_INSTANCE,ASH.CLIENT_ID,ASH.MACHINE,GVS.LAST_CALL_ET,GVS.TADDR,GVS.SADDR,GVS.LOGON_TIME,GVS.USERNAME,GVS.OSUSER,GVS.SQL_EXEC_START,(GVS.MODULE || '--' || GVS.ACTION || '--' || GVS.PROGRAM || '--' ||GVS.PROCESS || '--' || GVS.CLIENT_IDENTIFIER || '--' ||GVS.CLIENT_INFO || '--' || GVS.SERVICE_NAME) SESSION_INFO,COUNT(*) ASH_COUNTSFROM GV$ACTIVE_SESSION_HISTORY ASH, GV$SESSION GVSWHERE ASH.INST_ID = GVS.INST_IDAND GVS.SQL_ID = ASH.SQL_IDAND GVS.SQL_EXEC_ID = ASH.SQL_EXEC_IDAND ASH.SESSION_ID = GVS.SIDAND ASH.SESSION_SERIAL# = GVS.SERIAL#AND GVS.STATUS = 'ACTIVE'AND ASH.SQL_ID IS NOT NULLGROUP BY ASH.INST_ID,ASH.SESSION_ID,ASH.SESSION_SERIAL#,ASH.SESSION_TYPE,ASH.USER_ID,ASH.SQL_ID,ASH.SQL_CHILD_NUMBER,ASH.SQL_OPNAME,ASH.SQL_EXEC_ID,NVL(ASH.EVENT, GVS.EVENT),ASH.SESSION_STATE,ASH.BLOCKING_SESSION,ASH.BLOCKING_SESSION_SERIAL#,ASH.BLOCKING_INST_ID,ASH.CLIENT_ID,ASH.MACHINE,GVS.LAST_CALL_ET,GVS.TADDR,GVS.SADDR,GVS.LOGON_TIME,GVS.USERNAME,GVS.OSUSER,GVS.PADDR, (GVS.MODULE || '--' || GVS.ACTION || '--' || GVS.PROGRAM || '--' ||GVS.PROCESS || '--' || GVS.CLIENT_IDENTIFIER || '--' ||GVS.CLIENT_INFO || '--' || GVS.SERVICE_NAME),GVS.SQL_EXEC_STARTHAVING COUNT(*) > 6) WBON (WB.SID = WA.SID AND WB.INST_ID = WA.INST_ID ANDWB.SQL_ID = WA.SQL_ID AND WB.SQL_EXEC_ID = WA.SQL_EXEC_ID)
)
------------------------------------------ 笛卡尔积
SELECT DISTINCT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO, '笛卡尔积【' || COUNT(*) OVER(PARTITION BY T.INST_ID, T.SID, T.SERIAL#, T.SQL_ID) || '】个' MONITOR_TYPESFROM TMPS TWHERE T.PLAN_OPERATION = 'MERGE JOIN'AND T.PLAN_OPTIONS = 'CARTESIAN'AND T.USERNAME NOT IN ('SYS')UNION ALL------------------------------------------ SQL执行时间过大
SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'执行时间过大' MONITOR_TYPESFROM TMPS TWHERE T.ELAPSED_TIME_S > 10 --5 * 60 * 60AND (nvl(PLAN_DEPTH,1)=1)UNION ALL------------------------------------------ 分区表全分区扫描SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'分区表全分区扫描' MONITOR_TYPESFROM TMPS TWHERE T.PLAN_OPERATION LIKE 'PARTITION%'AND T.PLAN_OPTIONS = 'ALL'-- AND T.ELAPSED_TIME_S >= 0.5 * 60 * 60UNION ALL------------------------------------------ 执行计划中COST花费超大SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'执行计划中COST花费超大【' || T.PLAN_COST || '】' MONITOR_TYPESFROM TMPS TWHERE T.PLAN_COST >= 3107523095AND (nvl(PLAN_DEPTH,1)=1)UNION ALL
------------------------------------------ 执行计划中预估行数超大SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO, '执行计划中预估行数超大【' || T.PLAN_CARDINALITY || '】' MONITOR_TYPESFROM TMPS TWHERE T.PLAN_CARDINALITY > 30748908521460AND (nvl(PLAN_DEPTH,1)=1)UNION ALL
------------------------------------------ SQL请求并行数过多SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO, 'SQL请求并行数过多【' || PX_MAXDOP || '】' MONITOR_TYPESFROM TMPS TWHERE T.PX_MAXDOP>=8AND (nvl(PLAN_DEPTH,1)=1)UNION ALL
------------------------------------------ 系统预估的剩余执行时间过长SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME, T.ASH_COUNTS,T.SESSION_INFO,'系统预估的剩余执行时间过长【' || ROUND(D.TIME_REMAINING) || '】' MONITOR_TYPESFROM TMPS T, GV$SESSION_LONGOPS DWHERE T.SQL_EXEC_ID = D.SQL_EXEC_IDAND T.SID = D.SIDAND T.SERIAL# = D.SERIAL#AND D.TIME_REMAINING > 10AND T.INST_ID = D.INST_IDAND D.TIME_REMAINING >0AND (nvl(PLAN_DEPTH,1)=1)UNION ALL------------------------------------------ 等待事件异常SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'等待事件异常【' || T.EVENT || '】' MONITOR_TYPESFROM TMPS TWHERE T.EVENT NOT IN ('db file sequential read', 'db file scattered read','db file parallel write','db file parallel read')AND (nvl(PLAN_DEPTH,1)=1)UNION ALL
------------------------------------------ TMP表空间占用过大SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'SQL占用TMP表空间过大【' || C.BYTES || '】Bytes' MONITOR_TYPESFROM TMPS T,(SELECT A.INST_ID, A.SESSION_ADDR, SUM(A.BLOCKS) * 8 * 1024 BYTESFROM GV$TEMPSEG_USAGE AGROUP BY A.INST_ID, A.SESSION_ADDR) CWHERE C.SESSION_ADDR = T.SADDRAND C.INST_ID = T.INST_IDAND C.BYTES > 10 --50 * 1024 * 1024 * 1024AND (nvl(PLAN_DEPTH,1)=1)UNION ALL
----------------------------------------- SQL占用UNDO过大,INACTIVE的会话也可能占用UNDO,但是这里只记录正在运行的SQL语句SELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'SQL占用UNDO过大【' || USED_SIZE_BYTES || '】Bytes' MONITOR_TYPESFROM TMPS T,(SELECT ST.ADDR,ST.INST_ID,(ST.USED_UBLK * 8 * 1024) USED_SIZE_BYTESFROM GV$TRANSACTION ST, V$ROLLNAME R, GV$ROLLSTAT GWHERE ST.XIDUSN = R.USNAND R.USN = G.USNAND G.INST_ID = ST.INST_ID) V1WHERE V1.ADDR = T.TADDRAND T.INST_ID = V1.INST_IDAND USED_SIZE_BYTES > 1024 -- 50 * 1024 * 1024 * 1024UNION ALL
----------------------------------------- 耗费性能SQLSELECT T.INST_ID,T.SID,T.SERIAL#,T.SPID,T.OSUSER,T.USERNAME,T.EVENT,T.SESSION_STATE,T.SQL_TEXT,T.EXECUTIONS,T.ELAPSED_TIME_S,T.CPU_TIME,T.USER_IO_WAIT_TIME,T.BUFFER_GETS,T.PLAN_OPERATION,T.STARTS,T.PLAN_PARTITION_START,T.PLAN_PARTITION_STOP,T.PHYSICAL_READ_BYTES,T.PHYSICAL_WRITE_BYTES,T.BLOCKING_INSTANCE,T.BLOCKING_SESSION,T.BLOCKING_SESSION_SERIAL#,T.LAST_CALL_ET,T.SQL_ID,T.SQL_EXEC_START,T.SQL_PLAN,T.LOGON_TIME,T.ASH_COUNTS,T.SESSION_INFO,'ASH捕获的次数【' || T.ASH_COUNTS || '】【'||SESSION_STATE||'】' MONITOR_TYPESFROM TMPS T
WHERE T.ASH_COUNTS>=4AND (nvl(PLAN_DEPTH,1)=1)ORDER BY SQL_EXEC_START DESC
看看之前的一些结果:
修改后的结果:
该脚本中有视图也有表。若想直接查询数据库耗费性能的SQL语句,可以直接使用视图VW_SQL_PP_LHR进行查询。若想查询历史记录,则可以通过表XB_SQL_MONITOR_PP_LHR来查询。另外,对于监控中使用的参数表为XB_SQL_PARAMETERS_LHR。JOB每次都会从该表中读取到配置参数的值,该表的查询结果如下图所示:
该脚本中有视图也有表。若想直接查询数据库耗费性能的SQL语句,可以直接使用视图VW_SQL_PP_LHR进行查询。若想查询历史记录,则可以通过表XB_SQL_MONITOR_PP_LHR来查询。另外,对于监控中使用的参数表为XB_SQL_PARAMETERS_LHR。JOB每次都会从该表中读取到配置参数的值,该表的查询结果如下图所示:
下面简单测试一下上边的监控脚本的效果。首先构造一个笛卡尔积连接的SQL,并开启并行。再构造一个锁等待的SQL。如下所示的3条SQL语句
① SELECT /*+ monitor parallel(20)*/
COUNT(*)
FROM DBA_OBJECTS A,
DBA_OBJECTS B,
DBA_OBJECTS C,
DBA_OBJECTS D;
② UPDATE /*+ MONITOR */ XB_SQL_MONITOR_LHR T SET T.SQL_TEXT='XXXXXXXXXXXX';
③ UPDATE /*+ MONITOR */ XB_SQL_MONITOR_LHR T SET T.SQL_TEXT='XXXXXXXXXXXX';
让以上3条SQL在不同的会话运行,等待大约5分钟后然后查看监控效果。
首先查询视图VW_SQL_PP_LHR:
从结果可以很明显的看出,会话(28,583)在等待锁,而会话(133,437)阻塞了会话(28,583)。对于会话(29,1207)可以看出,由于开了20个并行,所以导致系统CPU不足,所有的会话均在等待CPU资源,而且该会话的SQL语句产生了笛卡尔积、并行数过多、COST花费过大等问题。
对于该JOB的性能,由于作者从多个方面做了优化,所以基本不影响数据库的运行。下面是该JOB的运行日志:
SELECT JRD.LOG_ID,
JRD.JOB_NAME,
N.JOB_CLASS,
TO_CHAR(JRD.ACTUAL_START_DATE, 'YYYY-MM-DD HH24:MI:SS') ACTUAL_START_DATE,
TO_CHAR(JRD.LOG_DATE, 'YYYY-MM-DD HH24:MI:SS') LOG_DATE,
JRD.STATUS,
JRD.ERROR#,
JRD.RUN_DURATION 运行时长,
JRD.ADDITIONAL_INFO
FROM DBA_SCHEDULER_JOB_LOG N, DBA_SCHEDULER_JOB_RUN_DETAILS JRD
WHERE N.LOG_ID = JRD.LOG_ID
AND N.JOB_NAME LIKE 'JOB_SQL_%'
ORDER BY JRD.LOG_ID DESC;
JOB运行日志如下图所示:
查询监控表XB_SQL_MONITOR_PP_LHR也可获取相应的监控信息,这里不再演示。
About Me
...............................................................................................................................
● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用
● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/viewspace-1262559/
● 本文博客园地址:http://www.cnblogs.com/lhrbest
● 本文pdf版及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● QQ群:230161599 微信群:私聊
● 联系我请加QQ好友(646634621),注明添加缘由
● 于 2017-04-01 09:00 ~ 2017-04-03 22:00 在魔都完成
● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
...............................................................................................................................
拿起手机使用微信客户端扫描下边的左边图片来关注小麦苗的微信公众号:xiaomaimiaolhr,扫描右边的二维码加入小麦苗的QQ群,学习最实用的数据库技术。
![]()
![]()
![]()
【SQL监控】SQL完全监控的脚本相关推荐
- 用Semisynchronous Replication半同步,mk-table-checksum数据同步一致性检查,监控主从同步运行状态的脚本等方式加强SQL性能和数据审核...
一,为A组在X单独另建一个MYSQL服务器(MYSQL B),A组平时更新的数据库为MYSQL B.待MYSQL B的数据审核准确无误后.发布给现在布置在X上的MYSQL服务器(MYSQL A).并进 ...
- 集中化监控SQL Server数据库
英文原文地址:https://www.simple-talk.com/sql/database-administration/centralize-your-database-monitoring-p ...
- 5. SQL Server数据库性能监控 - 当前请求
5. SQL Server数据库性能监控 - 当前请求 原文:5. SQL Server数据库性能监控 - 当前请求 对于在线运行的系统,当前数据库性能监控,通常监视以下几点: (1) 是否有阻塞 ( ...
- 监控和剖析数据库操作P6Spy,SQL Profiler,SQL 使用简介
新一篇: 关于java类的动态装载 几乎 80% - 85% 的数据库性能问题是由于应用数据库的设计或者应用程序本身的代码所引起的.因此良好的事务处理能力需要在设计应用程序的时候,在设计数据库的时候就 ...
- mybatis开启log_mybatis使用spring-druid数据源连接池配置log4j打印sql语句以及开启监控平台...
杂七杂的杂 作为程序员,开发工程中,一套利于测试或者监控的工具很重要,mybatis默认没有提供log4j的打印sql语句的配置. 这对于开发rest服务,提供接口的开发者而言,是在很不好做,再加上m ...
- (转)SQL Server数据库状态监控 - 作业状态
4. SQL Server数据库状态监控 - 作业状态 有很多地方可以设置定时任务,比如:Windows的计划任务,Linux下的crontab,各种开发工具里的timer组件.SQL Server也 ...
- ORACLE常用性能监控SQL【一】
目录(?)[+] 系列 ORACLE常用性能监控SQL[一] ORACLE常用性能监控SQL[二] Oracle-动态性能视图解读 系列 死锁后的解决办法 生成Kill Session语句 查看导致死 ...
- 第三篇——第二部分——第六文 监控SQL Server镜像
原文: 第三篇--第二部分--第六文 监控SQL Server镜像 原文出处:http://blog.csdn.net/dba_huangzj/article/details/26846203 要优化 ...
- 监控 SQL Server 的运行状况
Microsoft SQL Server 2005 提供了一些工具来监控数据库.方法之一是动态管理视图.动态管理视图 (DMV) 和动态管理函数 (DMF) 返回的服务器状态信息可用于监控服务器实例的 ...
- 采用Opserver来监控你的ASP.NET项目系列(二、监控SQL Server与Asp.Net项目)
前言 之前有过2篇关于如何监控ASP.NET core项目的文章,有兴趣的也可以看看. ASP.NET Core之跨平台的实时性能监控 ASP.NET Core之跨平台的实时性能监控(2.健康检查) ...
最新文章
- 论文笔记:Spatial-Temporal Map Vehicle Trajectory Detection Using Dynamic Mode Decomposition and Res-UNe
- android按钮最底,Android:点击按钮后布局上的动画,最低SDK版本为14
- java注解式开发_JAVA语言之Spring MVC注解式开发使用详解[Java代码]
- Servlet的Cookie和HttpSession
- python处理文本格式_python linecache 处理固定格式文本数据的方法
- 圣母大学应用计算机数学统计,圣母大学(美国)应用、计算数学与统计学本科专业.pdf...
- 好奇!仅 13kB 大小的游戏,源码长啥样?
- Crypto API 学习笔记一
- php语言冒泡法,冒泡排序法(php)
- mysql 5.6.20 优化_mysql 5.6.20 占用内存超大,大概400M左右
- 调用外部 DLL 中的函数(显示调用)
- Implement Trie (Prefix Tree)
- 【Java】Java日志框架Logback的简单例子
- 怎样给家庭组计算机授权,steam如何设置家庭共享?steam设置家庭共享方法
- C语言读写txt文件
- python 设置输入法为英文_python 怎么转化输入法
- 百度 UNIT 使用
- 十大开源Web应用安全测试工具
- 学习ARM开发(10)
- linux安装python任意版本,一键安装和一键卸载shell脚本
热门文章
- js 身份证 港澳通行证正则
- 角度转度分秒lisp函数_自改小程序,提示错误,运行另一个lisp后就不会出错,求帮忙!...
- uc浏览器电脑版翻译设置在哪 uc浏览器翻译网页教程
- 小程序拼团营销怎么做
- OPA 防止服务重定向
- XYIXY.COM短网址在线生成,快速、稳定、永久有效,免费开放网址缩短API接口。...
- spark streaming 整合kafka 报错 KafkaConsumer is not safe for multi-threaded access
- 如何用Sonic云真机打王者
- 维护采购订单审批的特性Characteristic和类Class
- 编写一个程序。要求输入5个学生的成绩(从0到100的整数)并将这5个数保存到文件“data.txt”中,然后再编写一个程序,从文件“data.txt”中读取这5个学生的成绩,计算并输出他们的平均数,然