一 . 前期检查工作
主库上操作 :
SELECT NAME,CREATED,LOG_MODE,OPEN_MODE,DATABASE_ROLE,FORCE_LOGGING FROM V$DATABASE; 确认数据库处于自动归档模式,如果不是,修改为自动归档模式 。
执行此句 ALTER DATABASE FORCE LOGGING;
备注: ALTER DATABASE NO FORCE LOGGING; 在所有建立Logical Standby工作完成后取消force logging .
另外,在创建逻辑备库时确保在主数据库中做配置使用的账号有以下数据库角色权限:
a、logstdby_administrator 角色, 用来使用逻辑备用功能
b、select_catalog_role 角色, 能够访问所有数据字典视图。
这里我们选用sys 来进行操作。
我们需要通过查询主库中视图DBA_LOGSTDBY_UNSUPPORTED 来确定主数据库中是否含有不支持的对象 (如果有,可能需要做一些调整才能继续) :
SQL> SELECT * FROM DBA_LOGSTDBY_UNSUPPORTED;
该视图显示包含不被逻辑STANDBY支持的数据类型的表的列名及该列的数据类型.
SELECT OWNER,TABLE_NAME FROM DBA_LOGSTDBY_NOT_UNIQUE
WHERE (OWNER,TABLE_NAME) NOT IN (SELECT DISTINCT OWNER,TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED)
AND BAD_COLUMN = 'Y';
该语句在主库中检查SQL应用能否唯一识别表列,找出不被支持的表.
确定在主数据库上,补充日志是否被启用,可以查询v$database,如下:
SQL> select supplemental_log_data_pk,supplemental_log_data_ui from v$database;
SUP SUP
‐‐‐
YES YES
如果主库中存在不符合要求的table, 补充日志没有被启用, 且确实没有办法加入PK 或非空唯一索引,那么在Primary DB上启用补充日志:
SQL> alter database add supplemental log data(primary key,unique index)
columns;
在主库上创建一个新的表空间,用于LogMiner,否则Logical Standby 需要的对象
将默认创建在SYSTEM 表空间中(这是比较危险的)。( 这一步在ORACLE 文档中似乎没有提到,这里是为了不影响system 表空间而引入的 ) 。
SQL> CREATE TABLESPACE logmnrts DATAFILE
'/data/mxdell/logmnrts01.DBF' SIZE 2000M
AUTOEXTEND OFF
EXTENT MANAGEMENT LOCAL UNIFORM. SIZE 10M ;
SQL> EXECUTE DBMS_LOGMNR_D.SET_TABLESPACE('logmnrts');
如果执行报错,可能需要增大logmnrts 表空间大小 。
SQL>show parameter LOG_ARCHIVE_LOCAL_FIRST; 确认使用默认的本地先归档(true)
SQL>alter system set archive_lag_target=600 scope=both;
设定主库强制10分钟自动归档一次 (备注: 这里设置这个参数是因为我们使用归档传输ARCH方式及最大性能模式,为了使Logical Standby上数据和Primary DB上只相差10分钟以内; 如果不是此种需要,可以不用设置)
由于后续的BMS_LOGSTDBY.BUILD这个过程会通过闪回查询的方式来获取数据字典的一致性,因此oracle 初始化参数UNDO_RETENTION 值需要设置的足够大。
Oracle recommends setting the UNDO_RETENTION initialization parameter to 3600 on both the primary and logical standby databases ,Oracle10g 默认undo_retention为900,这里设置为3600, 同样Standby上的参数也需要设置为3600。
SQL>alter system set undo_retention=3600 scope=both;
SELECT * FROM DBA_LOGSTDBY_SKIP;
查看逻辑Standby的过滤操作; 对于一些系统schema,逻辑备库默认是忽略其实际变更的。逻辑备库和主库只是逻辑意义上也就是用户数据保持一致,元数据自然是不应该复制的,否则就乱套了,所以不要在系统schema上建立任何用户自己的数据表等 。
SQL> select owner,name from DBA_LOGSTDBY_SKIP;
OWNER NAME
------------------------------ ------------------------------
SYSTEM %
SYS %
DIP %
OUTLN %
二. 在Standby Server上建立物理STANDBY
这里Physical Standby 中DB_NAME及DB_UNIQUE_NAME均为MXDELL 。spfile 是直接
拷贝主库上的参数文件,并根据具体内存修改 。这里假设两台Server硬体配置一样 。
热备份或RMAN建立物理Standby
Primary DB上参数修改:
*.db_name='mxdell'
*.db_unique_name='mxdell'
*.log_archive_dest_1='location=/data/mxdell/arch valid_for=(all_logfiles,all_roles) db_unique_name=mxdell'
*.log_archive_dest_2='service=standby valid_for=(online_logfiles,primary_role) db_unique_name=mxstandby'
*.log_archive_dest_state_1='enable'
*.log_archive_dest_state_2='enable'
备注: 按照Oracle10g 物理Standby标准文档,建立物理Standby过程中主库中的参数还有一些用于主库备库互相切换的参数比如fal_server,fal_client等 ,这里不做切换打算,暂时不设置。 详情参考:
Physical Standby上参数修改:
*.db_name='mxdell'
*.db_unique_name='mxstandby'
*.log_archive_dest_1='location=/data/mxdell/arch valid_for=(all_logfiles,all_roles) db_unique_name=mxstandby'
*.log_archive_dest_2='service=mxdell valid_for=(online_logfiles,primary_role) db_unique_name=mxdell' -- 可以不用设置,主要用于主库备库切换
*.log_archive_dest_state_1='enable'
*.log_archive_dest_state_2='enable'
*.standby_archive_dest='/data/mxdell/arch' -- 接收来自主库的Log用于应用SQL,最好设置与standby上自己的归档路径log_archive_dest_1不一致 。
*.log_archive_min_succeed_dest=1
*.db_file_name_convert='/data/mxdell','/data/mxdell'
*.log_file_name_convert='/u01/product/oradata/mxdell','/u01/product/oradata/mxdell'
*.standby_file_management='AUTO'
*.fal_server='mxdell'
*.fal_client='standby'
Primary DB 和Physical Standby 的tnsnames.ora都加入如下两设置:
其中8.114是主库IP,130.189是物理备库IP
MXDELL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.161.8.114)(PORT = 1526))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = mxdell)
)
)
STANDBY =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.134.130.189)(PORT = 1526))
(CONNECT_DATA =
(SERVICE_NAME = mxdell)
(INSTANCE_NAME = mxdell) # 可以不需要
)
)
Primary DB 和Physical Standby 上listener.ora如下(都一样),并开启两台机器的监听:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = PLSExtProc)
(ORACLE_HOME = /u01/product/oracle)
(PROGRAM = extproc)
)
(SID_DESC =
(SID_NAME = mxdell)
(ORACLE_HOME = /u01/product/oracle)
(GLOABAL_DBNAME = mxdell)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = MXPSVDFMSNDB)(PORT = 1526))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
)
)
开启主库。
物理备库上操作:
SQL> startup nomount
SQL> alter database mount standby database ;
SQL> alter database recover managed standby database disconnect from session ;
测试物理Standby的恢复同步情况 (略) 。
四 . 准备将物理Standby切换为逻辑STANDBY
注意: 先要在备库上:
SQL> alter database recover managed standby database cancel ;
然后在主库上执行: SQL>EXECUTE DBMS_LOGSTDBY.BUILD;
否则后面执行 alter database recover to logical standby mxweb01; 会一直等待。
提示:
Ø 该过程会自动启用primary 数据库的补充日志(supplemental logging)功能(如果未启用的话)。
Ø 该过程执行需要等待当前所有事务完成,因此如果当前有较长的事务运行,可能该过程
执行也需要多花一些等待时间。
Ø 该过程是通过闪回查询的方式来获取数据字典的一致性,因此oracle 初始化参数
UNDO_RETENTION 值需要设置的足够大。
切换物理Standby为逻辑Standby :
SQL> alter database recover to logical standby mxweb01;
可能会遇到两种错误:
1. sys密码不一致导致一直hand住; ---建立与主库一致的密码文件
2. 备库监听没有包含standby的instance信息。 ---监听文件中添加instance信息
重启逻辑备库
第一次启动
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database open resetlogs; (这一步应该可以看到初始归档生成)
然后
SQL> shutdown immediate;
SQL> startup;
Logical Stadnby上启动sql apply
alter database start logical standby apply;
如果要启动实时应用特性,需要先在备库添加standby redo logfile,这里我们不使用 。
alter database add standby logfile '/data/mxdell/redo01s.log' size 50m;
alter database add standby logfile '/data/mxdell/redo02s.log' size 50m;
alter database add standby logfile '/data/mxdell/redo03s.log' size 50m;
alter database add standby logfile '/data/mxdell/redo04s.log' size 50m;
alter database add standby logfile '/data/mxdell/redo05s.log' size 50m;
启动real time sql apply
alter database stop logical standby apply;
alter database start logical standby apply immediate;
自动删除已经应用过的日志
逻辑备库一方面需要接收主库传过来的日志,一方面自己也会产生日志,不及时删除,可能很快归档空间就要爆掉(如无特殊要求可开启)
假设我们还有一个异地备份物理Standby, 需要定期拷贝Logical Standby上的归档应用到逻辑Standby(不在Production DB上拷贝),那么在Logical Standby上需要禁止删除传输过来的日志, 可以这样设置:
alter database stop logical standby apply;
execute dbms_logstdby.apply_set('LOG_AUTO_DELETE','false');
alter database start logical standby apply;
Logical standby 开启关闭的步骤:
SQL> startup
SQL> alter database start logical standby apply;
SQL> alter database stop logical standby apply;
SQL> shutdown immediate
Logical Standby管理 :
注意事项:
1. 赋予sysdba给任何用户会导致logical standby 应用停止,但是归档可以传输过去(如果使用的是arch传输的话) 。