http://zhaoyong.blog.51cto.com/61971/125470
oracle 高级复制同步数据
oracle我不是很熟,但现被安排要做个2台数据库表同步复制,不懂,只能从开始研究,制作。如果你和我一样,看了我的制作过程,一定给你很大的帮助。废话不说了,开始.......google....次数已经记不清楚了,可以用天衡量了,大概时断时续一周。。汗死。。。。。在此,非常感谢那些发表文章的人,通过看过很多人的文章,我才能基本完成,感谢!
概述:
在Internet上运作数据库经常会有这样的需求:把遍布全国各城市相似的数据库应用统一起来,一个节点的数据改变不仅体现在本地,还反映到远端。复制技术给用户提供了一种快速访问共享数据的办法。
前提条件
要准备2台测试用的机器,开始制作如下:
2台机器安装oracle10g,注意我的版本相同。
SID都是music1
1:安装及运行vnc。。。用于远程安装oracle
2:安装及运行 oracle10.2....
完成以上步骤后,基本工作就算做完了,现在开始配置高级复制。
假设数据库机器为 数据库机器A ...数据库机器B...
数据库机器A地址为;192.168.1.205
SID:music1
域名:master.anymusic.com
数据库机器B地址为;192.168.1.226
SID:music1
域名:salse.anymusic.com
首先配置确认俩台机器可以互相访问,如下:
机器A操作:
用oracle登陆
修改如下文件;
vi tnsnames.ora
添加:
MUSIC226 = 这个名称随便起
(DE.ION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.226)(PORT = 1521)) 这里为机器B的地址及数据库端口号
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = music1) 这个名称为机器B 数据库SID的值
)
)
配置完重起数据库
机器B操作:
用oracle登陆
同样修改如下文件;
vi tnsnames.ora
添加:
MUSIC205 = 这个名称随便起
(DE.ION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.205)(PORT = 1522)) 这里为机器A的地址及数据库端口号
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = music1) 这个名称为机器A 数据库SID的值
)
)
重起数据库
测试数据库连通性,在机器A如下;
[oracle@localhost admin]$ tnsping music226
显示如下;
TNS Ping Utility for Linux: Version 10.2.0.1.0 - Production . 04-JAN-2009 16:53:23
Copyright (c) 1997, 2005, Oracle. All rights reserved.
Used parameter files:
/home/oracle/oracle/product/10.2.0/network/admin/sqlnet.ora
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DE.ION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.226)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = music1)))
OK (10 msec)
测试数据库连通性,在机器B如下;
[oracle@localhost admin]$ tnsping music205
显示;
TNS Ping Utility for Linux: Version 10.2.0.1.0 - Production . 04-JAN-2009 17:09:04
Copyright (c) 1997, 2005, Oracle. All rights reserved.
Used parameter files:
/home/oracle/oracle/product/10.2.0/network/admin/sqlnet.ora
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DE.ION = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.205)(PORT = 1522)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = music1)))
OK (0 msec)
注意:这里我的2台机器没有加防火墙等其他安全措施,数据库也没有设置限制地址登陆。如果你连接不上,就仔细看看自己的其他配置。
接着在机器A操作如下:
察看v$option,Advanced replication为TRUE,则支持高级复制功能;否则不支持
select * from v$option;
以上察看结果默认为ture,支持高级复制。
察看global_name参数
SQL> show parameter global_name;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
global_names boolean FALSE
看过大多数文章都将这里要设置成true,我没有改动,默认false使用,
察看默认global_name,数据库域名
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
MUSIC1.REGRESS.RDBMS.DEV.US.ORACLE.COM
修改global_name,数据库域名
SQL> alter database rename global_name to master.anymusic.com;
察看修改结果;
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
MASTER.ANYMUSIC.COM
创建帐户及数据:
SQL> create user wcms identified by abc123 default tablespace users;
SQL>grant connect,resource to wcms;
切换到wcms,
SQL> conn wcms/abc123
创建表
SQL> create table test(id number,name varchar2(20),constraint test_id_pk primary key(id)); (主键一定是要的);
插入数据
SQL> insert into test values(1,'abc');
SQL> insert into test values(2,'def');
建立管理数据库复制的用户repadmin,并赋权。
SQL> create user repadmin identified by repadmin default tablespace users temporary tablespace temp;
SQL> execute dbms_defer_sys.register_propagator('repadmin');
SQL> grant execute any procedure to repadmin;
SQL> execute dbms_repcat_admin.grant_admin_any_repgroup('repadmin');
SQL> execute dbms_repcat_admin.grant_admin_any_schema(username => 'repadmin');
SQL> grant comment any table to repadmin;
SQL> grant lock any table to repadmin;
SQL> grant select any dictionary to repadmin;
用repadmin 创建database link 连接
SQL> conn repadmin/repadmin
SQL> create database link "salse.anymusic.com" connect to repadmin identified by repadmin using 'music226';
说明一下;salse.anymusic.com为我修改global_name的值
music226 :是以上tnsnames.ora中我设定连接机器B数据库的值
察看一下:SQL> select owner,db_link,host from all_db_links;
OWNER DB_LINK HOST
REPADMIN SALSE.ANYMUSIC.COM music226
在机器B操作如下;
察看v$option,Advanced replication为TRUE,则支持高级复制功能;否则不支持
select * from v$option;
以上察看结果默认为ture,支持高级复制。
察看global_name参数
SQL> show parameter global_name;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
global_names boolean FALSE
察看默认global_name,数据库域名
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
MUSIC1.REGRESS.RDBMS.DEV.US.ORACLE.COM
修改global_name,数据库域名
SQL> alter database rename global_name to salse.anymusic.com;
察看修改结果;
SQL> select * from global_name;
GLOBAL_NAME
--------------------------------------------------------------------------------
SALSE.ANYMUSIC.COM
创建帐户及数据:
SQL> create user wcms identified by abc123 default tablespace users;
SQL>grant connect,resource to wcms;
切换到wcms,
SQL> conn wcms/abc123
创建表
SQL> create table test(id number,name varchar2(20),constraint test_id_pk primary key(id)); (主键一定是要的);
插入数据
SQL> insert into test values(1,'zhao');
SQL> insert into test values(2,'yong');
配置复制管理用户
SQL> create user repadmin identified by repadmin default tablespace users;
建立管理数据库复制的用户repadmin,并赋权。
SQL> create user repadmin identified by repadmin default tablespace users temporary tablespace temp;
SQL> execute dbms_defer_sys.register_propagator('repadmin');
SQL> grant execute any procedure to repadmin;
SQL> execute dbms_repcat_admin.grant_admin_any_repgroup('repadmin');
SQL> execute dbms_repcat_admin.grant_admin_any_schema(username => 'repadmin');
SQL> grant comment any table to repadmin;
SQL> grant lock any table to repadmin;
SQL> grant select any dictionary to repadmin;
用repadmin 创建database link 连接
SQL> create database link "master.anymusic.com" connect to repadmin identified by repadmin using 'music205';
说明一下;master.anymusic.com为我修改global_name的值
music205 :是以上tnsnames.ora中我设定连接机器A数据库的值
察看一下:SQL> select owner,db_link,host from all_db_links;
SQL> select owner,db_link,host from all_db_links;
OWNER DB_LINK HOST
--------------------------------------------------------------------------------
REPADMIN MASTER.ANYMUSIC.COM music205
测试开始
登陆机器A
测试数据库链接:
SQL> select * from
[email protected];
显示:
GLOBAL_NAME
--------------------------------------------------------------------------------
SALSE.ANYMUSIC.COM
表示数据库到此连接成功
登陆机器B
测试数据库链接:
SQL> select * from
[email protected];
显示:
GLOBAL_NAME
--------------------------------------------------------------------------------
MASTER.ANYMUSIC.COM
表示数据库到此连接成功。
登陆数据库机器A
开始复制实施进程,在主数据库执行
用repadmin 登陆数据库
创建主复制组rep_anymusic,此名可以任意命名
SQL> execute dbms_repcat.create_master_repgroup('REP_anymusic');
察看复制主体组相关信息:
SQL> select gname,master,status from dba_repgroup
GNAME M STATUS
------------------------------ - ---------
REP_ANYMUSIC Y QUIESCED
QUIESCED表示主体组未开始运行。
在主体组中添加复制对象
SQL> execute dbms_repcat.create_master_repobject (sname=>'wcms',oname=>'test', type=>'TABLE', use_existing_object=>true,gname=>'REP_anymusic',copy_rows=>true);
sname 实现数据库复制的用户名称
oname 实现数据库复制的数据库对象名称
type 实现数据库复制的数据库对象类别。(支持的类别:表,索引,同义词,触发器,视图,过程,函数,程序包,程序包体)
use_existing_object true表示用主复制节点已经存在的数据库对象
gname 主复制组名
copy_rows true表示第一次开始复制时和主复制节点保持一致
察看复制主体组中复制对象的相关信息:
SQL>select sname,oname,status,gname from dba_repobject
SNAME ONAME STATUS GNAME
------------------------------
WCMS TEST VALID REP_ANYMUSIC
为复制对象生成复制支持:
SQL> execute dbms_repcat.generate_replication_support('wcms','test','TABLE');
(说明:产生支持wcms用户下test表复制的数据库触发器和程序包)
再次察看对应的复制对象的相关信息:
SQL> select sname,oname,status,gname from dba_repobject
SNAME ONAME STATUS GNAME
------------------------------
WCMS TEST VALID REP_ANYMUSIC
WCMS TEST$RP VALID REP_ANYMUSIC
WCMS TEST$RP VALID REP_ANYMUSIC
为复制主体组添加数据库主站点:
SQL>execute dbms_repcat.add_master_database(gname=>'REP_anymusic',master=>'salse.anymusic.com',
use_existing_objects=>true,copy_rows=>true, propagation_mode => 'synchronous');
gname 主复制组名
master 加入主复制节点的另一个数据库
use_existing_object true表示用主复制节点已经存在的数据库对象
copy_rows false表示第一次开始复制时不用和主复制节点保持一致
propagation_mode 异步地执行
察看复制站点信息:
SQL> select gname,dblink,masterdef,master from dba_repsites
GNAME DBLINK M M
REP_ANYMUSIC MASTER.ANYMUSIC.COM Y Y
REP_ANYMUSIC SALSE.ANYMUSIC.COM N Y
启动复制进程:
SQL> execute dbms_repcat.resume_master_activity('REP_anymusic',true);
再次察看复制主体组相关信息:
SQL> select gname,master,status from dba_repgroup
GNAME M STATUS
------------------------------ - ---------
REP_ANYMUSIC Y NORMAL
确认复制的任务队列已经加入数据库的数据字典
SQL>select job,log_user,this_date,next_date,next_sec,broken,failures,what from user_jobs;
JOB LOG_USER THIS_DATE NEXT_DATE
NEXT_SEC B FAILURES WHAT
21 REPADMIN 05-JAN-09
14:23:42 N 0 dbms_repcat.do_deferred_repcat_admin('"REP_ANYMUSIC"', FALSE);
注释:job:表示当前此工作的标示号
log_user: 表示当前工作的操作者
this_date:表示当前工作是否正在工作,空为空闲。
next_date:表示此工作下次执行日期
next_sec:表示此工作下次执行时间
broken:表示工作是否被挂起
failures:表示工作失败次数
what: 应该是工作执行语句
注意:复制主体组的状态由QUIESCED变为NORMAL。停顿(quiesced )正常(normal)
这里在以repadmin登陆机器B,察看结果如下就表示正确
SQL>select job,log_user,this_date,next_date,next_sec,broken,failures,what from user_jobs;
JOB LOG_USER THIS_DATE NEXT_DATE NEXT_SEC B FAILURES WHAT
21 REPADMIN 05-JAN-09 14:52:04 N 0 dbms_repcat.do_deferred_repcat_admin('"REP_ANYMUSIC"', FALSE);
至此,这个复制过程实施完毕。可以进行相关的数据操作进行测试
开始测试:
用wcms登陆机器A数据库
插入表test中数据
SQL> insert into test values(4,'aaaaaaaa');
察看结果
SQL> select * from test;
ID NAME
---------- --------------------
4 aaaaaaaa
用wcms登陆机器B数据库
察看表test中数据,因为我以上只对表test作了数据同步工作
SQL> select * from test;
ID NAME
---------- --------------------
4 aaaaaaaa
如果没有看到同步的数据,那就多等会,再看。
由于以上只同步一张表,在现有组中再次插入同步的表,
以wcms 登陆数据库,在机器A中创建表
SQL> create table aa(id number,name varchar2(20),constraint aa_id_pk primary key(id));
接着插入数据
SQL> insert into aa values(1,'abc');
以repadmin登陆数据库
接下来添加新表然后执行同步操作
SQL> execute dbms_repcat.suspend_master_activity('rep_anymusic');
取消抑制。停止主体组
SQL> execute dbms_repcat.create_master_repobject(sname=>'wcms',oname=>'aa',type=>'TABLE',use_existing_object=>true,gname=>'REP_anymusic',copy_rows=>true);
为组增加新表。
SQL>execute dbms_repcat.generate_replication_support('wcms','aa','TABLE')
增加支持。
SQL>execute dbms_repcat.resume_master_activity('REP_anymusic',true);
启动进程
用wcms帐户登陆机器B,
SQL> select * from aa;
ID NAME
---------- --------------------
1 abc
登陆机器A
创建复制数据库的时间表,作用是将俩个数据库添加到主体组的表同步,包括,添加,删除,创建 新表及表中数据。以上作用说明我是个人认为。如果你清楚以下push任务具体作用,请告诉我。。
添加PUSH任务
SQL> begin
2 dbms_defer_sys.schedule_push(
3 destination=>'SALSE.ANYMUSIC.COM',
4 interval=>'sysdate + 10/1440', 一天每10分钟运行一次
5 next_date=>sysdate, 下一次运行时间为当前时间
6 delay_seconds=>50, 延迟秒数50
7 parallelism=>1);
8 end;
9 /
如果出现以下类似错误,那就注意仔细看看语法是否正确,我出现这个错误是,第3行,第4行 没有加单引号出的错。哈哈
ERROR at line 3:
ORA-06550: line 3, column 16:
PLS-00201: identifier 'SALSE.ANYMUSIC' must be declared
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
ERROR at line 1:
ORA-23319: parameter value "07-JAN-09" is not appropriate
ORA-06512: at "SYS.DBMS_DEFER_SYS", line 2346
ORA-01403: no data found
ORA-06512: at line 2
添加PURGE任务
SQL> begin
2 dbms_defer_sys.schedule_purge (
3 next_date => sysdate,
4 interval => 'sysdate + 10/1440',
5 delay_seconds => 0);
### 6 rollback_segment =>0);
7 end;
8 /
SQL> select job,what from user_jobs;
JOB WHAT
21 dbms_repcat.do_deferred_repcat_admin('"REP_ANYMUSIC"', FALSE);
41 declare rc binary_integer; begin rc := sys.dbms_defer_sys.push(destination=>'SALSE.ANYMUSIC.COM'); end;
42 declare rc binary_integer; begin rc := sys.dbms_defer_sys.purge( delay_seconds=>0, rollback_segment=>'0'); end;
登陆机器B:
用repadmin登陆数据库,同样添加以下代码
SQL> begin
2 dbms_defer_sys.schedule_push(
3 destination=>'master.anymusic.com',
4 interval=>'sysdate + 10/1440',
5 next_date=>sysdate,
6 delay_seconds=>50, 延迟秒数50
7 parallelism=>1);
8 end;
9 /
SQL> begin
2 dbms_defer_sys.schedule_purge (
3 next_date => sysdate,
4 interval => 'sysdate + 10/1440',
5 delay_seconds => 0);
### 6 rollback_segment =>0);
7 end;
8 /
SQL> select job,what from user_jobs;
JOB WHAT
--------------------------------------------------------------------------------
21 dbms_repcat.do_deferred_repcat_admin('"REP_ANYMUSIC"', FALSE);
41 declare rc binary_integer; begin rc := sys.dbms_defer_sys.push(destination=>'MASTER.ANYMUSIC.COM'); end;
42 declare rc binary_integer; begin rc := sys.dbms_defer_sys.purge( delay_seconds=>0, rollback_segment=>'0'); end;
OK!!!!至此完成同步复制操作,以下是一些实用命令,呵呵呵。。如果以上有哪里不对,请给于指明。。。。。。。
#######################################
用select * from dba_repgroup;检查站点状态 状态为NORMAL时表示该站点正常。
相关视图
" DBA_REPSITES ----复制站点情况
" DBA_REPGROUP -----复制组情况
" DBA_REPOBJECT ----复制对象情况
" DBA_REPCATLOG ---同步情况日志
######################################
如果想删除其中的一个同步表,如下执行;
SQL> execute dbms_repcat.suspend_master_activity('rep_anymusic'); 停止主体组
SQL> EXECUTE Dbms_Repcat.Drop_Master_Repobject('wcms','test','table'); 删除同步表
SQL> EXECUTE Dbms_Repcat.Remove_Master_Databases('rep_anymusic', 'master.anymusic.com');删除主站点上面的组
SQL> execute dbms_repcat.resume_master_activity('REP_anymusic',true); 启动复制组
######################################
删除私有数据链路
用repadmin 登陆数据库
EXECUTE Dbms_Repcat.Drop_Master_Repgroup('主体组名');删除主体组
DROP DATABASE LINK master.anymusic.com; 删除db link名
删除jobs
select job,what from user_jobs; 查询job numbers
EXECUTE Dbms_Job.Remove(2); 括号内填写刚查询到的job numbers
######################################
删除REPADMIN用户,注意:必须先删除站点下隶属于该repadmin用户的jobs和组mygrp 才能删除用户
用sys登陆
EXECUTE Dbms_Defer_Sys.Unregister_Propagator(username=>'REPADMIN');
EXECUTE Dbms_Repcat_Admin.Revoke_Admin_Any_Schema(username=>'REPADMIN');
DROP USER repadmin CASCADE;
######################################
--删除公用的数据链路
用sys登陆
DROP PUBLIC DATABASE LINK master.anymusic.com;
######################################
备注:每次运行完repcat 包以后都应该执行一次commit,因为某些rep 的存储过程是不会
自动commit 的,同时这也是一个troubleshooting,一般的rep 脚本都会较快的返回结果,
如果一条命令之后长时间没有结果返回,那么很可能是上面的命令没有commit,取消掉当
前的命令,然后作一次commit,再重新执行,一般都能够解决问题。
#######################################
强制删除复制组
Sql>Truncate table system.def$_aqcall;
Sql>Exec dbms_repcat.drop_master_repgroup(gname=>'mygrp',all_sites=>true);