学无止境
分类: 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。