總結:基於Oracle Logminer數據同步

第 1 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
LogMiner 配置使用手冊
1 Logminer 簡介
1.1 LogMiner介紹
Oracle LogMiner 是 Oracle 公司從產品 8i 之後提供的一個實際很是有用的分析工具,使
用該工具能夠輕鬆得到 Oracle 在線/歸檔日誌文件中的具體內容,特別是該工具能夠分析出所
有對於數據庫操做的 DML 和 DDL 語句。該工具特別適用於調試、審計或者回退某個特定的事
務。
LogMiner分析工具其實是由一組PL/SQL包和一些動態視圖(Oracle8i內置包的一部分)
組成,它做爲 Oracle 數據庫的一部分來發布是 8i 產品提供的一個徹底免費的工具。但該工具和
其餘Oracle 內建工具相比使用起來顯得有些複雜,主要緣由是該工具沒有提供任何的圖形用戶
界面(GUI)。
1.2 LogMiner做用
在 Oracle 8i 以前,Oracle 沒有提供任何協助數據庫管理員來讀取和解釋重做日誌文件內容
的工具。系統出現問題,對於一個普通的數據管理員來說,惟一能夠做的工做就是將全部的log
文件打包,而後發給 Oracle 公司的技術支持,而後靜靜地等待 Oracle 公司技術支持給咱們最
後的答案。然而從8i之後,Oracle 提供了這樣一個強有力的工具--LogMiner。
LogMiner 工具便可以用來分析在線,也能夠用來分析離線日誌文件,便可以分析自己本身
數據庫的重做日誌文件,也能夠用來分析其餘數據庫的重做日誌文件。
總的說來,LogMiner工具的主要用途有:
1. 跟蹤數據庫的變化:能夠離線的跟蹤數據庫的變化,而不會影響在線系統的性能。
2. 回退數據庫的變化:回退特定的變化數據,減小 point-in-time recovery 的執行。
3. 優化和擴容計劃:可經過分析日誌文件中的數據以分析數據增加模式
1.3 使用詳解
1.3.1 安裝LogMiner
在使用 LogMiner 以前須要確認 Oracle 是否帶有進行 LogMiner 分析包,通常來講第 2 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
Windows操做系統 Oracle10g 以上都默認包含。若是不能確認,能夠 DBA身份登陸系統,查
看系統中是否存在運行LogMiner所須要的dbms_logmnr、dbms_logmnr_d包,若是沒有需
要安裝 LogMiner工具,必須首先要運行下面這樣兩個腳本:
一、$ORACLE_HOME/rdbms/admin/dbmslm.sql
二、$ORACLE_HOME/rdbms/admin/dbmslmd.sql.
這兩個腳本必須均以DBA用戶身份運行。其中第一個腳本用來建立DBMS_LOGMNR 包,
該包用來分析日誌文件。第二個腳本用來建立DBMS_LOGMNR_D包,該包用來建立數據字典
文件。
建立完畢後將包括以下過程和視圖:
類型 過程名 用途
過程 Dbms_logmnr_d.build 建立一個數據字典文件
過程 Dbms_logmnr.add_logfile 在類表中增長日誌文件以供分析
過程 Dbms_logmnr.start_logmnr 使用一個可選的字典文件和前面肯定要分析日誌
文件來啓動LogMiner
過程 Dbms_logmnr.end_logmnr 中止LogMiner分析
視圖 V$logmnr_dictionary 顯示用來決定對象ID 名稱的字典文件的信息
視圖 V$logmnr_logs 在LogMiner啓動時顯示分析的日誌列表
視圖 V$logmnr_contents LogMiner啓動後,可使用該視圖在 SQL 提示
符下輸入SQL語句來查詢重作日誌的內容
1.3.2 建立數據字典文件
LogMiner 工具其實是由兩個新的 PL/SQL 內建包((DBMS_LOGMNR 和 DBMS_
LOGMNR_D)和四個 V$動態性能視圖(視圖是在利用過程 DBMS_LOGMNR.START_LOGMNR
啓動 LogMiner 時建立)組成。在使用 LogMiner 工具分析 redo log 文件以前,可使用
DBMS_LOGMNR_D 包將數據字典導出爲一個文本文件。該字典文件是可選的,可是若是沒有
它,LogMiner 解釋出來的語句中關於數據字典中的部分(如表名、列名等)和數值都將是 16
進制的形式,咱們是沒法直接理解的。例如,下面的sql 語句:
INSERT INTO dm_dj_swry (rydm, rymc) VALUES (00005, '張三');
LogMiner解釋出來的結果將是下面這個樣子,
insert into Object#308(col#1, col#2) values (hextoraw('c30rte567e436'),
hextoraw('4a6f686e20446f65'));
建立數據字典的目的就是讓 LogMiner 引用涉及到內部數據字典中的部分時爲他們實際的
名字,而不是系統內部的 16 進制。數據字典文件是一個文本文件,使用包 DBMS_LOGMNR_D第 3 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
來建立。若是咱們要分析的數據庫中的表有變化,影響到庫的數據字典也發生變化,這時就須要
從新建立該字典文件。另一種狀況是在分析另一個數據庫文件的重做日誌時,也必需要從新
生成一遍被分析數據庫的數據字典文件。
建立數據字典文件以前須要配置LogMiner文件夾:
CREATE DIRECTORY utlfile AS 'D:\oracle\oradata\practice\LOGMNR';
alter system set utl_file_dir='D:\oracle\oradata\practice\LOGMNR' scope=spfile;
建立字典文件須要以DBA用戶登陸,建立到上面配置好的LogMiner文件夾中:
CONN LOGMINER/ LOGMINER@PRACTICE AS SYSDBA
EXECUTE dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_
location =>'D:\oracle\oradata\practice\LOGMNR');
1.3.3 加入需分析的日誌文件
Oracle 的 LogMiner 能夠分析在線(online)和歸檔(offline)兩種日誌文件,加入分析
日誌文件使用 dbms_logmnr.add_logfile 過程,第一個文件使用 dbms_logmnr.NEW 參數,
後面文件使用 dbms_logmnr.ADDFILE 參數。
一、建立列表
BEGIN
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\REDO03.LO
G',options=>dbms_logmnr.NEW);
END;
/
二、添加其餘日誌文件到列表
BEGIN
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\ARCHIVE\A
RC00002_0817639922.001',options=>dbms_logmnr.ADDFILE);
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\ARCHIVE\A
RC00003_0817639922.001',options=>dbms_logmnr.ADDFILE);
END;
/
1.3.4 使用LogMiner 進行日誌分析
Oracle 的 LogMiner 分析時分爲無限制條件和限制條件兩種,無限制條件中分析全部加入
到分析列表日誌文件,限制條件根據限制條件分析指定範圍日誌文件。
第 4 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
一、無限制條件
EXECUTE
dbms_logmnr.start_logmnr(dictfilename=>'D:\oracle\oradata\practice\LOGMNR\
dictionary.ora');
二、有限制條件
經過對過程DBMS_ LOGMNR.START_LOGMNR中幾個不一樣參數的設置(參數含義見表1),
能夠縮小要分析日誌文件的範圍。經過設置起始時間和終止時間參數咱們能夠限制只分析某一時
間範圍的日誌。
參數 參數類型 默認值 含義
StartScn 數字型 0 分析重做日誌中SCN≥StartScn 日誌文件部分
EndScn 數字型 0 分析重做日誌中SCN≤EndScn 日誌文件部分
StartTime 日期型 1998-01-01 分析重做日誌中時間戳≥StartTime 的日誌文件
部分
EndTime 日期型 2988-01-01 分析重做日誌中時間戳≤EndTime 的日誌文件部

DictFileName 字符型 字典文件該文件包含一個數據庫目錄的快照。
以下面的例子,咱們僅僅分析 2013 年6 月8日的日誌,:
EXECUTE dbms_logmnr.start_logmnr(
DictFileName => dictfilename=>'D:\..\practice\LOGMNR\dictionary.ora',
StartTime =>to_date('2013-6-8 00:00:00','YYYY-MM-DD HH24:MI:SS')
EndTime =>to_date(''2013-6-8 23:59:59','YYYY-MM-DD HH24:MI:SS '));
也能夠經過設置起始SCN和截至 SCN來限制要分析日誌的範圍:
EXECUTE dbms_logmnr.start_logmnr(
DictFileName =>'D:\..\practice\LOGMNR\dictionary.ora',
StartScn =>20,
EndScn =>50);
1.3.5 觀察分析結果(v$logmnr_contents)
到如今爲止,咱們已經分析獲得了重做日誌文件中的內容。動態性能視圖
v$logmnr_contents包含 LogMiner分析獲得的全部的信息。
SELECT sql_redo FROM v$logmnr_contents;
若是咱們僅僅想知道某個用戶對於某張表的操做,能夠經過下面的 SQL 查詢獲得,該查詢
能夠獲得用戶 LOGMINER對錶EMP所做的一切工做。
SELECT sql_redo FROM v$logmnr_contents WHERE username='LOGMINER' AND 第 5 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
tablename='EMP';
序號 名稱 含義
1 SCN 特定數據變化的系統更改號
2 TIMESTAM 數據改變發生的時間
3 COMMIT_TIMESTAMP 數據改變提交的時間
4 SEG_OWNER 數據發生改變的段名稱
5 SEG_NAME 段的全部者名稱
6 SEG_TYPE 數據發生改變的段類型
7 SEG_TYPE_NAME 數據發生改變的段類型名稱
8 TABLE_SPACE 變化段的表空間
9 ROW_ID 特定數據變化行的ID
10 SESSION_INFO 數據發生變化時用戶進程信息
11 OPERATION 重作記錄中記錄的操做(如 INSERT)
12 SQL_REDO 能夠爲重作記錄重作指定行變化的 SQL 語句(正
向操做)
13 SQL_UNDO 能夠爲重作記錄回退或恢復指定行變化的 SQL
語句(反向操做)
須要強調一點的是,視圖 v$logmnr_contents 中的分析結果僅在咱們運行過程
'dbms_logmrn.start_logmnr'這個會話的生命期中存在。這是由於全部的 LogMiner 存儲都在
PGA內存中,全部其餘的進程是看不到它的,同時隨着進程的結束,分析結果也隨之消失。
最後,使用過程DBMS_LOGMNR.END_LOGMNR終止日誌分析事務,此時 PGA內存區域
被清除,分析結果也隨之再也不存在。
2 數據同步 Oracle 數據庫設置
Oracle 數據使用 LogMiner查看執行 SQL語句,其中須要進行以下四步驟是指:
1. 設置數據庫爲歸檔模式;
2. 設置 LogMiner字典文件路徑等;
3. 建立數據同步用戶(如用戶名爲 LOGMINER,該用戶擁有DBA權限);
4. 驗證配置是否成功; 第 6 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
2.1 設置數據庫爲歸檔模式
2.1.1 查看數據庫是否爲歸檔模式
使用 SqlPlus或者命令行界面鏈接數據庫(如下以命令行界面操做)
--進入SqlPlus程序
sqlplus /nolog
--使用DBA用戶登陸到源數據庫中
conn system/system@practic as sysdba

--查看PRACTICE數據庫是否處於歸檔模式
SELECT dbid, name, log_mode FROM v$database;
或者 ARCHIVE LOG LIST;

若是顯示數據庫顯示爲歸檔模式,則設置數據庫爲歸檔模式可跳過;若是顯示數據庫爲非歸檔模
式則須要進行如下設置。
上圖顯示數據庫未進行歸檔,須要進行歸檔設置。 第 7 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
2.1.2 設置歸檔模式
建立 ARCHIVE 文件夾,ARCHIVE 文件夾路徑根據所在服務器進行設置,在下面操做中設置爲"
D:\oracle\oradata\practice\ARCHIVE"

--設置歸檔日誌文件路徑
ALTER SYSTEM SET log_archive_dest="D:\oracle\oradata\practice\ARCHIVE";
--日誌文件名稱格式:
ALTER SYSTEM SET log_archive_format="ARC%S_%R.%T" SCOPE=SPFILE;

--修改完畢後,關閉數據庫,以 MOUNT方式啓動
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
--設置數據庫爲歸檔模式
ALTER DATABASE ARCHIVELOG; 第 8 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

(注意:若是重啓數據失敗,請參考第4 章節異常問題處理)
2.1.3 驗證歸檔是否設置成功
--查看PRACTICE數據庫是否處於歸檔模式
SELECT dbid, name, log_mode FROM v$database;
或者 ARCHIVE LOG LIST;

--驗證參數設置是否起做用
SELECT dest_id, status, destination FROM v$archive_dest WHERE dest_id =1;

--在參數文件設置已經起做用,打開數據庫 第 9 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
ALTER DATABASE OPEN;

2.2 LogMiner設置
2.2.1 建立LogMiner 文件夾
建立 LOGMNR文件夾,路徑爲"D:\oracle\oradata\practice\LOGMNR"

2.2.2 設置LogMiner 字典文件路徑
--建立數據字典文件
CREATE DIRECTORY utlfile AS 'D:\oracle\oradata\practice\LOGMNR';
alter system set utl_file_dir='D:\oracle\oradata\practice\LOGMNR' scope=spfile; 第 10 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

2.2.3 開啓LogMiner 日誌補充模式
--建立數據字典文件
alter database add supplemental log data;

2.2.4 重啓數據庫驗證
--修改完畢後,關閉數據庫,以 MOUNT方式啓動
SHUTDOWN IMMEDIATE;
STARTUP;
--查看Logminer文件夾是否設置
SHOW PARAMETER utl_file_dir; 第 11 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

2.3 建立數據同步用戶
在數據庫建立LOGMINER用戶,該用戶須要具備DBA權限
--在源數據庫建立 LOGMINER用戶,並賦予 DBA權限
CREATE USER LOGMINER IDENTIFIED BY LOGMINER;
GRANT CONNECT, RESOURCE,DBA TO LOGMINER;

3 使用 LogMiner 讀取日誌例子
在使用 LogMiner 讀取歸檔/在線日誌須要按照第 2 章節進行設置,設置完畢後能夠對歸檔
和在線日誌進行分析。特別是須要開啓 LogMiner 日誌補充模式,若是沒有開始 LogMiner 補
充模式將沒法查看 DDL語句,按照測試結果看,只有開始 LogMiner日誌補充模式後,才能查
看 DDL語句,在此以前進行DDL將沒法進行查看。 第 12 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
3.1 使用LogMiner 讀取在線日誌
3.1.1 測試數據準備
--以LOGMINER用戶登陸(非DBA登陸)建立 AAAAA表(Oracle11g請注意用戶名、密碼大
小寫)
CONNECT LOGMINER/LOGMINER@PRACTICE
CREATE TABLE AAAAA(field001 varchar2(100));
INSERT INTO AAAAA (field001) values ('000000');
INSERT INTO AAAAA (field001) values ('0000010');
commit;

3.1.2 建立數據字典文件
數據庫對象發生變化,須要從新建立數據字典文件
--以LOGMINER用戶(DBA權限)登陸,生成字典文件
CONN LOGMINER/LOGMINER@PRACTICE AS SYSDBA
EXECUTE dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_loca
tion =>'D:\oracle\oradata\practice\LOGMNR');

3.1.3 確認當前處於聯機狀態的日誌文件
--須要確認當前處於聯機狀態的日誌文件
SELECT group#, sequence#, status, first_change#, first_time FROM V$log ORDER BY first_change#; 第 13 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

從上圖能夠看出在線日誌REDO03 處於ACTIVE狀態中
3.1.4 加入需分析的日誌文件
--加入解析在線日誌文件
BEGIN
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\REDO03.LOG',opti
ons=>dbms_logmnr.NEW);
END;
/

3.1.5 使用LogMiner 進行分析
--啓動LogMiner進行分析
EXECUTE
dbms_logmnr.start_logmnr(dictfilename=>'D:\oracle\oradata\practice\LOGMNR\dictio
nary.ora');
第 14 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
3.1.6 觀察分析結果
--查詢相關操做日誌
SELECT sql_redo, sql_undo, seg_owner
FROM v$logmnr_contents
WHERE seg_name='AAAAA'
AND seg_owner='LOGMINER';

3.2 使用LogMiner 讀取歸檔日誌
3.2.1 測試數據準備
--以 LOGMINER 用戶登陸(非 DBA 權限)建立 EMP 表(Oracle11g 請注意用戶名、密碼大小
寫)
CONN LOGMINER/ LOGMINER@PRACTICE
CREATE TABLE EMP
(EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY, 第 15 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2));

--插入EMP數據
INSERT INTO EMP VALUES
(7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20);
INSERT INTO EMP VALUES
(7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30);
INSERT INTO EMP VALUES
(7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30);
INSERT INTO EMP VALUES
(7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20);
COMMIT;

--從v$log視圖中找出日誌文件的序號
CONNECT system/system@practice as sysdba
ALTER SYSTEM SWITCH LOGFILE;
select sequence#, FIRST_CHANGE#, NEXT_CHANGE#,name from v$archived_log order
by sequence# desc; 第 16 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

3.2.2 建立數據字典文件
確保按照 2.2 進行 logMiner設置
--以LOGMINER用戶(DBA權限)登陸,生成字典文件
CONN LOGMINER/ LOGMINER@PRACTICE AS SYSDBA
EXECUTE dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_loca
tion =>'D:\oracle\oradata\practice\LOGMNR');

3.2.3 加入需分析的日誌文件
--加入解析日誌文件
BEGIN
dbms_logmnr.add_logfile(logfilename=>'D:\oracle\oradata\practice\ARCHIVE\ARC000
02_0817639922.001',options=>dbms_logmnr.NEW);
END;
/ 第 17 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

3.2.4 使用LogMiner 進行分析
--啓動LogMiner進行分析
EXECUTE
dbms_logmnr.start_logmnr(dictfilename=>'D:\oracle\oradata\practice\LOGMNR\dictio
nary.ora');

3.2.5 觀察分析結果
--查詢相關操做日誌
SELECT sql_redo, sql_undo
FROM v$logmnr_contents
WHERE seg_name='EMP'
AND seg_owner='LOGMINER'; 第 18 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan


4 其餘
4.1 異常問題處理
4.1.1 出現ORA-12514錯誤
若是出現 ORA-12514 錯誤時,以下圖所示: 第 19 頁 共 20 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

須要修改 listerner.ora 文件,具體在 Oracle 安裝目錄\NETWORK\ADMIN 下,當前操做爲"
D:\oracle\product\10.2.0\db_1\NETWORK\ADMIN\listener.ora "加入以下設置
(SID_DESC =
(GLOBAL_DBNAME = practice)
(ORACLE_HOME = D:\oracle\product\10.2.0\db_1)
(SID_NAME = practice)
)
設置後須要從新啓動TNSListener,便可生效
4.1.2 出現ORA-16018錯誤
若是出現 ORA-16018 錯誤時,以下圖所示:

該問題是數據庫開啓了閃回功能,歸檔文件默認狀況下是保存到閃迴路徑中,簡單的處理方式是
在設置歸檔路徑中加入scope=spfile 參數
--設置歸檔日誌文件路徑
ALTER SYSTEM SET log_archive_dest="D:\oracle\oradata\practice\ARCHIVE"
scope=spfile;
此時查看閃迴路徑,該路徑並未影響,只不過閃迴文件和歸檔文件保存到各自文件夾中
java

第 1 頁 共 7 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
Oracle Logminer 性能測試
1 測試介紹
1.1 測試目的
經過模擬不一樣環境下 LogMiner 解析聯機/歸檔日誌文件運行狀況,經過測試所獲取
的數據分析,經過對如下兩點的驗證來肯定經過 LogMiner技術技術可行性:
一、在日誌文件不一樣大小、不一樣數據壓力狀況下對數據庫服務器內存、CPU 的影響;
二、並經過查詢 LogMiner 的動態表和實際物理表中數據數目是否一致,驗證其準確
性。
1.2 測試環境
用途及說明 硬件配置 軟件配置 其它說明
數據庫服務器
型號:T420i
處理器:Intel(R)core(TM) i5
CPU M430
主頻:2.2G
內存:2G
硬盤:300G
操做系統:WindowXP
數據庫及版本:Oracle10.2g
IP地址:10.88.54.83

測試機
型號:T420i
處理器:Intel(R)core(TM) i5
CPU M430
主頻:2.2GHz
內存:1.8 GB
顯示器:1280*800 寬屏
操做系統:windows xp
瀏覽器及版本:ie8
1.3 測試方案
1.3.1 性能影響(針對目標一)
爲了模擬實際運行環境,加入了 Logminer運行背景環境,分別測試數據庫在無操做、
300 個插入/秒操做、500 個插入/秒操做狀況下運行狀況,而且對比日誌文件50M、100M第 2 頁 共 7 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
大小下運行狀況

聯機日誌大小 讀取文件個數 運行做業數目 插入數據量
方案一 50M
1 個 0 個 0 筆/秒
3 個 0 個 0 筆/秒
5 個 0 個 0 筆/秒
10 個 0 個 0 筆/秒
方案二 50M
1 個 500 個 估計300 筆/秒
3 個 500 個 估計300 筆/秒
5 個 500 個 估計300 筆/秒
10 個 500 個 估計 300 筆/秒
方案三 50M(未運行
CPU80%,680M)
1 個 1000 個 估計 500 筆/秒
3 個 1000 個 估計500 筆/秒
5 個 1000 個 估計500 筆/秒
10 個 1000 個 估計 500 筆/秒
方案四 100M(未運行
CPU25%,464M)
1 個 500 個 估計300 筆/秒
3 個 500 個 估計300 筆/秒
5 個 500 個 估計300 筆/秒
10 個 500 個 估計 300 筆/秒
1.3.2 準確性(針對目標二)
一、數據類型
序號 數據類型 是否支持 問題處理
1 BINARY_DOUBLE 8.1 及以上
2 BINARY_FLOAT 8.1 及以上
3 CHAR 8.1 及以上
4 DATE 8.1 及以上
需設置時間格式,不然只能同步日期
alter system set
nls_date_format='yyyy-MM-dd
HH24:mi:ss' scope=spfile;
5 INTERVAL DAY 8.1 及以上
6 INTERVAL YEAR 8.1 及以上
7 NUMBER 8.1 及以上
8 NVARCHAR2 8.1 及以上
9 RAW 8.1 及以上
10 TIMESTAMP 8.1 及以上
11 TIMESTAMP 8.1 及以上 第 3 頁 共 7 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
WITH LOCAL
TIME ZONE
12 VARCHAR2 8.1 及以上
13 LONG 9.2 及以上
14 CLOB 10.1 及以上 須要設置以下:
ALTER DATABASE ADD SUPPLEMENTAL
LOG DATA (ALL) COLUMNS;
插入時分爲兩條語句,另外插入二進制數據
未進行測試
15 BLOB 10.0 及以上

二、DDL語句測試(未測試完畢)
序號 類型 是否支持
1 建立表(Create table) 支持
2 刪除表(Drop table)
支持,出現兩個語句,首先修改表
名爲臨時表名,而後刪除該臨時表
監控該類型須要進行合併處理
3 建立做業(Create job) 不支持
4 建立序列(Create sequence) 支持
5 建立存儲過程(Create pocedure) 支持
6 增長字段(alter table TABLE add column) 支持
7 刪除字段(alter table emp drop column) 支持
8 修改字段(alter table emp modify column) 支持
9 修改列名(alter table rename column) 支持
10 修改表名(rename emp to TABLE) 支持
11 清除表數據(truncate table TABLE) 支持
12 刪除表(drop table TABLE) 支持
13 恢復被刪除的表(Flashback table TABLE to before
drop) 支持
14 NOT NULL約束(alter table TABLE modify
COLUMN not null) 支持
15 UNIQUE 約束 支持
16 PRIMARY KEY 約束 支持
17 FOREIGN KEY 約束 支持
18 CKECK 約束 支持
19 禁用/激活約束 支持
20 刪除約束 支持
21 建立不惟一索引 支持 第 4 頁 共 7 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
22 建立惟一索引 支持
23 建立位圖索引 支持
24 建立反序索引 支持
25 建立函數索引 支持
26 修改索引 支持
27 合併索引 支持
28 重建索引 支持
29 刪除索引 支持
30 建立視圖(CREATE VIEW) 支持
31 修改視圖(CREATE OR REPLACE VIEW) 支持
32 刪除視圖(DROP VIEW) 支持
33 建立序列(CREATE SEQUENCE) 支持
34 修改序列(ALTER SEQUENCE) 支持
35 刪除序列(DROP SEQUENCE) 支持

三、其餘問題測試
序號 問題 現象及處理方式
1 主子表插入數據測試 可以正常插入及同步
2 事務提交(commit、rollback)
可以看到提交和未提交的內容,考慮在產品設計
中加入
DBMS_LOGMNR.COMMITTED_DATA_ON
LY
參數,該參數只讀取已經提交事務
3 批量更新時,影響多條數據,在聯機日誌
中每一條更新數據對應生成一條語句 不影響,可同步獲取再執行
4 更新和刪除語句中帶rowid
加入去除rowid 參數
dbms_logmnr.NO_ROWID_IN_STMT
5
2 測試結論
2.1 測試初步結論
1. 從性能影響測試中能夠看出: 第 5 頁 共 7 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
a) logminer加載分析過程隨機器根據負載不一樣在 6~21 秒完成;
b) 加載分析過程並不隨日誌文件個數增長在時間、CPU、內存有較大變化;
c) 加載分析過程當中受分析日誌文件個數最大是內存,其次是 CPU,耗時應影響較小;
2. 從準確性測試來看
a) 經過設置基本上可以獲取 DML語句(其中 LOB 字段還須要進行測試);
b) 從現有狀況來看,DDL支持並不充分,須要進一步測試;
第 6 頁 共 7 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

聯機日誌大小
讀取
文件
個數
運行做
業數目 插入數據量
生成字典
文件 加載處理 分析處理 log_content
s
數據量


(M)


(秒)
耗時
(秒)
CPU(%
)
內存
(M)
耗時
(秒)
CPU(%
)
內存
(M)
方案
一 50M
1 個 0 個 0 筆/秒
47.
5
12.
7
1 1 309 5.5 25 438 600
3 個 0 個 0 筆/秒 1 1 309 5.7 25 444 222,236
5 個 0 個 0 筆/秒 1 1 326 5.6 25 445 492,606
10個 0 個 0 筆/秒 1 1 326 5.6 25 445 1,149,284
方案
二 50M
1 個 500 個 估計300 筆/秒
47.
5 20
1 26 391 6.7 35 530 111,328
3 個 500 個 估計300 筆/秒 1 21 473 6.4 37 619 372,389
5 個 500 個 估計300 筆/秒 1 25 534 6.8 44 692 622,390
10個 500 個 估計300 筆/秒 1 30 624 6.7 39 780 1,254,748
方案

50M(未運行
CPU80%,680M)
1 個 1000個 估計500 筆/秒
47.
5
54.
7
3.5 71 688 15 80 806 35,892
3 個 1000個 估計500 筆/秒 1.5 41 688 14.4 78 777 384,743
5 個 1000個 估計500 筆/秒 1 68 687 75 805 652,148
10個 1000個 估計500 筆/秒 10 80 689 13.2 79 806 1,295,158
方案

50M(未運行
CPU80%,667M)
1 個 2000個 估計1000筆/秒
47.
5
73.
7
5.5 84 691 14.6 78 808 133,844
3 個 2000個 估計1000筆/秒 11.4 70 691 12 75 809 390,029
5 個 2000個 估計1000筆/秒 5.5 76 690 13.6 76 806 668,013
10個 2000個 估計1000筆/秒 6.1 40 690 15.4 88 809 1,335,587
方案 100M(未運行 1 個 500 個 估計300 筆/秒 23. 8.7 0.8 26 484 4.1 30 573 268,715 第 7 頁 共 7 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
五 CPU25%,464M) 3 個 500 個 估計300 筆/秒 8 0.9 25 534 3.2 36 622 768,989
5 個 500 個 估計300 筆/秒 0.9 27 581 3.2 35 662 1,324,447
10個 500 個 估計300 筆/秒 1.1 29 690 5.2 35 763 2,619,322 sql

第 1 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
使用 Oracle Logminer 同步 Demo
1 Demo介紹
1.1 Demo設想
前面介紹了 Oracle LogMiner 配置使用以及使用 LogMiner 進行解析日誌文件性能,在這
篇文章中將利用LogMiner進行數據同步,實現從源目標數據庫到目標數據庫之間的數據同步。
因爲LogMiner支持的版本是8.1及以上,因此進行數據同步的Oracle數據庫版本也必須是8.1
及以上。
固然在本文中介紹的是LogMiner進行數據同步例子,也能夠利用LogMiner進行數據審計、
數據操做追蹤等功能,因爲這些從操做原理來講是一致,在本文不作討論。
1.2 框架圖
第 2 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
1.3 流程圖

 配置階段
一、 控制端:指定源端、目標端數據庫信息、LOGMINER同步時間等配置信息;
 獲取源端同步數據
二、 控制檯:經過定時輪詢的方式檢測是否到達數據同步時間,若是是則進行數據同步,否
則繼續進行輪詢;
三、 源數據庫:定時加載數據庫歸檔日誌文件到動態表v$logmnr_contents中;
四、 源數據庫:根據條件讀取指定sql 語句;
 目標端數據入庫
五、 源數據庫:執行sql 語句。
2 代碼分析
2.1 目錄及環境配置
在該 Demo 項目中須要引入 Oracle JDBC 驅動包,具體項目分爲四個類: 第 3 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
1. Start.java:程序入口方法;
2. SyncTask.java:數據同步 Demo 核心,生成字典文件和讀取日誌文件、目標數據庫執
行SQL語句等;
3. DataBase.java:數據庫操做基礎類;
4. Constants.java:源數據庫、目標數據庫配置、字典文件和歸檔文件路徑。

2.2 代碼分析
2.2.1 Constants.java
在該類中設置了數據同步開始 SCN號、源數據庫配置、目標數據庫配置以及字典文件/日誌
文件路徑。須要注意的是在源數據庫配置中有兩個用戶:一個是調用 LogMiner 用戶,該用戶
須要擁有 dbms_logmnr、dbms_logmnr_d兩個過程權限,在該 Demo 中該用爲爲sync;另
外一個爲 LogMiner讀取該用戶操做 SQL語句,在該Demo 中該用爲爲 LOGMINER。
package com.constants;

/**
* [Constants]|描述:Logminer配置參數
* @做者: ***
* @日期: 2013-1-15 下午01:53:57
* @修改歷史:
*/
public class Constants {

/** 上次數據同步最後SCN號 */
public static String LAST_SCN = "0"; 第 4 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

/** 源數據庫配置 */
public static String DATABASE_DRIVER="oracle.jdbc.driver.OracleDriver";
public static String
SOURCE_DATABASE_URL="jdbc:oracle:thin:@127.0.0.1:1521:practice";
public static String SOURCE_DATABASE_USERNAME="sync";
public static String SOURCE_DATABASE_PASSWORD="sync";
public static String SOURCE_CLIENT_USERNAME = "LOGMINER";

/** 目標數據庫配置 */
public static String SOURCE_TARGET_URL="jdbc:oracle:thin:@127.0.0.1:1521:target";
public static String SOURCE_TARGET_USERNAME="target";
public static String SOURCE_TARGET_PASSWORD="target";

/** 日誌文件路徑 */
public static String LOG_PATH = "D:\\oracle\\oradata\\practice";

/** 數據字典路徑 */
public static String DATA_DICTIONARY = "D:\\oracle\\oradata\\practice\\LOGMNR";
}
2.2.2 SyncTask.java
在該類中有兩個方法,第一個方法爲 createDictionary,做用爲生成數據字典文件,另一
個是startLogmur,該方法是 LogMiner分析同步方法。

/**
* <p>方法名稱: createDictionary|描述: 調用logminer
/**
* <p>方法名稱: startLogmur|描述:啓動
生成數據字典文件</p>
* @param sourceConn 源數據庫鏈接
* @throws Exception 異常信息
*/
public void createDictionary(Connection sourceConn) throws Exception{
String createDictSql = "BEGIN dbms_logmnr_d.build(dictionary_filename =>
'dictionary.ora', dictionary_location =>'"+Constants.DATA_DICTIONARY+"'); END;";
CallableStatement callableStatement = sourceConn.prepareCall(createDictSql);
callableStatement.execute();
}


logminer分析 </p>
* @throws Exception
*/
public void startLogmur() throws Exception{
第 5 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
Connection sourceConn = null;
Connection targetConn = null;
try {
ResultSet resultSet = null;

// 獲取源數據庫鏈接
sourceConn = DataBase.getSourceDataBase();
Statement statement = sourceConn.createStatement();

// 添加全部日誌文件,本代碼僅分析聯機日誌
StringBuffer sbSQL = new StringBuffer();
sbSQL.append(" BEGIN");
sbSQL.append("
dbms_logmnr.add_logfile(logfilename=>'"+Constants.LOG_PATH+"\\REDO01.LOG',
options=>dbms_logmnr.NEW);");
sbSQL.append("
dbms_logmnr.add_logfile(logfilename=>'"+Constants.LOG_PATH+"\\REDO02.LOG',
options=>dbms_logmnr.ADDFILE);");
sbSQL.append("
dbms_logmnr.add_logfile(logfilename=>'"+Constants.LOG_PATH+"\\REDO03.LOG',
options=>dbms_logmnr.ADDFILE);");
sbSQL.append(" END;");
CallableStatement callableStatement = sourceConn.prepareCall(sbSQL+"");
callableStatement.execute();

// 打印獲分析日誌文件信息
resultSet = statement.executeQuery("SELECT db_name, thread_sqn, filename FROM
v$logmnr_logs");
while(resultSet.next()){
System.out.println("已添加日誌文件==>"+resultSet.getObject(3));
}

System.out.println("開始分析日誌文件,起始scn號:"+Constants.LAST_SCN);
callableStatement = sourceConn.prepareCall("BEGIN
dbms_logmnr.start_logmnr(startScn=>'"+Constants.LAST_SCN+"',dictfilename=>'"+Consta
nts.DATA_DICTIONARY+"\\dictionary.ora',OPTIONS
=>DBMS_LOGMNR.COMMITTED_DATA_ONLY+dbms_logmnr.NO_ROWID_IN_STMT);END;");
callableStatement.execute();
System.out.println("完成分析日誌文件");

// 查詢獲取分析結果
System.out.println("查詢分析結果");
resultSet = statement.executeQuery("SELECT
scn,operation,timestamp,status,sql_redo FROM v$logmnr_contents WHERE
seg_owner='"+Constants.SOURCE_CLIENT_USERNAME+"' AND seg_type_name='TABLE' AND
operation !='SELECT_FOR_UPDATE'");
第 6 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
// 鏈接到目標數據庫,在目標數據庫執行redo語句
targetConn = DataBase.getTargetDataBase();
Statement targetStatement = targetConn.createStatement();

String lastScn = Constants.LAST_SCN;
String operation = null;
String sql = null;
boolean isCreateDictionary = false;
while(resultSet.next()){
lastScn = resultSet.getObject(1)+"";
if( lastScn.equals(Constants.LAST_SCN) ){
continue;
}

operation = resultSet.getObject(2)+"";
if( "DDL".equalsIgnoreCase(operation) ){
isCreateDictionary = true;
}

sql = resultSet.getObject(5)+"";

// 替換用戶
sql = sql.replace("\""+Constants.SOURCE_CLIENT_USERNAME+"\".", "");
System.out.println("scn="+lastScn+",自動執行sql=="+sql+"");

try {
targetStatement.executeUpdate(sql.substring(0, sql.length()-1));
} catch (Exception e) {
System.out.println("測試一下,已經執行過了");
}
}

// 更新scn
Constants.LAST_SCN = (Integer.parseInt(lastScn))+"";

// DDL發生變化,更新數據字典
if( isCreateDictionary ){
System.out.println("DDL發生變化,更新數據字典");
createDictionary(sourceConn);
System.out.println("完成更新數據字典");
isCreateDictionary = false;
}

System.out.println("完成一個工做單元");

}
finally{ 第 7 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan
if( null != sourceConn ){
sourceConn.close();
}
if( null != targetConn ){
targetConn.close();
}

sourceConn = null;
targetConn = null;
}
}
3 運行結果
3.1 源數據庫操做
一、建立 AAAAA表,並插入數據

二、建立EMP1 表 第 8 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan

3.2 運行 Demo
在控制檯中輸出以下日誌

3.3 目標數據庫結果
建立 AAAAA和EMP1 表,並在AAAAA插入了數據 第 9 頁 共 9 頁 出自石山園主,博客地址:http://www.cnblogs.com/shishanyuan


轉:http://files.cnblogs.com/files/shishanyuan/3.%E4%BD%BF%E7%94%A8OracleLogminer%E5%90%8C%E6%AD%A5Demo.pdf 數據庫

相關文章
相關標籤/搜索