在很多的数据处理任务中,我们经常会用到数据同步的需求,尤其是异构数据库同步,当然目前世面上有很多的数据同步工具,开源和商业的都有很多,当然Oracle自身也可以实现数据的实时或者异步同步。这里我们示例一下通过配置 Oracle 提供的 LogMiner 免费工具,进行数据变更的捕获。配置完成后,动手能力强的小伙伴,就可以自己写个代码,解析相应的变更,然后可以做成同构或者异构数据库的同步工具。
具体步骤:
登录数据库,并查看 utl_file_dir 参数是否配置。
代码语言:javascript复制sqlplus / as sysdba
show parameter utl_file_dir;
如果没有配置,则在文件系统中创建/opt/oradata/oraclelogs目录。
代码语言:javascript复制mkdir /opt/oradata/oraclelogs
在 Oracle 执行以下命令:
代码语言:javascript复制CREATE OR REPLACE DIRECTORY logdir AS '/opt/oradata/oraclelogs';
alter system set utl_file_dir = '/opt/oradata/oraclelogs' scope = spfile;
重启数据库,并执行@?/rdbms/admin/utlfile.sql
代码语言:javascript复制shutdown immediate
startup
@?/rdbms/admin/utlfile.sql
注意:在Oracle XE中,该文件将位于 /u01/app/oracle/product/11.2.0/xe/rdbms/admin/utlfile.sql。
运行以下命令配置日志参数(非必须):
代码语言:javascript复制show parameter recovery_file_dest;
alter system set log_archive_dest_1='LOCATION=/opt/oradata/oraclelogs' scope = spfile;
alter system set db_recovery_file_dest_size = [根据实际情况配置]g;
alter system set db_recovery_file_dest = '/opt/oradata/oraclelogs' scope = spfile;
关闭并重启数据库到 mount。
代码语言:javascript复制shutdown immediate
startup mount
启用归档模式:
代码语言:javascript复制alter database archivelog;
alter database open;
archive log list;
创建并授予用户使用 logminer 的以下权限:
代码语言:javascript复制create user repuser identified by repuser;
GRANT CREATE SESSION TO repuser
grant all on DBMS_LOGMNR_D to repuser;
grant all on DBMS_LOGMNR to repuser;
grant execute on sys.dbms_logmnr to repuser;
grant select on v_$archived_log to repuser;
grant select on v_$logfile to repuser;
grant select on v_$log to repuser;
grant select on v_$logmnr_contents to repuser;
grant select on v_$database to repuser;
grant select any transaction to repuser;
grant select on dba_objects to repuser;
启用补充日志记录:
代码语言:javascript复制ALTER DATABASE ADD LOGFILE('/opt/oradata/oraclelogs/tpcds.log') SIZE 100M BLOCKSIZE 512 REUSE;
select SUPPLEMENTAL_LOG_DATA_MIN from sys.v_$database;
如果结果为 NO,请运行以下命令:
代码语言:javascript复制alter database add supplemental log data;
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
select SUPPLEMENTAL_LOG_DATA_MIN from sys.v_$database;
此时结果应为 YES。
运行以下命令以验证配置过程:
代码语言:javascript复制select GROUP#,member from sys.v_$logfile;
上面命令将显示日志文件列表。要验证补充日志:
代码语言:javascript复制SELECT supplemental_log_data_min "Minimum",supplemental_log_data_pk "Primary key",supplemental_log_data_ui "Unique Key",supplemental_log_data_fk "Foregin Key",supplemental_log_data_all "All" FROM v$database;
上面的查询结果 Minimum 和 ALL 列的值为 YES,如下:
代码语言:javascript复制Minimum Pri Uni For All
-------- --- --- --- ---
YES NO NO NO YES
切换日志:
代码语言:javascript复制alter system switch logfile;
select GROUP#,THREAD#,STATUS from sys.v_$log;
注意:必须至少有一个状态是活动的。如果不是,则运行上面的查询,直到一个状态变为活动状态。
查询归档日志名称:
代码语言:javascript复制SELECT name FROM sys.v_$archived_log
从查询结果中选取条一个文件名称,这里假设第一个文件为“/opt/oradata/oraclelogs/XE/archivelog/2015_09_15/o1_mf_1_196_bzho8z5g_.arc”,运行以下命令:
代码语言:javascript复制exec sys.dbms_logmnr.add_logfile(logfilename => '/opt/oradata/oraclelogs/XE/archivelog/2015_09_15/o1_mf_1_195_bzho5hql_.arc',OPTIONS => sys.DBMS_LOGMNR.NEW);
对于第一个文件以外的日志文件,这里假设第二个文件为“/opt/oradata/oraclelogs/XE/archivelog/2015_09_15/o1_mf_1_196_bzho8z5g_.arc”,运行以下命令:
代码语言:javascript复制exec sys.dbms_logmnr.add_logfile(logfilename => '/opt/oradata/oraclelogs/XE/archivelog/2015_09_15/o1_mf_1_196_bzho8z5g_.arc',OPTIONS => sys.DBMS_LOGMNR.ADDFILE);
执行以下命令启动 logmnr。
代码语言:javascript复制exec sys.dbms_logmnr_d.build(dictionary_filename => 'dictionary.ora', dictionary_location => '/opt/oradata/oraclelogs');
EXECUTE sys.DBMS_LOGMNR.START_LOGMNR(DICTFILENAME =>'/opt/oradata/oraclelogs/dictionary.ora');
exec sys.dbms_logmnr.start_logmnr();
select table_name from sys.v_$logmnr_contents;
此时可以对表进行插入、删除、更新等操作。运行以下查询即可以获取对表所做的更改。 这里我们假设我们操作的表为:TEST1,TEST2。
代码语言:javascript复制select sql_redo from sys.v_$logmnr_contents where SEG_TYPE_NAME = 'TABLE' AND table_name in ('TEST1','TEST2');
查询出的 sql_redo 就是对表做的变更操作了。