ITPub博客

首页 > 数据库 > 数据库开发技术 > ORACLE10G 物理standby转为逻辑standby

ORACLE10G 物理standby转为逻辑standby

数据库开发技术 作者:下一站在哪 时间:2014-06-10 15:32:54 0 删除 编辑

  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/29661313/viewspace-1179688/ ,如需转载,请注明出处,否则将追究法律责任。

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

注册时间:2014-05-16

  • 博文量
    24
  • 访问量
    43693