Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1117006
  • 博文数量: 231
  • 博客积分: 2500
  • 博客等级: 少校
  • 技术积分: 2662
  • 用 户 组: 普通用户
  • 注册时间: 2009-11-03 16:35
个人简介

学无止境

文章分类

全部博文(231)

文章存档

2014年(7)

2013年(103)

2011年(11)

2010年(53)

2009年(57)

分类: Oracle

2011-03-25 17:12:42

一张表上没有主键,但是也可以启用主键字段的追加日志,但是用的是所有字段内容,作为一行标识。
在streams复制中,如果启动了主键追加日志,在通常情况下,DML变化是可以复制。
在streams通常如果没有主键字段或唯一键字段的话,需要指定替代键字段。
如果表上有重复行,默认apply是不允许多行的,会报ORA-01403: no data found的错误。

在10gR2中,streams提供了一个参数,允许生效多行,ALLOW_DUPLICATE_ROWS。默认该参数是N,可以使用以下过程设置为Y,使之可以生效多行。

BEGIN
DBMS_APPLY_ADM.SET_PARAMETER (
apply_name    =>'stm1_apply',
parameter     =>'allow_duplicate_rows',
value         =>'Y');
END;
/


查询DBA_LOGSTDBY_NOT_UNIQUE视图可以看到哪些表没有唯一键。用了以下3种环境:
为了能够观察到追加日志在redo中加了哪些内容,用logminer挖掘redo日志,查看其中的sql_redo内容。
1.无主键,但使用alter table语句的add SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS子句启用了追加日志。
2.有主键,也使用alter table语句的add SUPPLEMENTAL LOG DATA (PRIMARY KEY) COLUMNS子句启用了追加日志。
3.无主键,没有启用追加日志。


语句都是相同的语句:
update eagle.test01 set id=1 where id=4;

主键字段是ID

条件1中,查看到sql_redo为:
update "EAGLE"."TEST01" set "ID" = '4' where "ID" = '1' and "NAME" = 'dgg' and ROWID = 'AAADz0AAOAAAABuAAA';
条件2中,查看到sql_redo为:
update "EAGLE"."TEST01" set "ID" = '4' where "ID" = '1' and ROWID = 'AAADz0AAOAAAABuAAA';
条件3中,查看到sql_redo为:
update "EAGLE"."TEST01" set "ID" = '4' where "ID" = '1' and ROWID = 'AAADz0AAOAAAABuAAA';

可以看到,启用了主键追加日志的情况下,如果没有主键,redo log中的语句条件中,除了id字段,还有该表的另一个字段name,用来标识该行。
如果有主键,条件中只有主键字段ID。
在没有启用追加日志,也没有主键的情况,sql语句中where条件,也只有一个字段ID。这种情况下,streams是无法复制DML变化的,目标数据库上的apply进程会报错abort。


所以,在streams环境中,需要复制的表,最好有主键字段,或唯一键字段,如果没有,最好能指定一个替代键。
如果表中无法避免有重复行,那么只有10gR2的streams环境允许该表进行streams复制,并且apply参数allow_duplicate_rows需要设置为Y。

 

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