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

一、 修改逻辑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;

会话已更改。

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

2、 取消对象同步

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

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

老规矩,先停了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');

已创建 1 行。

JSSWEB> commit;

提交完成。

JSSWEB> alter system switch logfile;

系统已更改。

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

MAX(SEQUENCE#)

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

           877

启动逻辑standby端的redo应用,看看对象的应用情况:

JSSLDG2> alter database start logical standby apply immediate;

数据库已更改。

JSSLDG2> select sequence#,applied from dba_logstdby_log;

 SEQUENCE# APPLIED

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

       875 YES

       876 YES

       877 YES

JSSLDG2> select *from jss.tmp1;

AA

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

a

b

c

d

e

f

g

h

i

j

k

已选择11行。

OK,恢复正常啦!

注意哟,此处我们清楚明白的知道我们之前只操作了tmp1一张表,如果是正式应用的话,那你恐怕有必要将所有tmp开头的表都同步一下,不然有可能会造成数据丢失的哟。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值