你好,游客 登录 注册 搜索
背景:
阅读新闻

Oracle DG 修改逻辑Standby端数据

[日期:2013-08-16] 来源:Linux社区  作者:Oracle之路 [字体: ]

4、逻辑Standby端修改数据


逻辑Standby的一个极具实用价值的特性就是可以边查询边应用,因此将其作为报表服务器专供查询是个很不错的想法,而且逻辑Standby相对于物理Standby而言更具灵活性,如我们可以在逻辑Standby上,对一些表创建Primary数据库并不方便创建的索引、约束,甚至可以做DML/DDL操作(当然,需要注意不要破坏了与Primary数据库之间同步的逻辑关系)。


不过由于此时Data Guard仍然控制着对逻辑Standby数据库中表的读写操作,因此,如果你想对逻辑Standby中的数据做些什么的话,ALTER SESSION DISABLE|ENABLE GUARD语句就必须牢记在心了,它拥有像"芝麻开门"一样神奇的能力。 下面我们就来感受一下吧。


在逻辑Standby端启动SQL应用的情况下,执行DDL操作:


SQL> GRANT DBA TO SCOTT;


Grant succeeded.


SQL> CONN SCOTT/TIGER;


Connected.


SQL> CREATE TABLE DAVE AS SELECT * FROM USER_OBJECTS;


CREATE TABLE DAVE AS SELECT * FROM USER_OBJECTS


*


ERROR at line 1:


ORA-01031: insufficient privileges


出错了,提示权限不足,实际上SCOTT被授予了DBA角色,肯定拥有CREATE TABLE权限的,因此此处与用户的权限无关,而是有其他因素制约了SCOTT无法进行修改。


下面禁用Data Guard保护之后,再次尝试操作数据:


SQL> ALTER SESSION DISABLE GUARD;


Session altered.


SQL> CREATE TABLE DAVE AS SELECT * FROM USER_OBJECTS;


Table created.


这下可以了,这就是Data Guard的作用。


注 意: 数据修改完之后,别忘了再次启用Data Guard,以避免不经意的误操作对逻辑Standby的配置造成影响(你说不手动启用Data Guard保护,直接退出行不行,当然也可以,ALTER SESSION所做修改仅对当前会话有效,退出重新登录,原会话设置自然就失效了)。


SQL> ALTER SESSION ENABLE GUARD;


Session altered.


按照Oracle的建议,还是尽可能不要在逻辑Standby端执行DML之类操作,以免破解其与Primary之间同步的逻辑关系,


也可以通过下列语句查看当前数据库是否处于Data Guard保护状态:


SQL> SELECT GUARD_STATUS FROM V$DATABASE;


GUARD_S


-------


ALL


该参数对应三个值:


ALL:表示对数据库中所有对象启动修改保护,除SYS用户外,其他用户均不能直接修改数据。


STANDBY:表示对处于逻辑Standby维护关系的对象启动修改保护,除SYS用户外,其他用户均不能直接修改数据。


NONE:不启动数据保护。


如果要永久设置数据库的Data Guard保护模式,则是通过ALTER DATABASE命令来完成,可指定的值也正是上述的三种,例如:


SQL> ALTER DATABASE GUARD STANDBY;


Database altered.


执行完上述语句后,Data Guard仅对处于逻辑Standby维护关系的对象进行防止修改操作的保护。


考虑到逻辑Standby中也有可能对数据进行修改(正如上例演示),因此这里引申谈一谈在逻辑Standby数据库中,约束和触发器的执行模式。默认情况下,约束和触发器都能在逻辑Standby端正常运行。约束和触发器在逻辑Standby端的执行可以分成两种情况:


对于SQL应用维护的约束和触发器,由于在Primary数据库已经检查过约束,因此Standby端不需要再次检查;触发器的情况也是这样,Primary端操作时结果已经被记录,因此逻辑Standby端将直接被应用,而不会二次触发。


对于没有SQL应用维护的约束和触发器,其执行情况与普通的Oracle数据库环境相同。

 


5、重定义REDO应用执行的操作


对于逻辑Standby数据库,你甚至可以通过编写自定义的PROCEDURE,来重新定义SQL应用时执行的操作。


如逻辑Standby数据库的文件路径与Primary数据库路径不同,如果是物理Standby,可以通过*_FILE_NAME_CONVERT之类的参数处理,在逻辑Standby环境中这几个参数无效,应该如何处理呢?答案就是通过编写自定义的过程,修改SQL应用时执行的操作。


下面通过示例,演示通过编写自定义的PROCEDURE,修改创建表空间时逻辑Standby端数据文件的路径。


首先当然是创建一个过程,建议创建在SYS下,因为在这个用户下的操作肯定不会有同步的问题,如下所示:


SQL> CREATE OR REPLACE PROCEDURE SYS.HANDLE_TBS_DDL (


2 OLD_STMT IN VARCHAR2,


3 STMT_TYP IN VARCHAR2,


4 SCHEMA IN VARCHAR2,


5 NAME IN VARCHAR2,


6 XIDUSN IN NUMBER,


7 XIDSLT IN NUMBER,


8 XIDSQN IN NUMBER,


9 ACTION OUT NUMBER,


10 NEW_STMT OUT VARCHAR2


11 ) AS


12 BEGIN


13


14 NEW_STMT := REPLACE(OLD_STMT, '/u01/oradata/orcl_pd/', '/u01/oradata/orcl_st');


15 ACTION := DBMS_LOGSTDBY.SKIP_ACTION_REPLACE;


16


17 EXCEPTION


18 WHEN OTHERS THEN


19 ACTION := DBMS_LOGSTDBY.SKIP_ACTION_ERROR;


20 NEW_STMT := NULL;


21 END HANDLE_TBS_DDL;


22 /


Procedure created.


逻辑非常简单,基本上就是一个REPLACE,不过PROCEDURE中声明的变量看起来很多,这个是固定格式,不建议修改。


停止逻辑Standby的SQL应用:


SQL> ALTER DATABASE STOP LOGICAL STANDBY APPLY;


Database altered.


如果不停,PROCEDURE不能生效。


执行DBMS_LOGSTDBY.SKIP过程,将编写的过程注册到表空间处理的SQL应用中:


SQL> EXEC DBMS_LOGSTDBY.SKIP (stmt => 'TABLESPACE',proc_name => 'sys.handle_tbs_ddl');


PL/SQL procedure successfully completed.


这里也要借助DBMS_LOGSTDBY.SKIP过程实现。该过程功能非常强大,而且操作非常灵活。


重启SQL应用:


SQL> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;


Database altered.


测试一下,在Primary端创建一个新的表空间:


SQL> CREATE TABLESPACE BOOKS DATAFILE '/u01/oradata/orcl_pd/books01.dbf' SIZE 20m;


Tablespace created.


SQL> SELECT FILE_NAME FROM DBA_DATA_FILES WHERE TABLESPACE_NAME='BOOKS';


FILE_NAME


-----------------------------------------------------------------------------


/u01/oradata/orcl_pd/books01.dbf


转向逻辑Standby数据库查看:


SQL> SELECT FILE_NAME FROM DBA_DATA_FILES WHERE TABLESPACE_NAME='BOOKS';


FILE_NAME


----------------------------------------------------------------------------


/u01/oradata/orcl_st/books01.dbf


表空间成功创建,并且数据文件路径也被转换为我们指定的路径。


此时如果你查看Alert日志文件,会发现其中记录下了类似这样的信息:


LOGSTDBY stmt: create tablespace books datafile '/u01/oradata/orcl_pd/books01.dbf' size 20m


LOGSTDBY status: ORA-16110: 逻辑备用应用 DDL 的用户过程处理


LOGSTDBY id: XID 0x0001.009.000000d1, hSCN 0x0000.0012ec41,


lSCN 0x0000.0012ec41, Thread 1, RBA 0x007f.0000079a.80,


txnCscn 0x0000.0012ec43, PID 5816, ORACLE.EXE (P004)


LOGSTDBY stmt: create tablespace books datafile '/u01/oradata/orcl_st/books01.dbf' size 20m


LOGSTDBY status: ORA-16202: 跳过过程已请求替换语句


LOGSTDBY id: XID 0x0001.009.000000d1, hSCN 0x0000.0012ec41,


lSCN 0x0000.0012ec41, Thread 1, RBA 0x007f.0000079a.80,


txnCscn 0x0000.0012ec43, PID 5816, ORACLE.EXE (P004)


create tablespace books datafile '/u01/oradata/orcl_st/books01.dbf' size 20m


Completed: create tablespace books datafile '/u01/oradata/orcl_st/books01.dbf' size 20m


LOGSTDBY stmt: create tablespace books datafile '/u01/oradata/orcl_st/books01.dbf' size 20m


LOGSTDBY status: ORA-16204: 成功应用了 DDL

更多Oracle相关信息见Oracle 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=12

linux
相关资讯       Oracle standby  Oracle DG 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款