ITPub博客

首页 > 数据库 > Oracle > ORACLE10G 物理standby转为逻辑standby

ORACLE10G 物理standby转为逻辑standby

Oracle 作者:lively1982 时间:2014-09-04 18:08:25 0 删除 编辑
本文章参考于:http://www.cnblogs.com/landexia/archive/2012/08/06/2624668.html 和ORACLE10G官方文档
1.配置逻辑Standby 的准备工作
在创建逻辑standby之前,首先检查primary数据库的状态,确保primary数据库已经为创建逻辑standby做好了全部准备工作,比如说是否启动了归档是否启用了forced logging等,这部分可以参考创建物理standby时的准备工作,除此之外呢,由于逻辑standby是通过sql应用来保持与primary数据库的同步,sql应用与redo应用是有很的大区别,redo应用实际上是物理standby端进行recover,sql应用则是分析redo文件将其转换为sql语句在逻辑standby端执行,
1)检查数据库是否有不被逻辑standby支持的对象,如下:

SQL> SELECT * FROM DBA_LOGSTDBY_UNSUPPORTED;

OWNER      TABLE_NAME           COLUMN_NAME          DATA_TYPE            ATTRIBUTES
---------- -------------------- -------------------- -------------------- --------------------
SH         MVIEW$_EXCEPTIONS    BAD_ROWID            ROWID
OE         CUSTOMERS            CUST_ADDRESS         CUST_ADDRESS_TYP
OE         CUSTOMERS            PHONE_NUMBERS        PHONE_LIST_TYP
OE         CUSTOMERS            CUST_GEO_LOCATION    SDO_GEOMETRY
OE         WAREHOUSES           WAREHOUSE_SPEC       XMLTYPE
OE         WAREHOUSES           WH_GEO_LOCATION      SDO_GEOMETRY
PM         ONLINE_MEDIA         PRODUCT_AUDIO        ORDAUDIO
PM         ONLINE_MEDIA         PRODUCT_TESTIMONIALS ORDDOC
PM         ONLINE_MEDIA         PRODUCT_PHOTO        ORDIMAGE
PM         ONLINE_MEDIA         PRODUCT_PHOTO_SIGNATURE ORDIMAGESIGNATURE
PM         ONLINE_MEDIA         PRODUCT_THUMBNAIL    ORDIMAGE
PM         ONLINE_MEDIA         PRODUCT_VIDEO        ORDVIDEO
PM         PRINT_MEDIA          AD_TEXTDOCS_NTAB     TEXTDOC_TAB
PM         PRINT_MEDIA          AD_GRAPHIC           BFILE
PM         PRINT_MEDIA          AD_HEADER            ADHEADER_TYP
OE         CATEGORIES_TAB       CATEGORY_NAME        VARCHAR2             Object Table
OE         CATEGORIES_TAB       CATEGORY_DESCRIPTION VARCHAR2             Object Table
OE         CATEGORIES_TAB       CATEGORY_ID          NUMBER               Object Table
OE         CATEGORIES_TAB       PARENT_CATEGORY_ID   NUMBER               Object Table

19 rows selected.

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

2)维护逻辑standby与primary的数据库同步是通过sql应用实现,SQL应用转换的SQL语句在执行时,对于insert还好说,对于update,delete操作则必须能够唯一定位到数据库待更新的那条记录,问题就在这里,如果primary库中表设置不当,可能就无法确认唯一条件,逻辑standby跟物理standby的区别,就是因为它只是逻辑上与primary数据库相同,物理上可能与primary数据库存在相当大差异,一定要认识到,逻辑standby的物理结构与primary是不相同的(即使初始逻辑standby是通过primary的备份创建),因此想通过rowid更新显然是不好使的,就不能再将其做为唯一条件,可以通过以下的方法来解决:
如何确保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_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database; 
SUP SUP SUPPLEME
--- --- --------
NO  NO  NO

SQL> ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;       
Database altered.
SQL> select SUPPLEMENTAL_LOG_DATA_FK,SUPPLEMENTAL_LOG_DATA_ALL,SUPPLEMENTAL_LOG_DATA_MIN from v$database;

SUP SUP SUPPLEME
--- --- --------
NO  NO  YES

批注:SUPPLEMENTAL_LOG_DATA_MIN=YES和IMPLICIT都表示数据库启动了最小化的补充日志。YES表示通过ALTER DATABASE ADD SUPPLEMENTAL LOG DATA语句启动的最小化补充日志;如果启动了对主键、唯一键、外键、ALL的补充日志,默认情况下都会打开最小化的补充日志,IMPLICIT表示的是通过启动对主键、唯一键、外键或者ALL的支持而打开的最小化补充日志。
因此,Oracle 建议你为表创建一个主键或非空的唯一索引/约束,以尽可能确保sql应用能够有效应用redo数据更新逻辑standby数据库。
3)执行下列语句检查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_COLUMN = 'Y';

OWNER                          TABLE_NAME
------------------------------ ------------------------------
TSMSYS                         SRS$      --这是一张系统表,首先查看该用户是否可以登录,如果是锁定状态,我们就无需设置它

SQL> select username,account_status from dba_users where username like '%TSMSYS%';

USERNAME                       ACCOUNT_STATUS
------------------------------ --------------------------------
TSMSYS                         EXPIRED & LOCKED
批注:DBA_LOGSTDBY_NOT_UNIQUE 该视图显示包含不被支持的数据类型,即既没有主键,也没有唯一索引的表,如果表中的列包括足够多的信息通常也可支持在逻辑standby的更新,不被支持的表通常是由于列的定义包含了不支持的数据类型。
对于BAD_COLUMN 列值有两个:
Y:表示该表中有采用大数据类型的字段,比如LONG,CLOB,如果表中除log列某些行记录完全匹配,则该表无法成功应用于逻辑standby,standby会尝试维护这些表,不过你必须保证应用不允许;

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

4)假设某张表你可以确认数据是唯一的,但是因为效率方面的考虑,不想为其创建主键或唯一约束,怎么办呢,没关系,oracle想到了这一点,你可以创建一个disable的primary-key rely约束:
关于primary-key RELY约束:
如果你能够确认表中的行是唯一的,那么可以为该表创建rely的主键,RELY约束并不会造成系统维护主键的开销,如果你对一个表创建了rely约束,系统则会假定该表中的行是唯一,这样能够提供sql应用时的性能,但是需要注意,由于rely的主键约束只是假定唯一,如果实际并不唯一的话,有可能会造成错误的更新。
创建rely的主键约束非常简单,只要在标准的创建语句后加上RELY DISABLE即可,示例如下:
SQL> ALTER TABLE mytab ADD PRIMARY KEY (id, name) RELY DISABLE;    --表mytab为我要创建rely主键约束的表名

2.创建逻辑standby
为了方便区分当前操作的数据库,设置一下操作符,如下:
SQL> set sqlprompt primary>           --表示primary数据库
SQL> set sqlprompt lgstandby>         --表示standby数据库
1)在物理standby上取消redo apply :
lgstandby>ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
批注:如果决定将其转换为逻辑standby,就必须停止该物理standby的redo应用,以避免提前应用含LogMiner 字典的redo 数据,造成转换为逻辑standby 后,sql 应用时logMiner 字典数据不足而影响到逻辑standby 与primary 的正常同步。
2)设置primary数据库
[oracle@xiaoru app]$ mkdir my_arch2
[oracle@xiaoru app]$ ls
admin  flash_recovery_area  my_arch  my_arch2  oracle  oradata  oraInventory
primary>alter system set LOG_ARCHIVE_DEST_3='LOCATION=/u01/app/my_arch2/ VALID_FOR=(STANDBY_LOGFILES,STANDBY_ROLE)
  2  DB_UNIQUE_NAME=orcl' LOG_ARCHIVE_DEST_STATE_3=ENABLE SCOPE=BOTH ;

System altered.

primary>show parameter LOG_ARCHIVE_DEST_3;

NAME                  TYPE        VALUE
--------------------- ----------- ------------------------------
log_archive_dest_3     string      LOCATION=/u01/app/my_arch2/ VALID_FOR=(STANDBY_LOGFILES,STANLID_FOR=(
                                   STANDBY_LOGFILES,STANDBY_ROLE) DB_UNIQUE_NAME=orcl

执行如下语句,生成LogMiner字典信息:
primary>EXECUTE DBMS_LOGSTDBY.BUILD;

PL/SQL procedure successfully completed.

批注:该过程专门用于生成记录的元数据信息到redo log,这样改动才会被传输到逻辑standby,然后才会被逻辑standby 进行SQL 应用。该过程通过闪回查询的方式来获取数据字典的一致性,因此oracle初始化参数UNDO_RETENTION值需要设置的足够大。
3)转换物理standby为逻辑standby
lgstandby>show parameter db_name;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_name                              string      myorcl

lgstandby>ALTER DATABASE RECOVER TO LOGICAL STANDBY lg_myorcl;
ALTER DATABASE RECOVER TO LOGICAL STANDBY lg_myorcl
*
ERROR at line 1:
ORA-02084: database name is missing a component
ORACLE10G官网查看错误分析,截图如下:


批注:感觉我也没有使用里面不允许的特殊字符啊,不解;
lgstandby>ALTER DATABASE RECOVER TO LOGICAL STANDBY lgmyorcl;      --不让用就不用呗,多简单的事啊,这不是也哦了吗

Database altered.

批注:逻辑standby是一个全新的数据库,如果当前使用spfile,则数据库会自动修改其中的相关信息,如果使用的是pfile,在下次执行shutdown的时候oracle会提示你去修改db_name初始化参数的值。
4)重启standby数据库
lgstandby>shutdown immediate
lgstandby>startup mount;
lgstandby>show parameter db_name;        --查看db_name

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_name                              string      LGMYORCL

lgstandby>select name,database_role,open_mode from v$database;

NAME      DATABASE_ROLE    OPEN_MODE
--------- ---------------- ----------
LGMYORCL  LOGICAL STANDBY  MOUNTED
5)打开逻辑standby
由于逻辑standby与primary数据库事务并不一致,因此第一次打开时必须指定resetlogs选择,如下:
lgstandby>alter database open resetlogs;

Database altered.

然后执行如下SQL语句打开redo应用:
lgstandby>alter database start logical standby apply immediate;

Database altered.

3.验证
1)首先查询主、备库中scott用户下的表,如下:
primary>conn scott/tiger;
Connected.
primary>select * from tab;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
DEPT                           TABLE
EMP                            TABLE
BONUS                          TABLE
SALGRADE                       TABLE

lgstandby>conn scott/tiger;
Connected.
lgstandby>select * from tab;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
DEPT                           TABLE
EMP                            TABLE
BONUS                          TABLE
SALGRADE                       TABLE

2)主库中创建表mydept,并为其添加主键约束,如下
primary>create table mydept as select * from dept;

Table created.

primary>alter table mydept add constraints pk_d primary key (deptno);

Table altered.

primary>select * from tab;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
DEPT                           TABLE
EMP                            TABLE
BONUS                          TABLE
SALGRADE                       TABLE
MYDEPT                         TABLE

primary>select TABLE_NAME,CONSTRAINT_NAME,CONSTRAINT_TYPE from user_constraints where table_name='MYDEPT';

TABLE_NAME                     CONSTRAINT_NAME                C
------------------------------ ------------------------------ -
MYDEPT                         PK_D                           P
primary>conn / as sysdba
Connected.
primary>alter system switch logfile;   --切换日志

System altered.

3)备库查看主库在scott用户下创建的mydept表是否同步
lgstandby>select * from tab;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
DEPT                           TABLE
EMP                            TABLE
BONUS                          TABLE
SALGRADE                       TABLE
MYDEPT                         TABLE

lgstandby>select TABLE_NAME,CONSTRAINT_NAME,CONSTRAINT_TYPE from user_constraints where table_name='MYDEPT';

TABLE_NAME                     CONSTRAINT_NAME                C
------------------------------ ------------------------------ -
MYDEPT                         PK_D                           P

4)主库上对表mydept执行DML语句,示例如下:
primary>conn scott/tiger
Connected.
primary>delete mydept where deptno=10;

1 row deleted.

primary>select * from mydept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        50 ORACLE         JAVA
        60 dayong         xiaoru
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

primary>commit;

Commit complete.

primary>conn / as sysdba;
Connected.
primary>alter system switch logfile;

System altered.

5)备库查询数据是否同步
lgstandby>show user;
USER is "SCOTT"
lgstandby>select * from mydept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        50 ORACLE         JAVA
        60 dayong         xiaoru
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

批注:由查询结果可知,备库已经成功同步,至此,物理standby转为逻辑standby已经完成

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/14288937/viewspace-1264045/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2013-11-27

  • 博文量
    31
  • 访问量
    59135