引子
在分析某客户网友问题时,发现oracle ash并非所有的SQL语句会被其捕获。即然ash不会捕获所有的sql语句类型,那么v$session也不会记录所有的sql操作类型吧,或者在捕获时是有一定规则?
分析过程
申明
测试SQL脚本
col sql_text for a50
set linesize 300
select sid,
taddr,
v$session.sql_id,
v$session.prev_sql_id,
sql_text
from v$session,v$sql
where sid=73 and
decode(v$session.sql_id,null,v$session.prev_sql_id,v$session.sql_id)=v$sql.sql_id;
测试期间本SQL执行,仅贴结果
具体测试
select查询会记录在v$session
SQL> select * from dual;D-XSID TADDR SQL_ID PREV_SQL_ID SQL_TEXT---------- ---------------- ------------- ------------- -------------------73 a5ks9fhw2v9s1 a5ks9fhw2v9s1 select * from dual
正常情况ddl操作不会记录在v$session
(注意:正常情况是指ddl操作时间消耗极短,估计是未达到捕获的时间阀值或某种规则,所以不会被捕获)
SQL> create table t_ddl3(a int);Table created.SQL>no rows selected
但是查阅v$session.command列,是包括各种ddl操作指令,可见v$session是具备记录ddl操作的功能


综上所述,我分析是应该是会记录等待某种资源的ddl操作,而不是不一般的ddl操作。
下面进行验证
1,测试会话 73SQL> create table t_ddl_lock(a int,b int);Table created.SQL> insert into t_ddl_lock values(1,1);1 row created.SQL> commit;Commit complete.2,测试会话2(产生排它读锁)SQL> select * from t_ddl_lock for update;A B---------- ----------1 13,测试会话73可见处于锁等待的DDL语句会被记录SQL> alter table t_ddl_lock add c int;SQL>SID TADDR SQL_ID PREV_SQL_ID SQL_TEXT---------- ---------------- ------------- ------------- --------------------------------------------------73 000000008454D800 5xn3tsayfcsds 6sfjg9y7w0buc alter table t_ddl_lock add c int
在生产系统中,ddl操作是严格禁止,但万事总有遗漏或疏忽。某些情况下,开发或业务维护人员误操作,执行了ddl操作,导致业务模块受到影响,严重情形会令业务系统停机。有没有一种方法可以监控各种情形(正常执行DDL及等待资源DDL)呢,数据库参数enable_ddl_logging可以实现这个功能。
SQL> show parameter ddlNAME TYPE VALUE------------------------------------ ----------- ------------------------------ddl_lock_timeout integer 0enable_ddl_logging boolean FALSESQL> alter system set enable_ddl_logging=true;System altered.SQL> create table t_ddl6(a int);Table created.SQL> alter table t_ddl6 add b int;Table altered.在11g 会记录在alert告警日志,开启enable_ddl_logging不会在告警日志记录ddl[oracle@yuminbase trace]$ pwd/u01/app/oracle/diag/rdbms/zxydb/zxydb/trace[oracle@yuminbase trace]$ tail -f alert_zxydb.log2019-11-12T12:33:59.098191+08:00create table t_ddl6(a int);2019-11-12T12:33:59.098193+08:00alter table t_ddl6 add b int;在12c 会记录在如下文件[oracle@yuminbase ddl]$ pwd/u01/app/oracle/diag/rdbms/zxydb/zxydb/log/[oracle@yuminbase log]$ lltotal 4drwxr-x--- 2 oracle oinstall 20 Nov 12 12:33 ddl-rw-r----- 1 oracle oinstall 140 Nov 12 12:52 ddl_zxydb.logdrwxr-x--- 2 oracle oinstall 6 Jan 27 2019 debugdrwxr-x--- 2 oracle oinstall 6 Jan 27 2019 hcsdrwxr-x--- 2 oracle oinstall 6 Jan 27 2019 imdbdrwxr-x--- 2 oracle oinstall 6 Jan 27 2019 test[oracle@yuminbase log]$ more ddl_zxydb.log2019-11-12T12:33:59.098191+08:00diag_adl:create table t_ddl6(a int)2019-11-12T12:52:14.363126+08:00diag_adl:alter table t_ddl6 add b int[oracle@yuminbase log]$ more ddl_zxydb.log2019-11-12T12:33:59.098191+08:00diag_adl:create table t_ddl6(a int)2019-11-12T12:52:14.363126+08:00diag_adl:alter table t_ddl6 add b int[oracle@yuminbase log]$ tail -f ddl_zxydb.log2019-11-12T12:33:59.098191+08:00diag_adl:create table t_ddl6(a int)2019-11-12T12:52:14.363126+08:00diag_adl:alter table t_ddl6 add b int2019-11-12T12:56:19.397280+08:00diag_adl:drop table t_ddl6 purge--如下文件也会记录ddl,与上述文件区别在于记录了pid(操作系统id)[oracle@yuminbase ddl]$ pwd/u01/app/oracle/diag/rdbms/zxydb/zxydb/log/ddl[oracle@yuminbase ddl]$ more log.xml<msg time='2019-11-12T12:33:59.097+08:00' org_id='oracle' comp_id='rdbms'msg_id='opiexe:4705:2946163730' type='UNKNOWN' group='diag_adl'level='16' host_id='yuminbase' host_addr='10.0.0.72'pid='1459' version='1'><txt>create table t_ddl6(a int)</txt></msg><msg time='2019-11-12T12:52:14.362+08:00' org_id='oracle' comp_id='rdbms'msg_id='opiexe:4705:2946163730' type='UNKNOWN' group='diag_adl'level='16' host_id='yuminbase' host_addr='10.0.0.72'pid='1459'><txt>alter table t_ddl6 add b int</txt>
延伸思考
v$active_session_history即ash以及dba_hist_active_sess_history同上逻辑,也不会记录ddl(注:不会记录正常执行的DDL语句,而会记录出现等待资源的DDL)
如果记录在v$session及ash及awr上述相关表,必定是ddl语句要么消耗时间很久,要么在等待某种资源
v$session.command对应于v$active_session_history.opname。监控数据库时,可以监控ash opname列,也是一种分析诊断问题的方法
培训课件
(收费20元)


联系方式






