Oracle Data Guard逻辑备库是利用主库的一个备份首先建立一个物理备库,然后再将其转换为逻辑备库。这之后主库将日志传递到备库,备库利用logminer从主库的日志中解析出主库所执行过的SQL,在备库上重新执行一遍,从而保证与主库的数据在逻辑上保持一致。与
Oracle Data Guard逻辑备库是利用主库的一个备份首先建立一个物理备库,然后再将其转换为逻辑备库。这之后主库将日志传递到备库,备库利用logminer从主库的日志中解析出主库所执行过的SQL,在备库上重新执行一遍,从而保证与主库的数据在逻辑上保持一致。与物理备库相对应的是,物理备库使用的是redo apply,逻辑备库使用的是sql apply。因此逻辑备库仅仅保证数据与主库是在逻辑上是一致的,从而逻辑备库可以处于open状态下并进行相应的DML操作。
在转换physical备库到logical备库之前,先来看看主备库的情况:
SQL> select name,open_mode,database_role,protection_mode from v$database;Nach dem Login kopieren
- Primary库
Physical备库
由于逻辑Standby是通过SQL应用来保持与Primary数据库的同步。SQL应用与REDO应用是有很大的区别,REDO应用实际上是在物理Standby端进行RECOVER;SQL应用则是分析重做日志文件中的REDO信息,并将其转换为SQL语句,在逻辑Standby端执行,因此需要确认操作的对象和语句是否能被逻辑Standby支持。
- 检查primary数据库是否有不被逻辑standby支持的对象
SQL> SELECT * FROM DBA_LOGSTDBY_UNSUPPORTED;Nach dem Login kopieren
- 查看primary数据库中不含有主键或唯一键索引的表
SQL> SELECT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_NOT_UNIQUE 2> WHERE (OWNER, TABLE_NAME) NOT IN 3> (SELECT DISTINCT OWNER, TABLE_NAME FROM DBA_LOGSTDBY_UNSUPPORTED) 4> AND BAD_COLUMN = 'Y';Nach dem Login kopieren
注意BAD_COLUMN列值,该列有两个值:
Y :表示该表中有采用大数据类型的字段,比如LONG啦,CLOB啦之类。如果表中除log列某些行记录完全匹配,则该表无法成功应用于逻辑standby。standby会尝试维护这些表,不过你必须保证应用不允许。
N :表示该表拥有足够的信息,能够支持在逻辑standby的更新,不过仍然建议你为该表创建一个主键或者唯一索引/约束以提高log应用效率。
假设在某张表中你可以确认数据是唯一的,但是基于效率方面的考虑,不想为其创建主键或唯一约束,怎么办呢?没关系,Oracle早想到了这一点,你可以创建一个DISABLE的Primary-Key Rely约束。
Add a disabled primary-key RELY constraint.(摘自君三思)Nach dem Login kopieren
维护逻辑standby与primary的数据库同步是通过sql应用实现,SQL应用转换的SQL语句在执行时,对于insert还好说,对于update,delete操作则必须能够唯一定位到数据库待更新的那条记录。如果primary库中表设置不当,可能就无法确认唯一条件。所以,Oracle 建议为表创建一个主键或非空的唯一索引/约束,以尽可能确保sql应用能够有效应用redo数据,更新逻辑standby数据库。
如果能够确认表中的行是唯一的,那么可以为该表创建rely的主键,RELY约束并不会造成系统维护主键的开销,主你对一个表创建了rely约束,系统则会假定该表中的行是唯一,这样能够提供sql应用时的性能。但是需要注意,由于rely的主键约束只是假定唯一,如果实际并不唯一的话,有可能会造成错误的更新哟。
创建rely的主键约束非常简单,只要在标准的创建语句后加上RELY DISABLE即可,例如:
SQL> ALTER TABLE mytab ADD PRIMARY KEY (id, name) RELY DISABLE;Nach dem Login kopieren
注 意:创建了Rely约束后,Oracle会假定该列是唯一的(给DBA足够的信任),不过并不会对该列的值进行唯一性的验证,因此该列是否唯一只能由DBA来主动维护。
参详物理standby创建
Physical备库切换到logical备库,需要在primary库构建LogMiner字典及开启supplemental日志,在这之前应先停用physical备库的MRP进程,以避免提前应用含LogMiner字典的REDO数据,造成转换为逻辑Standby后,SQL应用时没有LogMiner字典数据的REDO数据而影响到逻辑Standby与Primary的正常同步。
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;Nach dem Login kopieren
备库恢复传输redo:
SQL> recover managed standby database disconnect from session;Nach dem Login kopieren
一是将主库LOG_ARCHIVE_DEST_1参数中的VALID_FOR属性改为仅仅联机重做日志有效,而不包括备用重做日志。当primary为主库时,用于存放primary产生的arch,当primary被切换为备库角色后,用于存放自身作为备库产生的归档。
LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ONLINE_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=primary'Nach dem Login kopieren
二是专门为备用重做日志添加一个新的归档路径LOG_ARCHIVE_DEST_3,也就是说联机日志与备用日志分开,仅当primary库转为备库时有效,当primary库为备库角色时,用于存放从primary库接收到的STANDBY_LOGFILES。
LOG_ARCHIVE_DEST_3='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=primary' LOG_ARCHIVE_DEST_STATE_3=ENABLENach dem Login kopieren
- 生成LogMiner字典
生成LogMiner字典,这样redo日志中的变化才能被LogMiner字典的SQL Apply组件正确解析。
SQL> EXECUTE DBMS_LOGSTDBY.BUILD;Nach dem Login kopieren
另外主键和唯一约束/索引列的supplemental日志是自动生成的,The supplemental logging information ensures each update contains enough information to logically identify each row that is modified by the statement.对于11.2以上的版本,supplemental日志会随primary库传至physical备库,而这之前的版本需要检查primary库与physical 备库是否生成supplemental日志,如果没有则主库通过如下语句生成,然后再执行switchover 或 failover传至physical 备库。
SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA (PRIMARY KEY, UNIQUE INDEX) COLUMNS;Nach dem Login kopieren
- physical备库转logical备库
若physical备库为RAC模式,则需先进行:
SQL> ALTER SYSTEM SET CLUSTER_DATABASE=FALSE SCOPE=SPFILE; SQL> SHUTDOWN ABORT; SQL> STARTUP MOUNT EXCLUSIVE;Nach dem Login kopieren
转physical备库为logical备库:
SQL> ALTER DATABASE RECOVER TO LOGICAL STANDBY db_name;Nach dem Login kopieren
- 备库参数配置
SQL> SHUTDOWN; SQL> STARTUP MOUNT; LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=standby'Nach dem Login kopieren
与physical备库所不同的是,logical备库被open后会产生自己的重做日志(redo),因此我们需要配置参数LOG_ARCHIVE_DEST_n。对于逻辑备库,此时存在三种日志文件,即online redo log,archived redo log,standby redolog。
LOG_ARCHIVE_DEST_3='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=standby'; LOG_ARCHIVE_DEST_STATE_3=ENABLENach dem Login kopieren
- 由于逻辑standby与primary数据库事务并不一致,因此第一次打开时必须指定resetlogs子句
SQL> ALTER DATABASE OPEN RESETLOGS;Nach dem Login kopieren
- 应用redo数据
SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;Nach dem Login kopieren
- 查询数据库状态
SQL> select name,open_mode,database_role,protection_mode from v$database;Nach dem Login kopieren
Primary库NN用户T1表插入数据
Logical standby库查询
至此,ORACLE 11G 之DATAGUARD搭建逻辑standby成功!