用EXP、IMP迁移包含物化视图日志的数据

 

   2014-1-15日修改下面文章:物化视图日志的迁移由于不能更改创建物化日志的用户名,所以导致不是同名的用户入库会失效,这是oracle的bug,如果非要不同名用户下使用,可以使用以下语句建立新的内部触发器:

exec dbms_snapshot_utl.sync_up_log(‘ring’,’T_USERINFO’);

select * from dba_internal_triggers where table_name=’T_USERINFO’and  Owner_name=’RING’;


  这个问题给我最大感触:迁移数据库的时候,要保持新库和老库都一样,包含全局名,sid,用户名等,这样就不会出现乱七八糟的问题,这也是比较傻瓜的迁移方式。

 

 

 

今天在测试环境中,原来正常快速刷新的物化视图不能同步数据了,最后发现是因为在同一个库做exp、imp操作后使得物化视图日志失效了,不记录基表的数据变化了。
在解决问题的过程中发现了其他一些问题,这里一并记录。

 

 

源库:a@TEST1> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE 9.2.0.1.0 Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production

--在源库创建用户sys@TEST1> create user a identified by a default tablespace suk;

用户已创建。

sys@TEST1> create user b identified by b default tablespace suk;

用户已创建。

sys@TEST1> grant connect,resource,create materialized view to a;

授权成功。

sys@TEST1> grant connect,resource,create materialized view to b;

授权成功。

sys@TEST1> conn a/a@suk
已连接。a@TEST1> create table t(a int primary key);

表已创建。

a@TEST1> create materialized view log on t;

实体化视图日志已创建。

a@TEST1> insert into t values(1);

已创建 1 行。

a@TEST1> commit;

提交完成。

a@TEST1> select * from mlog$_t;

A SNAPTIME$$ D O CHANGE_VECTOR$$
---------- -------------- - - ------------------------
1 01-1月 -00 I N FE


其他库:
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
PL/SQL Release 9.2.0.4.0 - Production
CORE 9.2.0.3.0 Production
TNS for Linux: Version 9.2.0.4.0 - Production
NLSRTL Version 9.2.0.4.0 - Production

 

--在其他库创建用户
SQL> create user suk identified by suk default tablespace suk;

User created.

SQL> create user a identified by a default tablespace suk;

User created.

SQL> grant connect,resource,create materialized view to suk;

Grant succeeded.

SQL> grant connect,resource,create materialized view to a;

Grant succeeded.


1、导入同一个库中的另一个用户
E:oracleora92bin>imp 
b/b@suk file=e:a.dmp fromuser=a touser=b log=e:b.log

Import: Release 9.2.0.1.0 - Production on 星期二 10月 30 13:46:10 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.


连接到: Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production

经由常规路径导出由EXPORT:V09.02.00创建的文件

警告: 此对象由 A 导出, 而不是当前用户

已经完成ZHS16GBK字符集和AL16UTF16 NCHAR 字符集中的导入
. . 正在导入表 "MLOG$_T" 1行被导入
. . 正在导入表 "T" 1行被导入
IMP-00015: 由于对象已存在,下列语句失败:
"CREATE SNAPSHOT LOG ON "A"."T" WITH PRIMARY KEY EXCLUDING NEW VALUES USING "
"("MLOG$_T", (5, 'TEST1.COM', 98, '2007-10-30:13:43:30', '2007-10-30:13:43:3"
"0', '2007-10-30:13:43:30', '4000-01-01:00:00:00', '4000-01-01:00:00:00', 1,"
" "A", '2007-10-30:13:43:30', 2, 0, ("RUPD$_T")))"
成功终止导入,但出现警告。

导入失败,从log看原因很清楚:虽然是要导入到其他用户下,但创建物化视图日志时仍然尝试在原来的用户下创建,结果当然是失败的。
这个还不是最主要的,最严重的是这样导致了原来的物化视图日志失效。

a@TEST1> col CHANGE_VECTOR$$ format a30a@TEST1> select * from mlog$_t;

A SNAPTIME$$ D O CHANGE_VECTOR$$
---------- -------------- - - ------------------------------
1 01-1月 -00 I N FE

a@TEST1> insert into t values(2);

已创建 1 行。

a@TEST1> select * from mlog$_t;

A SNAPTIME$$ D O CHANGE_VECTOR$$
---------- -------------- - - ------------------------------
1 01-1月 -00 I N FE

从上面看到,物化视图日志已经不能记录基表的数据变化,所有基于这个表的快速刷新的物化视图将不能快速刷新(刷新时不会报错,但是数据修改的数据同步不过去)。
此时的解决方式是,重建原来用户的物化视图日志,然后对引用到这些表的物化视图做一次完全刷新。

2、导入其他库中的其他用户
[oracle@datasrv1 dmp]$ imp suk/suk file=a.dmp fromuser=a touser=suk log=imp_suk.log

Import: Release 9.2.0.4.0 - Production on 星期二 10月 30 13:16:04 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.


Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production

Export file created by EXPORT:V09.02.00 via conventional path

Warning: the objects were exported by A, not by you

import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. . importing table "MLOG$_T" 1 rows imported
. . importing table "T" 1 rows imported
IMP-00017: following statement failed with ORACLE error 942:
"BEGIN SYS.DBMS_SNAPSHOT_UTL.SYNC_UP_LOG('A','T'); END;"
IMP-00003: ORACLE error 942 encountered
ORA-00942: table or view does not exist
ORA-06512: at "SYS.DBMS_SNAPSHOT_UTL", line 1589
ORA-06512: at line 1
"CREATE SNAPSHOT LOG ON "A"."T" WITH PRIMARY KEY EXCLUDING NEW VALUES USING "
"("MLOG$_T", (5, 'TEST1.COM', 98, '2007-10-30:13:43:30', '2007-10-30:13:43:3"
"0', '2007-10-30:13:43:30', '4000-01-01:00:00:00', '4000-01-01:00:00:00', 1,"
" "A", '2007-10-30:13:43:30', 2, 0, ("RUPD$_T")))"
IMP-00003: ORACLE error 1435 encountered
ORA-01435: user does not exist
IMP-00000: Import terminated unsuccessfully

导入失败,原因和上面所述一样。
SQL> conn suk/suk
Connected.

SQL> select * from tab;

TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
MLOG$_T TABLE
RUPD$_T TABLE
T TABLE

oracle在导入的时候是先创建物化视图日志表,然后再创建物化视图日志的。在这里,物化视图日志表虽然创建成功了,但是物化视图日志不能创建成功,此时这系列MOG$_、RUPD$_没有任何作用。
这种情况下,如果需要在T上记录物化视图日志,则在删除对应的MLOG$和RUPD$表后重建物化视图日志。
如果有必要,你还需要在其他库上重建指向这些表的物化视图。

3、导入其他库中的相同用户
[oracle@datasrv1 dmp]$ imp a/a file=a.dmp fromuser=a touser=a log=imp_a.log

Import: Release 9.2.0.4.0 - Production on 星期二 10月 30 13:53:14 2007

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.


Connected to: Oracle9i Enterprise Edition Release 9.2.0.4.0 - 64bit Production
With the Partitioning option
JServer Release 9.2.0.4.0 - Production

Export file created by EXPORT:V09.02.00 via conventional path
import done in ZHS16GBK character set and AL16UTF16 NCHAR character set
. . importing table "MLOG$_T" 1 rows imported
. . importing table "T" 1 rows imported
Import terminated successfully without warnings.

从导入信息看,完全没有错误,且物化视图日志仍然有效。

SQL> select * from mlog$_t;

A SNAPTIME$$ D O CHANGE_VECTOR$$
---------- ---------- - - ------------------------------
1 01-1月 -00 I N FE

SQL> insert into t values(10);

1 row created.

SQL> select * from mlog$_t;

A SNAPTIME$$ D O CHANGE_VECTOR$$
---------- ---------- - - ------------------------------
1 01-1月 -00 I N FE
10 01-1月 -00 I N FE

从这个测试看,物化视图日志也可以反应基表数据的变化,那么基于这个表的物化视图也可以快速刷新。


对于这个问题,Utilities的import章节有如下解释:

Importing a Snapshot into a Different Schema
Snapshots, snapshot logs, and related items are exported with the schema name explicitly given in the DDL statements; therefore, snapshots and their related items cannot be imported into a different schema.

If you attempt to use FROMUSER and TOUSER to import snapshot data, an error will be written to the Import log file and the items will not be imported.

但是为何在把含有物化视图日志的表导入到同一个库的另一个用户后,会使物化视图日志失效的问题这里仍然没有解释。

结论:
1、含有物化视图日志的表导入到同一个库的另一个用户后,原来用户下物化视图日志会失效;新用户的物化视图日志不能成功导入。
2、含有物化视图日志的表导入到另一个库的另一个用户后,原来用户下的物化视图日志不受影响;物化视图日志不能成功导入到新数据库中。
3、含有物化视图日志的表导入到另一个库的同一个用户后,原来用户下的物化视图日志不受影响;物化视图日志可以成功导入到新数据库中并正常工作。

猜你喜欢

转载自churuozhiye-java.iteye.com/blog/1910069