您的位置:首页 > 数据库 > SQL

【SQL监控】SQL完全监控的脚本

2021-04-17 23:40 806 查看


       

    今天小麦苗给大家分享了一套SQL监控的脚本,有兴趣的朋友可以拿来玩玩。


 【SQL监控】SQL完全监控的脚本          


脚本内容如下所示:


 
             
             

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

。。。。。。。。。。。。。。。。。。。。。。。。。。


由于公众号最多2W字,所以,脚本并没有列举完,全部脚本请参考:

http://blog.itpub.net/26736162/viewspace-1262559/。



该脚本中有视图也有表。若想直接查询数据库耗费性能的语句,可以直接使用视图进行查询。若想查询历史记录,则可以通过表来查询。另外,对于监控中使用的参数表为。每次都会从该表中读取到配置参数的值,该表的查询结果如下图所示:下面简单测试一下上边的监控脚本的效果。首先构造一个笛卡尔积连接的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';

首先查询视图VW_SQL_PP_LHR:


对于该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也可获取相应的监控信息,这里不再演示。


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: