Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1200871
  • 博文数量: 350
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 5668
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-23 17:53
文章分类

全部博文(350)

文章存档

2013年(350)

分类: Oracle

2013-04-24 16:40:06

准备工作

正如我们打小就被叮嘱饭前一定要洗手,在创建逻辑standby之前,准备工作同样必不可少。

在创建逻辑standby之前,首先检查primary数据库的状态,确保primary数据库已经为创建逻辑standby做好了全部准备工作,比如说是否启动了归档,是否启用了forced logging等,这部分可以参考创建物理standby时的准备工作。

除此之外呢,由于逻辑standby是通过应用来保持与primary数据库的同步。sql应用与redo应用是有很大区别地,这事儿咱们前面提到过,redo应用实际上是物理standby端进行recover,sql应用则是分析redo文件,将其转换为sql语句在逻辑standby端执行,因此,需要注意:

并非所有的数据类型都能被逻辑standby支持;

支持的数据类型有:

BINARY_DOUBLE、BINARY_FLOAT、BLOB、CHAR、CLOB and NCLOB、DATE、INTERVAL YEAR TO MONTH、INTERVAL DAY TO SECOND、LONG、LONG RAW、NCHAR、NUMBER、NVARCHAR2、RAW、TIMESTAMP、TIMESTAMP WITH LOCAL TIMEZONE、TIMESTAMP WITH TIMEZONE、VARCHAR2 and VARCHAR 

提示:

下列类型在获取standby支持时需要注意兼容性:

clob,需要primary数据库的兼容级别运行于10.1或更高

含lob字段的索引组织表(IOT),需要primary数据库的兼容级别运行于10.2或更高

不含lob字段的索引组织表(IOT),需要primary数据库的兼容级别运行于10.1或更高

不支持的数据类型有:

BFILE、Encrypted columns、ROWID, UROWID、XMLType、对象类型、VARRAYS、嵌套表、自定义类型。

洗手杀菌可以用肥皂或洗手液,检查是否有不被逻辑standby支持的对象也同样有简单方式,我们可以通过查询视图DBA_LOGSTDBY_UNSUPPORTED来确定主数据库中是否含有不支持的对象

SQL> SELECT * FROM DBA_LOGSTDBY_UNSUPPORTED;

提示:关于DBA_LOGSTDBY_UNSUPPORTED

该视图显示包含不被支持的数据类型的表的列名及该列的数据类型。注意该视图的ATTRIBUTES列,列值会显示表不被sql应用支持的原因。

并非所有的存储类型都能被逻辑standby支持;

支持簇表(Cluster tables)、索引组织表(Index-organized tables)、堆组织表(Heap-organized tables),不支持段压缩(segment compression)存储类型

并非所有的pl/sql包都能被SQL应用支持。

那些可能修改系统元数据的包不会被sql应用支持,因此即使它们在primary执行过,并且被成功传输到逻辑standby端,也不会执行,例如:DBMS_JAVA, DBMS_REGISTRY, DBMS_ALERT, DBMS_SPACE_ADMIN, DBMS_REFRESH, DBMS_REDEFINITION, DBMS_SCHEDULER, and DBMS_AQ等。

只有dbms_job例外,primary数据库的jobs会被复制到逻辑standby,不过在standby数据库不会执行这些job。

并非所有的sql语句都能在逻辑standby执行;

默认情况下,下列sql语句在逻辑standby会被sql应用自动跳过:

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

另外,还有一大批ddl操作,同样也不会在逻辑standby端执行,由于数目较重,此处不再一一列举,感兴趣的话请查看官方文档。

并非所有的dml操作都能在逻辑standby端SQL应用;

维护逻辑standby与primary的数据库同步是通过sql应用实现,SQL应用转换的SQL语句在执行时,对于insert还好说,对于update,delete操作则必须能够唯一定位到数据库待更新的那条记录。问题就在这里,如果primary库中表设置不当,可能就无法确认唯一条件。

你可能会说可以通过rowid唯一嘛!!同学,千万要谨记啊,逻辑standby,为啥叫逻辑standby呢,它跟物理standby有啥区别呢,就是因为它只是逻辑上与primary数据库相同,物理上可能与primary数据库存在相当大差异,一定要认识到,逻辑standby的物理结构与primary是不相同的(即使初始逻辑standby是通过primary的创建),因此想通过rowid更新显然是不好使的,就不能再将其做为唯一条件。那怎么办泥,OK,话题被引入,下面请听三思向您一一道来:

如何确保primary库中各表的行可被唯一标识

Oracle 通过主键、唯一索引/约束补充日志(supplemental logging)来确定待更新逻辑standby库中的行。当数据库启用了补充日志(supplemental logging),每一条update语句写redo的时候会附加列值唯一信息,比如:

如果表定义了主键,则主键值会随同被更新列一起做为update语句的一部分,以便执行时区别哪些列应该被更新。

如果没有主键,则非空的唯一索引/约束会随同被更新列做为update语句的一部分,以便执行时区分哪些列应该被更新,如果该表有多个唯一索引/约束,则自动选择最短的那个。

如果表即无主键,也没有定义唯一索引/约束,所有可定长度的列连同被更新列作为update语句的一部分。更明确的话,可定长度的列是指那些除:long,lob,long raw,object type,collection类型外的列。

确定在主数据库上,补充日志是否被启用,可以查询v$database,如下:

SQL> select supplemental_log_data_pk,supplemental_log_data_ui from v$database;

SUP SUP

--- ---

YES YES

因此,Oracle 建议你为表创建一个主键或非空的唯一索引/约束,以尽可能确保sql应用能够有效应用redo数据,更新逻辑standby数据库。

执行下列语句检查sql应用能否唯一识别表列,找出不被支持的表

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_COLLUMN = 'Y';

提示:

关于DBA_LOGSTDBY_NOT_UNIQUE

该视图显示所有即没主键也没唯一索引的表。如果表中的列包括足够多的信息通常也可支持在逻辑standby的更新,不被支持的表通常是由于列的定义包含了不支持的数据类型。

注意BAD_COLUMN列值,该列有两个值:

Y:表示该表中有采用大数据类型的字段,比如LONG啦,CLOB啦之类。如果表中除log列某些行记录完全匹配,则该表无法成功应用于逻辑standby。standby会尝试维护这些表,不过你必须保证应用不允许

N:表示该表拥有足够的信息,能够支持在逻辑standby的更新,不过仍然建议你为该表创建一个主键或者唯一索引/约束以提高log应用效率。

假设某张表你可以确认数据是唯一的,但是因为效率方面的考虑,不想为其创建主键或唯一约束,,怎么办呢,没关系,oracle想到了这一点,你可以创建一个disable的primary-key rely约束:

关于primary-key RELY约束:

如果你能够确认表中的行是唯一的,那么可以为该表创建rely的主键,RELY约束并不会造成系统维护主键的开销,主你对一个表创建了rely约束,系统则会假定该表中的行是唯一,这样能够提供sql应用时的性能。但是需要注意,由于rely的主键约束只是假定唯一,如果实际并不唯一的话,有可能会造成错误的更新哟。

创建rely的主键约束非常简单,只要在标准的创建语句后加上RELY DISABLE即可,例如:

SQL> alter table jss.b add primary key (id) rely disable;

表已更改。


阅读(629) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~