Decode360's Blog

业精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

  BlogJava :: 首页 :: 新随笔 :: 联系 ::  :: 管理 ::
  397 随笔 :: 33 文章 :: 29 评论 :: 0 Trackbacks
本文作者: junsansi     转载网址: http://www.5ienet.com/index.shtml
 
 
第三部分逻辑standby(1)创建步骤  2008.02.03
 
 
一、准备工作
 
    正如我们打小就被叮嘱饭前一定要洗手,在创建逻辑standby 之前,准备工作同样必不可少。
 
    在创建逻辑standby 之前,首先检查primary 数据库的状态,确保primary 数据库已经为创建逻辑standby做好了全部准备工作,比如说是否启动了归档,是否启用了forced logging 等,这部分可以参考创建物理standby时的准备工作。
 
    除此之外呢,由于逻辑standby 是通过sql 应用来保持与primary 数据库的同步。sql 应用与redo 应用是有很大区别地,这事儿咱们前面提到过,redo 应用实际上是物理standby 端进行recover,sql 应用则是分析redo 文件,将其转换为sql 语句在逻辑standby 端执行,因此,需要注意:
 
    并非所有的数据类型都能被逻辑standby支持;
 
    支持的数据类型有:
    BINARY_DOUBLE、BINARY_FLOAT、BLOB、CHAR、CLOB and NCLOB、DATE、INTERVAL YEAR TOMONTH、INTERVAL DAY TO SECOND、LONG、LONG RAW、NCHAR、NUMBER、NVARCHAR2、RAW、TIMESTAMP、TIMESTAMP WITH LOCAL TIMEZONE、TIMESTAMP WITH TIMEZONE、VARCHAR2 andVARCHAR

    提示:
    下列类型在获取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 端执行,由于数目较重,此处不再一一列举,感兴趣的话请google 查看官方文档。
 
    并非所有的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 语句的一部分,以便执行时区分哪些列应该被更新,如果该表有多个唯一索引/约束,则oracle 自动选择最短的那个。
    ◆ 如果表即无主键,也没有定义唯一索引/约束,所有可定长度的列连同被更新列作为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;
    表已更改。

 

二、创建步骤
 
1、创建物理standby
 
    最方便的创建逻辑standby 的方式就是先创建一个物理standby,然后再将其转换成逻辑standby,因此第一步就是先创建一个物理standby。注意,在将其转换为逻辑standby 前,可以随时启动和应用redo,但是如果你决定将其转换为逻辑standby,就必须先停止该物理standby 的redo 应用,以避免提前应用含
LogMiner 字典的redo 数据,造成转换为逻辑standby 后,sql 应用时logMiner 字典数据不足而影响到逻辑standby 与primary 的正常同步。
 
2、设置primary 数据库
 
    在前面创建standby 时我们曾经设置过无数个初始化参数用于primary 与物理standby 的角色切换,我想说的是,对于逻辑standby 的角色切换,那些参数同样好使。
    不过注意,如果希望primary 数据库能够正常切换为逻辑standby 角色的话,那么你还需要设置相应的log_archive_dest_N,并且valid_for 属性,需要更改成:(STANDBY_LOGFILES,STANDBY_ROLE)。
 
    然后需要生成LogMiner 字典信息,通过执行下列语句生成(务必执行):

    SQL> EXECUTE DBMS_LOGSTDBY.BUILD;

 
    该过程专门用于生成记录的元数据信息到redo log,这样改动才会被传输到逻辑standby,然后才会被逻辑standby 进行SQL 应用。

    提示:
    ¤ 该过程会自动启用primary 数据库的补充日志(supplemental logging)功能(如果未启用的话)。
    ¤ 该过程执行需要等待当前所有事务完成,因此如果当前有较长的事务运行,可能该过程执行也需要多花一些等待时间。
    ¤ 该过程是通过闪回查询的方式来获取数据字典的一致性, 因此oracle 初始化参数UNDO_RETENTION 值需要设置的足够大。

 
3、转换物理standby 为逻辑standby

    执行下列语句,转换物理standby 为逻辑standby:

    SQL> alter database recover to logical standby NEW_DBNAME;

 
    关于db_name(注意哟,这可不是db_unique_name,不同于物理standby,逻辑standby 是一个全新的数据库,因此建议你指定一个唯一的,与primary 不同的数据库名),如果当前使用spfile,则数据库会自动修改其中的相关信息,如果使用的pfile,在下次执行shutdown 的时候oracle 会提示你去修改db_name 初始化参数的值。

    提示:执行该语句前务必确保已经暂停了redo 应用,另外转换是单向的,即只能由物理standby 向逻辑standby 转换,而不能由逻辑standby 转成物理standby。这并不仅仅是因为dbname 发生了修改,更主要的原因是逻辑standby 仅是数据与primary 一致,其它如存储结构,scn 等基于dbid 都不一相同。

 
    另外,该语句执行过程中,需要应用全部的LogMiner 字典相关的redo 数据。这部分操作完全依赖于primary 数据库DBMS_LOGSTDBY.BUILD 的执行以及传输到standby 后有多少数据需要被应用。如果primary 数据库执行DBMS_LOGSTDBY.BUILD 失败,则转换操作也不会有结果,这时候你恐怕不得不先cancel 掉它,解决primary 数据库的问题之后再尝试执行转换。
 
4、重建逻辑standby 的密码文件

    主要是由于转换操作修改了数据库名,因此密码文件也需要重建,这个操作我们做的比较多,这里就不详述了。
 
5、调整逻辑standby 初始化参数
 
    之所以要调整初始化参数,一方面是由于此处我们的逻辑standby 是从物理standby 转换来的,某些参数并不适合甚至可能造成错误,比如log_archive_dest_n 参数的设置。另一方面,由于逻辑standby 会有读写操作,因此需要读写本地online redologs 及并产生archivelogs,务必需要注意本地的archivelogs 路径不要与应用接收自primary 数据库的redo 数据生成的archivelogs 路径冲突。当然归根结底是因为逻辑standby是从物理standby 转换而来,因此standby 的初始化参数就需要第二次调整(第一次是创建物理standby),这里为什么要选择从物理standby 转换呢?很简单,因为前面测试过程中创建了两个standby,所以我觉着直接转换一个当成逻辑standby,操作更省事儿:)
    当然我相信,看完这个系列,如果你对于创建的流程能够非常清晰,完全可以跳过先创建物理standby的过程,直接创建逻辑standby。
    关于修改初始化参数的方式有多种,通过alter system set 也可以,或者先生成pfile 修改相关参数,然后再根据修改过的pfile 生成spfile 也可以。
 
6、打开逻辑standby
 
    由于逻辑standby 与primary 数据库事务并不一致,因此第一次打开时必须指定resetlogs 选择,如下:

    SQL> alter database open resetlogs;

 
    然后可以通过执行下列sql 命令应用redo 数据:

    SQL> alter database start logical standby apply immediate;

 
    如果想停止逻辑standby 的sql 应用,可以通过下列命令:

    SQL> alter database stop logical standby apply immediate;

 
 
posted on 2009-02-23 23:15 decode360 阅读(109) 评论(0)  编辑  收藏 所属分类: 10.DB_Tools

只有注册用户登录后才能发表评论。


网站导航: