逻辑备库只是对于主库的一个逻辑意义上的数据冗余,不像物理备库能够在block级别上和主库保持一致。所以有其优点,也有其缺点。比如主库的一个datafile损坏,可以从物理备库拷贝对应的文件过来然后recover datafile就可以恢复,逻辑备库则无法实现这样保护了。由于是SQL APPLY,对于一些数据类型也是有限制的。
不支持的数据类型
Oracle10gR2的logical standby已经能支持大多数的数据类型了,包括CLOB/BLOB/LONG等,但还是有几种类型是不支持的。如果主库中有使用到这些数据类型,则需要使用其他方式进行处理。
BFILE
Collections (including VARRAYS and nested tables)
Encrypted columns
Multimedia data types (including Spatial, Image, and Context)
ROWID, UROWID
User-defined types
XMLType
可以通过查询DBA_LOGSTDBY_UNSUPPORTED视图来查看当前库中是否有table包含了这些不支持的数据类型
no rows selected
如果发现有不支持的table,则可以进一步查询得到不支持的是哪些列和列的类型。
此外,压缩段存储是不支持的。需要修改系统元数据的PL/SQL过程如DBMS_JAVA, DBMS_REGISTRY, DBMS_ALERT, DBMS_SPACE_ADMIN, DBMS_REFRESH, DBMS_REDEFINITION, DBMS_SCHEDULER, and DBMS_AQ也是不支持的,也就是说,这些包在主库可以执行,但是不会将相应的改变传递到备库去。但有一个例外,就是DBMS_JOB。使用DBMS_JOB提交的Job会复制到备库,但是在备库的job是不会调度运行的,只有在切换后,原来的备库变成新的主库,这些Job会根据原来主库执行的情况自动启动。这个我在测试的时候碰到在主库提交一个Job,在备库看不到,直到在主库remove后,在备库的dba_jobs中才能查到该Job的记录,比较奇怪。先记录下来,以后再详细测试。
默认不复制的schema
对于一些系统schema,逻辑备库默认是忽略其实际变更的。逻辑备库和主库只是逻辑意义上也就是用户数据保持一致,元数据自然是不应该复制的,否则就乱套了。
OWNER NAME
------------------------------ ------------------------------
SYSTEM %
SYS %
DIP %
OUTLN %
WMSYS %
DBSNMP %
不支持的语句
以下语句在主库执行时不会应用到备库。基本上,只影响元数据的东西都是不会在备库应用的。
ALTER DATABASE
ALTER MATERIALIZED VIEW
ALTER MATERIALIZED VIEW LOG
ALTER SESSION
ALTER SYSTEM
CREATE CONTROL FILE
CREATE DATABASE
CREATE DATABASE LINK
CREATE PFILE FROM SPFILE
CREATE MATERIALIZED VIEW
CREATE MATERIALIZED VIEW LOG
CREATE SCHEMA AUTHORIZATION
CREATE SPFILE FROM PFILE
DROP DATABASE LINK
DROP MATERIALIZED VIEW
DROP MATERIALIZED VIEW LOG
EXPLAIN
LOCK TABLE
SET CONSTRAINTS
SET ROLE
SET TRANSACTION
此外,我们也可以通过DBMS_LOGSTDBY.SKIP过程指定某些对象的数据不在备库应用,这些对象也可以在DBA_LOGSTDBY_SKIP视图中查到。如果在主库执行了这些不支持的DDL,在备库的alert中会做做如下记录:
LOGSTDBY stmt: ALTER DATABASE OPEN
ORA-16226: DDL skipped due to lack of support
LOGSTDBY id: XID 0×0002.01b.00000064, hSCN 0×0000.000314d7, lSCN 0×0000.000314d7, Thread 1, RBA 0×0041.00000050.174, txnCscn 0×0000.000314da, PID 2180, ORACLE.EXE (P004)
主键和唯一键约束
前面也有提到,由于Oracle的日志是半逻辑半物理结构的,主库的redo在备库解析出来后,每一行数据的变更都会生成一条SQL。这样要求在备库能够唯一区别出一行数据。由于主备库只是逻辑上一致,其ROWID属于物理结构,是不一样的。所以最好能在主库的表上有主键或者唯一键约束。如果没有,则需要在日志中记录发生变化的数据行的所有列(除了LONG, LOB, LONG RAW, object type, and collections等类型的列),这样就需要在主库生成许多额外的日志量,在备库解析和应用日志时也需要占用更多的资源,对性能造成一定的压力。
当然如果应用能确保表中某些列的数据是唯一的,也不一定需要在主库创建实际生效的约束,使用RELY DISABLE关键字来创建约束,然后在备库对应列上创建一个索引就可以了。这样主库也就不需要为维护唯一约束付出代价。
可以通过查询DBA_LOGSTDBY_NOT_UNIQUE视图来获得系统中没有主键或者唯一键的表的情况
OWNER TABLE_NAME
------------------------------ ------------------------------
NING TEST2