有个项目提出的需求是这样的:部署两个相同的数据库应用A、B,两个库之间没有网络连接,要定期把A库里的数据复制到B库。
要求:
应用程序不做修改实现增量数据更新(不能重复导入)
我提出了使用DBMS_LOGMNR分析归档日志并redo变化的方案:
A库上线前数据库需要启用归档日志每次同步数据时对A库先执行一次日志切换,然后拷贝归档日志文件,拷贝后删除(最新生成的归档日志文件不要拷贝和删除)在B库上使用DBMS_LOGMNR分析归档日志文件并redo变化
create or replace directory logfilename_dir as 'D:\logmine\';
grant read, write on directory logfilename_dir to wxy;
conn user1/password1
begin
excute immediate 'create table logname_ext (logfile_name varchar2(300)) organization external (type oracle_loader default directory data_dir logfilename_dir location (''log_file_name.txt''))';
exception when others then
if sqlcode = -955 then -- 名称已由现有对象使用
null;
else
raise;
end if;
end;
/
echo off
dir /a-d /b /s D:\logmine\redo_log\*.log > D:\logmine\log_file_name.txt
sqlplus user1/password1 @D:\logmine\create_ext_table.sql
begin
for x in (select logfile_name from logname_ext) loop
dbms_logmnr.add_logfile(x.logfile_name);
end loop;
end;
/
execute dbms_logmnr.start_logmnr(options => dbms_logmnr.committed_data_only);
begin
for x in (select sql_redo
from v$logmnr_contents
where table_space != 'SYSTEM' and instr(sql_redo,'"WXY".') > 0
order by commit_scn)
loop
execute immediate x.sql_redo;
end loop;
end;
/
exit;
要求:
应用程序不做修改实现增量数据更新(不能重复导入)
我提出了使用DBMS_LOGMNR分析归档日志并redo变化的方案:
A库上线前数据库需要启用归档日志每次同步数据时对A库先执行一次日志切换,然后拷贝归档日志文件,拷贝后删除(最新生成的归档日志文件不要拷贝和删除)在B库上使用DBMS_LOGMNR分析归档日志文件并redo变化
因为网不通,手工拷贝文件的工作不可避免,所以可以认为第1、2步为手工操作。第1步为上线前的数据库准备,是一次性工作;第2、3步为周期性工作。对于第3步,做了个简单的实现:在B库机器上上规划好目录,这里D:\logmine为主目录,D:\logmine\redo_log存放从A库拷贝来的归档日志文件。在B库上执行一次初始化对象脚本:
[sql] view plain copycreate or replace directory logfilename_dir as 'D:\logmine\';
grant read, write on directory logfilename_dir to wxy;
conn user1/password1
begin
excute immediate 'create table logname_ext (logfile_name varchar2(300)) organization external (type oracle_loader default directory data_dir logfilename_dir location (''log_file_name.txt''))';
exception when others then
if sqlcode = -955 then -- 名称已由现有对象使用
null;
else
raise;
end if;
end;
/
要做的工作:
拷贝A库归档日志文件到D:\logmine\redo_log执行D:\logmine\create_ext_table.bat删除1步拷贝的归档日志文件
create_ext_table.bat
[plain] view plain copyecho off
dir /a-d /b /s D:\logmine\redo_log\*.log > D:\logmine\log_file_name.txt
sqlplus user1/password1 @D:\logmine\create_ext_table.sql
create_ext_table.sql
[sql] view plain copybegin
for x in (select logfile_name from logname_ext) loop
dbms_logmnr.add_logfile(x.logfile_name);
end loop;
end;
/
execute dbms_logmnr.start_logmnr(options => dbms_logmnr.committed_data_only);
begin
for x in (select sql_redo
from v$logmnr_contents
where table_space != 'SYSTEM' and instr(sql_redo,'"WXY".') > 0
order by commit_scn)
loop
execute immediate x.sql_redo;
end loop;
end;
/
exit;
这只是个实验,没有经过严格的测试,考虑到异常捕获和处理、数据量、系统负载、性能优化等等因素,能否应用于生产环境有待验证。