查看Oracle redo日志来分析SQL执行记录




1)设置Oracle数据字典导出路径参数(可选)

shutdown immediate

alter system set UTL_FILE_DIR='/opt/oracle/utl' scope=spfile; 

execute dbms_logmnr_d.build(dictionary_filename => 'logminer_dict.ora', dictionary_location => '/opt/oracle/utl');

startup

 

2)增加需要分析的重做日志文件(在线归档均可)

execute dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/OraBase/oradata/inomc/redo01.log', options=>dbms_logmnr.new);

execute dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/OraBase/oradata/inomc/redo02.log', options=>dbms_logmnr.new);

execute dbms_logmnr.add_logfile(LogFileName=>'/opt/oracle/OraBase/oradata/inomc/redo03.log', options=>dbms_logmnr.new);

3)执行日志加载

使用数据字典

execute dbms_logmnr.start_logmnr(DictFileName=> '/opt/oracle/utl/logminer_dict.ora') ;

使用在线字典

execute dbms_logmnr.start_logmnr(Options=>dbms_logmnr.DICT_FROM_ONLINE_CATALOG) ;

4)查看日志

SELECT sql_redo FROM v$logmnr_contents;

5)结束分析,卸载日志

execute dbms_logmnr.end_logmnr;

 

在PL/SQL中利用XML ,Oracle提供了几个组件,让开发人员能轻松地利用XML技术。这些组件包括:

1.XML分析程序。即用来分析、构造和验证XML文档。

2.XPath引擎。它是使用Xpath(XML标准的另一个元素)说明语法在内存中搜索XML文档的实用程序。SLT处理器。它在Oracle数据库中支持XSLT,允许您把XML文档转换成其他格式。

3.XML SQL实用程序。可以使用SQL产生XML文档,使您可以在Oracle数据库表格中轻松地插入基于XML的数据。

对于PL/SQL开发人员而言,XML分析程序是最重要的组件。通过它,您可以在Oracle数据库中分析、操纵和转换XML文档。XML分析程序由一套APIs(应用程序编程接口)构成。

通过generate解析SQL日志生成xml进行SQL回放_xml文件

===================================================================================================================================================================================

xml generate


生成Test.xml,内容如下





1


2


3


4


5


6


7


8


9


10




​<​​​​staff​​ ​​content = "name and id">​


​<​​​​member​​​​>​


​<​​​​name​​​​>Arwen</​​​​name​​​​>​


​<​​​​eno​​​​>123</​​​​eno​​​​>​


​</​​​​member​​​​>​


​<​​​​member​​​​>​


​<​​​​name​​​​>Tom</​​​​name​​​​>​


​<​​​​eno​​​​>456</​​​​eno​​​​>​


​</​​​​member​​​​>  ​


​</​​​​staff​​​​>​



 1.生成xml的plsql code:





1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53




​declare​


​doc  XMLDOM.DOMDOCUMENT;​


​doc_node  XMLDOM.DOMNODE;​


​root_node  XMLDOM.DOMNODE;​


​user_node XMLDOM.DOMNODE;​


​item_node XMLDOM.DOMNODE;​


​root_elmt XMLDOM.DOMELEMENT;​


​user_elmt XMLDOM.DOMELEMENT;​


​item_elmt XMLDOM.DOMELEMENT;​


​item_text XMLDOM.DOMTEXT;​


​begin​


​doc := XMLDOM.NEWDOMDOCUMENT;​


​xmldom.setVersion(doc, ​​​​'1.0'​​​​);​


​xmldom.setCharset(doc, ​​​​'UTF-8'​​​​);​


​--根节点​


​doc_node := XMLDOM.MAKENODE(doc);​


​root_elmt := XMLDOM.CREATEELEMENT(doc,​​​​'staff'​​​​);​


​XMLDOM.SETATTRIBUTE(root_elmt,​​​​'content '​​​​,​​​​'name and id'​​​​);​


​root_node:=XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(root_elmt));​


 


​--节点1​


​user_elmt := XMLDOM.CREATEELEMENT(doc,​​​​'member'​​​​);​


​user_node :=XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(user_elmt));​


 


​item_elmt :=XMLDOM.CREATEELEMENT(doc,​​​​'name'​​​​);​


​item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));​


​item_text := XMLDOM.CREATETEXTNODE(doc,​​​​'Arwen'​​​​);​


​item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));​


 


​item_elmt :=XMLDOM.CREATEELEMENT(doc,​​​​'eno'​​​​);​


​item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));​


​item_text := XMLDOM.CREATETEXTNODE(doc,​​​​'123'​​​​);​


​item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));​


 


​--节点2​


​user_elmt := XMLDOM.CREATEELEMENT(doc,​​​​'member'​​​​);​


​user_node :=XMLDOM.APPENDCHILD(root_node, XMLDOM.MAKENODE(user_elmt));​


 


​item_elmt :=XMLDOM.CREATEELEMENT(doc,​​​​'name'​​​​);​


​item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));​


​item_text := XMLDOM.CREATETEXTNODE(doc,​​​​'tom'​​​​);​


​item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));​


 


​item_elmt :=XMLDOM.CREATEELEMENT(doc,​​​​'eno'​​​​);​


​item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));​


​item_text := XMLDOM.CREATETEXTNODE(doc,​​​​'456'​​​​);​


​item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));​


 


​--写入操作系统文件中​


​XMLDOM.WRITETOFILE(doc,​​​​'DIR'​​​​||​​​​'\Test.xml'​​​​);​​​​--注意必须先创建一个文件目录dir​


​--可以通过语句 : create or replace directory dir as 'd:\temp'​


​XMLDOM.FREEDOCUMENT(doc);​


​end​​​​;​



 2.将xml encode 成clob 写入文件:





1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26




​declare​


​l_f utl_file.file_type;​


​clobpart varchar2(2048);​


​offset ​​​​integer​​​​;​


​l_xmltype XMLTYPE;​


​cloblen ​​​​integer​​​​;​


​response_clob CLOB;​


​resp_domdoc DBMS_XMLDOM.DOMDOCUMENT;​


​begin​


​l_f  := utl_file.fopen(​​​​'TEST_DIR'​​​​,l_full_file_name,​​​​'w'​​​​);​


​utl_file.put_line(l_f,​​​​'<?xml version="1.0" encoding="utf-8" standalone="yes"?>'​​​​||chr(13));​


​resp_domdoc := SoapEncPrcnScnrPckgRead.encd_root_prcn_scnr_pckg_read(p_psp_resp_doc);​


​l_xmltype := dbms_xmldom.getXmlType(resp_domdoc);​


​dbms_xmldom.freeDocument(resp_domdoc);​


​response_clob := l_xmltype.getClobVal;​


​cloblen := LENGTH(response_clob);​


​while offset < cloblen​


​loop​


​clobPart := dbms_lob.substr(response_clob, 1024, offset);​


​utl_file.put(l_f, clobPart);​


​offset := offset + 1024;​


​end​​ ​​loop;​


​utl_file.fflush(l_f);​


​utl_file.fclose(l_f);​


​end​​​​;​


​/​



 3.结合使用XMLDOM和utl_file

    这样生成XML文件非常方便,能满足一般的应用了.但是XMLDOM有个缺点,就是一次性在内存中生成所有xml文件内容,然后写入到磁盘文件中.如果 xml文件太大,比如说有个table有几个G,想把它保存成xml文件.这样可能就会出现内存不足,生成文件失败.那该咋整呢?

    可能首先想到的是用UTL_FILE去生成文件.

    里面的内容全部手动写成xml格式的,然后保存成xml后缀的文件.这样确实可行.但有个麻烦问题时如果一些节点内容含有xml的五个保留字符的话 (&,<,>,'," 分别是和号,小于号,大于号,单引号,双引号),我们如果以文本方式打开xml文件是看不到节点内容里面有这些保留字的,都转换成了对应 的&amp, &gt, &lt, &apos, &quot.节点指定的是上面的Arwen或123,假如有名字(A&r<w>e'n")则保存到xml文件中应该改成 (A&ampr&gtw&lte&aposn&quot).如果用xmldom会默认去转换,不用我们管了.如 果用UTL_FILE必须手动写代码去转换.

    假如有表staff(name varchar2(30), eno integer),里面有几个G的内容,要转换成开头讲的那种格式的xml文件。

    --生成xml的代码其中XML文件的头和尾用UTL_FILE直接写入文件中,节点内容用xmldom生成,然后写到clob变量中,再把clob变量值用utl_file写入到xml文件中。





1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53


54


55




​declare​


​STAFFINFO  UTL_FILE.FILE_TYPE;​


​v_temp clob;​


​cursor​​ ​​c_table_info ​​​​is​​ ​​select​​ ​​name​​​​,eno ​​​​from​​ ​​staff;​


​v_name varchar2(30);​


​v_eno ​​​​integer​​​​;​


​doc  XMLDOM.DOMDOCUMENT;​


​doc_node XMLDOM.DOMNODE;​


​root_node XMLDOM.DOMNODE;​


​user_node XMLDOM.DOMNODE;​


​item_node XMLDOM.DOMNODE;​


​root_elmt XMLDOM.DOMELEMENT;​


​user_elmt XMLDOM.DOMELEMENT;​


​item_elmt XMLDOM.DOMELEMENT;​


​item_text XMLDOM.DOMTEXT;​


​begin​


​--xml header​


​STAFFINFO :=utl_file.fopen_nchar(​​​​'DIR'​​​​,​​​​'Test.xml'​​​​,​​​​'W'​​​​,32767);​​​​--跟前面说的一样必须先创建一个directory才行​


​UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,​​​​'<staff content = "name and id">'​​​​);​


​UTL_FILE.FFLUSH(STAFFINFO );​​​​--直接写入到磁盘文件中,不会停留在内存中​


​UTL_FILE.FCLOSE(STAFFINFO );​


​open​​ ​​c_table_info;​


​loop​


​fetch​​ ​​c_table_info ​​​​into​​ ​​v_name,v_eno;​


​exit ​​​​when​​ ​​c_table_info%notfound;​


​--XML节点​


​doc := XMLDOM.NEWDOMDOCUMENT;​


​xmldom.setCharset(doc, ​​​​'UTF-8'​​​​);​


​doc_node := XMLDOM.MAKENODE(doc);​


​user_elmt := XMLDOM.CREATEELEMENT(doc,​​​​'member'​​​​);​


​user_node :=XMLDOM.APPENDCHILD(doc_node, XMLDOM.MAKENODE(user_elmt));​


​item_elmt :=XMLDOM.CREATEELEMENT(doc,​​​​'name'​​​​);​


​item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));​


​item_text := XMLDOM.CREATETEXTNODE(doc,v_name);​


​item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));​


​item_elmt :=XMLDOM.CREATEELEMENT(doc,​​​​'eno'​​​​);​


​item_node :=XMLDOM.APPENDCHILD(user_node, XMLDOM.MAKENODE(item_elmt));​


​item_text := XMLDOM.CREATETEXTNODE(doc,​​​​'eno'​​​​);​


​item_node:=XMLDOM.APPENDCHILD(item_node, XMLDOM.MAKENODE(item_text));​


​v_temp :=​​​​' '​​​​;​


​--写入到临时变量v_temp中​


​XMLDOM.WRITETOCLOB(doc,v_temp);​


​STAFFINFO :=utl_file.fopen_nchar(​​​​'DIR'​​​​,​​​​'Test.xml'​​​​,​​​​'A'​​​​,32767);​​​​--以a模式会在文件后添加内容,用w会覆盖之前的内容​


​UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,v_temp);​


​UTL_FILE.FFLUSH(STAFFINFO );​


​UTL_FILE.FCLOSE(STAFFINFO );​


​XMLDOM.FREEDOCUMENT(doc);​


​end​​ ​​loop;​


​close​​ ​​c_table_info;​


​--xml tail​


​STAFFINFO :=utl_file.fopen_nchar(​​​​'DIR'​​​​,​​​​'Test.xml'​​​​,​​​​'a'​​​​,32767);​


​UTL_FILE.PUT_LINE_NCHAR(STAFFINFO ,​​​​'</staff>'​​​​);​


​UTL_FILE.FFLUSH(STAFFINFO );​


​UTL_FILE.FCLOSE(STAFFINFO );​


​end​​​​;​