junsansi的博客
自我介绍
切换风格
订阅我的Blog
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
网站链接...
资源
===========================================================
一步一步学DataGuard(18)逻辑standby之高级管理3
===========================================================

连载第18篇

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

一步一步学DataGuard(17)逻辑standby之高级管理2

一步一步学DataGuard(16)逻辑standby之高级管理1

一步一步学DataGuard(15)逻辑standby之failover

一步一步学DataGuard(14)逻辑standby之switchover

一步一步学DataGuard(13)逻辑standby之创建示例

一步一步学DataGuard(12)逻辑standby之创建步骤

一步一步学DataGuard(11)逻辑standby之准备创建

一步一步学DataGuard(10)物理standby之高级管理3

一步一步学DataGuard(9)物理standby之高级管理2

一步一步学DataGuard(8)物理standby之高级管理1

一步一步学DataGuard(7)物理standby之failover

一步一步学DataGuard(6)物理standby之switchover

一步一步学DataGuard(5)物理standby之创建示例

一步一步学DataGuard(4)物理standby之创建步骤(2)

一步一步学DataGuard(3)物理standby之创建步骤(1)

一步一步学DataGuard(2)基础之术语再了解大概

一步一步学DataGuard(1)基础之名词先混个脸熟


修改逻辑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开头的表都同步一下,不然有可能会造成数据丢失的哟。

junsansi 发表于:2008.03.31 12:45 ::分类: ( 三思笔记 ) ::阅读:(97次) :: 评论 (0) :: 引用 (0)

发表评论
标题

在此添加评论

称呼

邮箱地址(可选)

个人主页(可选)

authimage