基于Oracle Logminer的数据同步技术研究
2020-07-18汤学达桂文军
◆张 媛 汤学达 桂文军
(中国电子科技集团公司第二十八研究所 江苏 210007)
随着指挥信息系统的不断发展和建设,当前各级指挥信息系统呈现物理位置分散、自成体系、数据不统一的特点,为构建逻辑上集中统一的指挥信息系统数据服务平台,满足各类业务应用数据访问需求,首先必须解决各级指挥信息系统之间的数据同步共享问题。本文结合现有指挥信息系统采用符合特定军用传输协议的手段进行信息交换的特点,在深入研究Oracle目前商用同步技术的基础上,提出了一种基于Oracle Logminer的数据同步方法,为在不同指挥信息系统之间保持共享数据一致性,确保不同信息系统在统一的共享数据视图下工作提供了一种有效的解决途径。
1 数据库同步技术
(1)基于触发器的数据同步技术
在 ORACLE数据库中,触发器(Trigger)是存储在数据库中的过程。当特定的某个事件(如对表或者视图进行插入、删除或者修改)发生后,这个过程就会被触发执行。基于触发器的数据同步技术的原理是在每一个同步对象表上创建增加、删除、修改三种类型的触发器,通过触发器捕获到同步对象表中的数据变更[1]。
(2)基于物化视图的数据同步技术
物化视图(Materialized View)又称快照(Snapshot),是对现有数据表或者视图查询后的结果,物化视图既保存了查询语句,又保存了查询后的结果集[2]。物化视图的快速刷新是通过物化视图日志实现的,物化视图日志记录了对应的数据表的增加、删除、修改等数据操作,定期刷新物化视图,捕获物化视图日志的变化可以实现数据同步。
(3)DataGuard数据同步技术
DataGuard是Oracle推出的一种可用性高的数据库方案,它是在主节点和备用节点间通过日志同步来保证数据库一对一的整体复制[3]。DataGuard提供了三种数据保护模式:最大性能模式、最大保护模式和最大可用模式。最大性能模式可以实现在不影响源数据库性能的基础上最大限度提高数据保护等级;最大保护模式可以确保数据不丢失,但会影响数据库的可用性;最大可用模式在不影响源数据库使用性能的条件下尽可能提高数据保护等级。
(4)Streams数据同步技术
Streams是Oracle为提高数据库的高可用性和数据的分发共享功能而设计的,在 Oracle 9i之前这个功能被称为 Advance Replication(高级复制)[4]。Streams采用高级队列技术将归档日志解析成DDL及DML语句,实现数据库之间的同步[5]。Streams具有较好的灵活性,在复制数据的同时,不影响数据库其他操作的运行,支持一对多、双向复制等多种复制方式,但Streams技术存在一定的数据局限性,并不能完全支持所有的数据类型和对象,而且Streams数据同步技术维护起来有一定的难度。
2 Logminer技术介绍
2.1 Logminer功能
在Oracle数据库中,所有对数据库进行的更改操作都被记录到重做日志文件和归档日志文件中,日志文件可用于数据库的恢复。但Oracle 8i以前这些日志文件内容不能直接阅读,使用一般的阅读工具查看到的都是乱码,Oracle 8i中首次提供了一个内置的分析工具——Logminer(日志挖掘),使用Logminer工具,DBA可以对数据库的日志进行分析[6]。Logminer具有以下优点:(1)实现事务级、细粒度的数据库恢复,通过执行相应的 UNDO操作取消用户执行的错误操作;(2)实现事后审计,利用Logminer的分析结果,可以追踪在数据库上执行的所有DML和DDL操作,取得这些操作的执行者、执行时间等重要信息;(3)优化和扩容,利用分析结果获取数据的增长模式实现优化和扩容[7]。
2.2 Logminer基本组成
(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]。
3 利用Logminer进行实时同步的设计实现
3.1 基于Logminer的数据同步原理
在图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的数据同步原理示意图
4.2 基于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重做日志文件的主要流程
4 结束语
本文通过对 Oracle Logminer工具的使用和研究,提出了一种解决各级指挥信息系统同构数据库之间数据同步共享问题的新思路。Logminer主要用于数据库的恢复,被喻为DBA一剂最好用的“后悔药”,本文充分利用Logminer解析Oracle重做日志的特点,基于Oracle内部时钟机制设计了日志变更捕获模块,定时捕获数据库表的变更,通过网络传输模块,在远端数据库进行同步更新。项目实践证明这种同步方法可以简便、有效、可靠的实现不同节点数据库表的同步,具有很好的实用价值。