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

全部博文(350)

文章存档

2013年(350)

分类: Oracle

2013-04-25 10:04:50

修改逻辑standby端数据

我们前面提到,逻辑standby一个极具实用价值的特性即是可以边查询边应用,因此将其做为报表服务器专供查询是个很不错的想法,而且逻辑standby相对于物理standby而言更具灵活性,比如我们可以在逻辑standby上,对一些表创建primary库上并不方便创建的索引,约束,甚至可以做dml,ddl操作(当然,需要注意不要破坏了与primary之间同步的逻辑关系)。不过由于此时dg仍然控制着对逻辑standby表的读写操作,因此,如果你想对逻辑standby中的数据做些什么的话,alter session database disable|enable guard语句就必须牢记在心了,它拥有像“芝麻开门”一样神奇的能力,不信?下面我们就来感受一下吧。

1、逻辑standby端执行ddl

在逻辑standby端开始了redo应用的情况下,执行ddl操作:

JSSLDG2> create table tmp55 as select * From b;

create table tmp55 as select * From b

                                    *

第 1 行出现错误:

ORA-01031: 权限不足

看看,出错了吧~~~

JSSLDG2> alter session disable guard;

会话已更改。

JSSLDG2> create table tmp55 as select * From b;

表已创建。

只有关闭了guard保护之后,才能操作数据,然后别忘了再启用guard,以避免不经意的操作对逻辑standby的配置造成影响。

JSSLDG2> alter session enable guard;

会话已更改。

提示:建议还是尽可能不要在逻辑standby执行执行dml之类操作,以免破解其与primary之间同步的逻辑关系,当然,这只是个建议,如果你已经仔细看完了3.1章,并且对表结构及存储结构了如指掌,那您就爱干嘛爱嘛。

2、取消对象同步

如果说,某些表或者数据不需要保护(比如一些在逻辑standby端生成的统计表),这个时候就需要DBMS_LOGSTDBY.SKIP,前头已经介绍过了dbms_logstdby.skip的基本用法,下面我们来具体演示一下!

下面我们假设standby端有一批表名为tmp开头的表,这张表不再需要保持与primary的同步,那么按照步骤执行下列语句,应用即可跳过这些表:

老规矩,先停了redo应用

JSSLDG2> alter database stop logical standby apply;

数据库已更改。

JSSLDG2> execute dbms_logstdby.skip('SCHEMA_DDL','JSS','TMP%');

--跳过对象的ddl操作

PL/SQL 过程已成功完成。

JSSLDG2> execute dbms_logstdby.skip('DML','JSS','TMP%');

--跳过对象的dml操作

PL/SQL 过程已成功完成。

JSSLDG2> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;

数据库已更改。

注意其中的%,该符号为通配符,作用与在sql语句中的相同。

OK,下面来测试一下,先看看逻辑standby中表的信息,我们选择两张表,一张是我们前面已经指定了跳过的表tmp1,另一张是普通表b:

JSSLDG2> select max(aa) from jss.tmp1;

Max(aa)

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

h

JSSLDG2> select max(id) from jss.b;

        Max(id)

----------

         9

JSSLDG2> select sequence#,applied from dba_logstdby_log;

 SEQUENCE# APPLIED

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

       872 YES

然后在primary数据库执行插入操作

JSSWEB> select max(aa) from jss.tmp1;

Max(aa)

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

h

JSSWEB> insert into jss.tmp1 values ('i');

已创建 1 行。

JSSWEB> insert into jss.b values (10);

已创建 1 行。

JSSWEB> commit;

提交完成。

JSSWEB> alter system switch logfile;

系统已更改。

JSSWEB> select max(sequence#) from v$archived_log;

MAX(SEQUENCE#)

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

           873

再来看看逻辑standby端的同步情况:

JSSLDG2> select sequence#,applied from dba_logstdby_log;

 SEQUENCE# APPLIED

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

       873 YES

显然日志已经接收,再看看数据:

JSSLDG2> select max(id) from b;

        Max(id)

----------

        10

JSSLDG2> select max(aa) from jss.tmp1;

Max(aa)

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

h

b表已应用,而tmp1表则无变化。

3、恢复对象同步

如果说某些表某个时候取消了同步,现在希望再恢复同步,没问题,DBMS_LOGSTDBY家大业大,它还有个叫UNSKIP的门生就是专干这个的。

我们来看一下dbms_logstdby.unskip的语法:

DBMS_LOGSTDBY.UNSKIP (

     stmt                      IN VARCHAR2,

     schema_name               IN VARCHAR2,

     object_name               IN VARCHAR2);

三项均为必选参数,各参数的定义与skip过程相同,这里不再复述。

此处我们来演示恢复tmp%表的同步。

JSSLDG2> select *from dba_logstdby_skip;

ERROR STATEMENT_OPT   OWNER      NAME            U E PROC

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

N     SCHEMA_DDL      JSS        TMP%            Y

N     DML             JSS        TMP%            Y

N     DML             JSS        TMP1            Y

........

JSSLDG2> alter database stop logical standby apply;

数据库已更改。

JSSLDG2> execute dbms_logstdby.unskip('DML','JSS','TMP1');

--本步操作是为解决历史遗留问题,不用关注

PL/SQL 过程已成功完成。

JSSLDG2> execute dbms_logstdby.unskip('DML','JSS','TMP%');

PL/SQL 过程已成功完成。

JSSLDG2> execute dbms_logstdby.unskip('SCHEMA_DDL','JSS','TMP%');

PL/SQL 过程已成功完成。

跳过同步已经取消了,紧接着我们需要再调用dbms_logstdby.instantiate_table过程重新同步一下跳地的对象,将skip这段时间,primary对tmp1表所做的操作同步过来(就俺看来,instantiate_table过程实际上是借助dblink重建了一遍对象),以保持与primary的一致。Dbms_logstdby.instantiate_table的语法如下:

DBMS_LOGSTDBY.INSTANTIATE_TABLE (

     schema_name         IN VARCHAR2,

     table_name          IN VARCHAR2,

     dblink              IN VARCHAR2);

使用DBMS_LOGSTDBY.INSTANTIATE_TABLE过程重新执行一下同步(执行前别忘了暂停redo应用):

JSSLDG2> EXECUTE DBMS_LOGSTDBY.INSTANTIATE_TABLE('JSS','TMP1','GETJSSWEB');

PL/SQL 过程已成功完成。

JSSLDG2> select *from jss.tmp1;

AA

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

a

b

c

d

e

f

g

h

i

已选择9行。

数据已重建,下面测试一下该表的redo应用是否恢复了。

JSSWEB> insert into jss.tmp1 values ('j');

已创建 1 行。

JSSWEB> insert into jss.tmp1 values ('k');

 

字数受限,详细请查看:

一步一步学DataGuard(18)逻辑standby之高级管理3全文

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