◆張 媛 湯學達 桂文軍
(中國電子科技集團公司第二十八研究所 江蘇 210007)
隨著指揮信息系統的不斷發展和建設,當前各級指揮信息系統呈現物理位置分散、自成體系、數據不統一的特點,為構建邏輯上集中統一的指揮信息系統數據服務平臺,滿足各類業務應用數據訪問需求,首先必須解決各級指揮信息系統之間的數據同步共享問題。本文結合現有指揮信息系統采用符合特定軍用傳輸協議的手段進行信息交換的特點,在深入研究Oracle目前商用同步技術的基礎上,提出了一種基于Oracle Logminer的數據同步方法,為在不同指揮信息系統之間保持共享數據一致性,確保不同信息系統在統一的共享數據視圖下工作提供了一種有效的解決途徑。
在 ORACLE數據庫中,觸發器(Trigger)是存儲在數據庫中的過程。當特定的某個事件(如對表或者視圖進行插入、刪除或者修改)發生后,這個過程就會被觸發執行。基于觸發器的數據同步技術的原理是在每一個同步對象表上創建增加、刪除、修改三種類型的觸發器,通過觸發器捕獲到同步對象表中的數據變更[1]。
物化視圖(Materialized View)又稱快照(Snapshot),是對現有數據表或者視圖查詢后的結果,物化視圖既保存了查詢語句,又保存了查詢后的結果集[2]。物化視圖的快速刷新是通過物化視圖日志實現的,物化視圖日志記錄了對應的數據表的增加、刪除、修改等數據操作,定期刷新物化視圖,捕獲物化視圖日志的變化可以實現數據同步。
DataGuard是Oracle推出的一種可用性高的數據庫方案,它是在主節點和備用節點間通過日志同步來保證數據庫一對一的整體復制[3]。DataGuard提供了三種數據保護模式:最大性能模式、最大保護模式和最大可用模式。最大性能模式可以實現在不影響源數據庫性能的基礎上最大限度提高數據保護等級;最大保護模式可以確保數據不丟失,但會影響數據庫的可用性;最大可用模式在不影響源數據庫使用性能的條件下盡可能提高數據保護等級。
Streams是Oracle為提高數據庫的高可用性和數據的分發共享功能而設計的,在 Oracle 9i之前這個功能被稱為 Advance Replication(高級復制)[4]。Streams采用高級隊列技術將歸檔日志解析成DDL及DML語句,實現數據庫之間的同步[5]。Streams具有較好的靈活性,在復制數據的同時,不影響數據庫其他操作的運行,支持一對多、雙向復制等多種復制方式,但Streams技術存在一定的數據局限性,并不能完全支持所有的數據類型和對象,而且Streams數據同步技術維護起來有一定的難度。
在Oracle數據庫中,所有對數據庫進行的更改操作都被記錄到重做日志文件和歸檔日志文件中,日志文件可用于數據庫的恢復。但Oracle 8i以前這些日志文件內容不能直接閱讀,使用一般的閱讀工具查看到的都是亂碼,Oracle 8i中首次提供了一個內置的分析工具——Logminer(日志挖掘),使用Logminer工具,DBA可以對數據庫的日志進行分析[6]。Logminer具有以下優點:(1)實現事務級、細粒度的數據庫恢復,通過執行相應的 UNDO操作取消用戶執行的錯誤操作;(2)實現事后審計,利用Logminer的分析結果,可以追蹤在數據庫上執行的所有DML和DDL操作,取得這些操作的執行者、執行時間等重要信息;(3)優化和擴容,利用分析結果獲取數據的增長模式實現優化和擴容[7]。
(1)源數據庫
源數據庫(Source Database)為要被分析的數據庫,Logminer工具要添加的日志文件來源于此數據庫。
分析數據庫
分析數據庫(Mining Database)是用來執行Logminer的數據庫,實際操作中要求它與源數據庫處于相同的硬件平臺,具有相同的字符集且版本不能低于源數據庫,源數據庫和分析數據庫可以是同一個數據庫。
(3)Logminer字典
Logminer字典是Oracle提供的一個將內部的數據庫對象ID和數據類型、二進制字段值翻譯為一般用戶能正常理解使用的數據庫對象名、數據類型及字段值的工具。
Logminer分析工具包是由一組PL/SQL包和一些動態視圖組成。其中用于建立程序包的2個PL/SQL文件分別為dbmslm.sql和 dbmslmd.sql,與分析相關的 4個動態視圖是v$logmnr_dictionary、v$logmnr_parameters、v$logmnr_logs 和v$logmnr_contents。v$logmnr_dictionary提供了Logminer可使用的數據字典信息,v$logmnr_parameter保存了當前Logminer所設定的限制參數信息,查看v$logmnr_logs可以獲取當前用于分析的日志列表,v$logmnr_contents記錄的是日志分析結果的原子操作[8]。
在圖1中,源數據庫中有數據表A,目的數據庫中有數據表B,表A和表B的結構相同,當數據表A中的數據發生變化時,數據表B也同步變化,保證B表和A表中的數據始終保持一致,基于Logminer數據同步的基本原理描述如下:
(1)在源數據庫中,用戶或者應用程序對數據表A進行了增加、刪除或者修改操作,表A的數據發生變化;
(2)數據表 A的變化記錄到 Oracle重做日志中,通過Logminer工具解析該時間段內的重做日志并將分析結果存入本地的事務隊列中;
(3)采用符合特定軍用傳輸協議的手段將本地的事務隊列傳送到遠端;
(4)遠端目的數據庫定時將事務隊列入庫,對數據表B進行同步更新。
由于Oracle重做日志記錄了在數據庫中執行的任何操作,日志量大且內容豐富,為提高日志解析效率,采用定時捕獲日志變化的方式,基于Oracle內部的時鐘機制,解析Oracle日志,獲取變更增量,同步應用于目的數據庫中。

圖1 基于Logminer的數據同步原理示意圖
(1)核心數據結構
在數據同步的過程中涉及的主要數據結構包括同步節點結構、節點信息結構、資源同步策略結構等。
1)同步節點結構
定義同步節點結構 SynNode(int rSynPolicyID,int rLocalNodeID,int rDestNodeID,int rRank),其中rSynPolicyID為同步策略標識,用來關聯資源同步策略;rLocalNodeID為本地節點標識,唯一標識業務訪問所在節點的編碼;rDestNodeID為目的節點標識,唯一標識待同步的目的節點編碼;rRank為同步優先級。
定義節點信息結構NodeInfo(int rNodeId;char rHostname[];char rIP[];char rDbType[];char rDbSid[])保存各同步節點的信息,其中rNodeId表示節點標識,rHostname表示主機名,rIP表示主機IP,rDbType表示數據庫類型,rDbSid表示數據庫實例。
3)資源同步策略結構
定義資源同步策略結構SynDefMain(int rSynPolicyID, char rPolicyName [],int rNodetype, int rIsSyn, int rChangeOpr, int rSysMode, int rInitSyn),其中rSynPolicyID為同步策略標識,唯一標識資源的同步策略;rPolicyName表示同步策略名稱;rNodetype表示業務訪問所屬節點類型;rIsSyn為同步標志,有不同步和同步兩種;rChangeOpr為變更操作類型,0代表全部,1代表增加,2代表刪除,3代表修改,4代表提交,5代表回滾;rSysMode為同步方式,包括同步或異步;rInitSyn為初始同步標志,初始數據需要同步或者不同步。
(2)功能模塊與劃分
基于 Logminer的數據同步的主要功能模塊包括日志變更捕獲模塊、網絡傳輸模塊和事務隊列同步模塊三大模塊。
①日志變更捕獲模塊
日志變更捕獲模塊的功能是按周期定時掃描 Oracle重做日志文件的內容,捕獲用戶關心的數據庫表的變更,并將捕獲結果存入待同步的事務隊列中。變更捕獲的周期以及需要同步的數據庫表可作為同步策略進行配置。
在此之前,需進行相關配置。首先以SYS用戶運行以下兩個腳本:
胎架制作→H型鋼梁的定位拼裝→校正→檢驗→對接焊縫焊接→焊后校正→方鋼管上弦桿和腹桿的拼裝→焊縫焊接→焊后校正→監理工程師檢查驗收→涂裝→檢驗合格。
SQL>@$ORACLE_HOME dbmsadmindbmslm.sql;
SQL>@$ORACLE_HOME dbmsadmindbmslmd.sql;
第一個腳本用來創建DBMS_LOGMNR包,用于分析日志文件,第二個腳本用來創建 DBMS_LOGMNR_D包,用于創建數據字典。與此同時開啟補充日志的功能,增加重做日志記錄中變更矢量記載的記錄量,支持 Logminer工具包對更新操作(UPDATE)的分析:
SQL>alter database add supplemental log data;
配置完成后,具體的設計實現步驟如下:
第一步:獲取源數據庫中當前重做日志文件的路徑,將其添加到本次日志分析過程中:
SQL>exec
dbms_logmnr.add_logfile(‘filename’,dbms_logmnr.new|dbms_l
ogmnr.addfile);
第二步:查詢系統最新的scn號作為本次日志分析過程的結束scn號,將上次掃描的結束scn號加1作為本次日志分析過程的起始scn號,開啟日志分析過程:
Startscn:=lastEndscn+1;
Endscn:=currentScn;
SQL>exec dbms_logmnr.start_logmnr(startscn,endscn,option);
其中option有以下幾個選項:NO_SQL_DELIMITER:重建的SQL語句內不使用分號,COMMITTED_DATA_ONLY:只有被提交的事務才被顯示在 V$LOGMNR_CONTENTS視圖內,NO_ROWID_IN_STMT:在SQL_REDO和SQL_UNDO列內不列出ROWID子句等。
第三步:分析重做日志,從動態性能視圖v$logmnr_contents中過濾出用戶關心的操作記錄,處理這些操作記錄,使其變成適合入庫的標準sql語句,并將這些標準sql語句存入事務隊列中:
SQL>select sql_redo from v$logmnr_contents where seg_owner= ‘schema’ and seg_name=‘table_name’ and operation in‘INSERT’,‘UPDATE’,‘DELETE’);
第四步:結束本次分析過程,等待下一次周期,繼續循環日志分析過程。
SQL>exec dbms_logmnr.end_logmnr();
其中第二步提到的scn(系統改變號,system change number)是數據庫中一個非常重要的數據結構,它定義了數據庫在某個確切時刻提交的版本,每當事務提交時,都會被賦予一個惟一標識事務的scn,scn提供Oracle內部時鐘機制,可看作數據庫的邏輯時鐘。每次循環都是以上一次分析結束的scn號加1作為本次分析開始的scn號,這樣可以保證scn區間的連續性,確保分析過程中用戶的操作不丟失,不遺漏。
圖2為采用Logminer進行日志變更捕獲的流程。如果重做日志文件設置的比較小,而用戶的某個事務操作規模比較大,數據庫又沒有開啟歸檔模式,此時可能會出現重做日志被覆蓋,部分日志丟失的情況。為了避免這種情況發生,可以考慮開啟數據庫歸檔模式,在發生重做日志文件被覆蓋的情況時,依據初始化參數文件中參數log_archive_dest_n的值找到oracle歸檔文件的目錄,并將被覆蓋的一個或幾個日志文件添加到日志分析過程中,保證日志分析的連續性和完整性。從原理上來說開啟了數據庫歸檔模式就能確保數據庫的任何操作不會丟失,但是開啟數據庫歸檔模式在實際應用也不十分可行,因為開啟了歸檔模式后,歸檔日志會不斷增加,若沒有人定期維護,硬盤空間就會逐漸填滿。在實際應用中可以考慮采用非歸檔模式,將日志文件設置的盡可能大一點,確保一定規模的事務操作不會導致數據庫重做日志文件被覆蓋,數據庫操作記錄不會丟失。
②網絡傳輸模塊
該模塊的主要功能是采用符合特定軍用傳輸協議的網絡傳輸手段對事務隊列進行發送和接收,作為溝通日志變更捕獲模塊和事務隊列同步模塊的橋梁。
③事務隊列同步模塊
該模塊的主要功能是將傳輸到目的數據庫上的事務隊列有序入庫,完成對目的數據庫相應庫表的同步更新,保證源端和目的端庫表內容一致。按照事務隊列先進先出的特點,選擇時間最早的未入庫事務進行入庫,并將執行情況寫入對應的同步日志表中,若事務執行失敗,還需記錄失敗的原因、oracle錯誤號等信息,同時將本次數據同步的情況反饋給源端數據庫。

圖2 掃描分析oracle重做日志文件的主要流程
本文通過對 Oracle Logminer工具的使用和研究,提出了一種解決各級指揮信息系統同構數據庫之間數據同步共享問題的新思路。Logminer主要用于數據庫的恢復,被喻為DBA一劑最好用的“后悔藥”,本文充分利用Logminer解析Oracle重做日志的特點,基于Oracle內部時鐘機制設計了日志變更捕獲模塊,定時捕獲數據庫表的變更,通過網絡傳輸模塊,在遠端數據庫進行同步更新。項目實踐證明這種同步方法可以簡便、有效、可靠的實現不同節點數據庫表的同步,具有很好的實用價值。