yangtingkun
===========================================================
减少全库导入时发生的错误(一)
===========================================================

全库导入操作一直是我比较头疼的东西,一般情况下,我会尽量避免这种操作。但是对于有些情况,全库导入又几乎是唯一的选择,比如跨平台的数据库迁移、大版本升级等操作。

其实全库导入操作说起来很简单,令人比较头疼的是,导入过程中几乎不可避免的会出现大量的错误信息,这些错误有的可以忽略,有的可能造成系统的异常,本文试图通过各种方法尽量减少全库导入时错误的数量。

减少全库导入时发生的错误(二):http://yangtingkun.itpub.net/post/468/218119

减少全库导入时发生的错误(三):http://yangtingkun.itpub.net/post/468/219532

减少全库导入时发生的错误(四):http://yangtingkun.itpub.net/post/468/221430

减少全库导入时发生的错误(五):http://yangtingkun.itpub.net/post/468/221839


如果某些表空间不存在的话,全库导入操作会首先尝试创建表空间。所以在全库导入的时候,要么提前建立好所有必须的表空间,要么确保建立表空间的路径是存在的,且oracle用户拥有读写权限。

如果导入数据库采用默认安装的话,那么直接导入会产生什么问题呢:

$ imp "sys as sysdba" file=testmv_full.dmp full=y buffer=20480000 ignore=y log=testmv_full.log

用于大量重复用户存在,会报很多的唯一约束冲突的错误,不但会严重影响导入效率,而且产生包含大量错误信息的日志也会增加排错的难度和工作量。

更严重的是,在低于9205的一些版本中,导入操作会中途失败。具体情况可以参考:http://yangtingkun.itpub.net/post/468/214725

因此,为了避免上面提到的那些错误,尝试将那些会造成冲突的用户清除掉。删除用户列表为:

DROP USER ANONYMOUS CASCADE;
DROP USER OUTLN CASCADE;
DROP USER WMSYS CASCADE;
DROP USER ORDSYS CASCADE;
DROP USER ORDPLUGINS CASCADE;
DROP USER MDSYS CASCADE;
DROP USER CTXSYS CASCADE;
DROP USER XDB CASCADE;
DROP USER WKSYS CASCADE;
DROP USER WKPROXY CASCADE;
DROP USER ODM CASCADE;
DROP USER ODM_MTR CASCADE;
DROP USER OLAPSYS CASCADE;
DROP USER HR CASCADE;
DROP USER OE CASCADE;
DROP USER PM CASCADE;
DROP USER SH CASCADE;
DROP USER QS_ADM CASCADE;
DROP USER QS CASCADE;
DROP USER QS_WS CASCADE;
DROP USER QS_ES CASCADE;
DROP USER QS_OS CASCADE;
DROP USER QS_CBADM CASCADE;
DROP USER QS_CB CASCADE;
DROP USER QS_CS CASCADE;

删除用户后,使用同样的导入命令,错误大大减少。

检查日志文件,其中以IMP-开头的错误有2319个。而以ORA-开头的错误有1113个。其中发现大部分错误为ORA-00001,错误数为972个。都是SYSTEM用户下的表造成的。

于是,尝试在上面的基础上,删除SYSTEM用户下包含数据的表中的数据,重新执行导入操作,删除SYSTEM用户数据脚本如下:

SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_CNT NUMBER := 0;
3 V_DEL NUMBER := 0;
4 V_LOOP NUMBER := 0;
5 V_RESULT NUMBER := 0;
6 BEGIN
7 <<LABLE_FOR_LOOP>>
8 FOR I IN (SELECT TABLE_NAME FROM USER_TABLES) LOOP
9 EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || I.TABLE_NAME INTO V_RESULT;
10 IF V_RESULT != 0 THEN
11 BEGIN
12 V_CNT := V_CNT + 1;
13 EXECUTE IMMEDIATE 'DELETE ' || I.TABLE_NAME;
14 V_DEL := V_DEL + 1;
15 EXCEPTION
16 WHEN OTHERS THEN
17 NULL;
18 END;
19 END IF;
20 END LOOP;
21 V_LOOP := V_LOOP + 1;
22 DBMS_OUTPUT.PUT_LINE(V_LOOP || ':' || ' COUNT ' || V_CNT || ', DEL ' || V_DEL);
23 IF V_CNT != V_DEL THEN
24 V_CNT := 0;
25 V_DEL := 0;
26 GOTO LABLE_FOR_LOOP;
27 END IF;
28 END;
29 /
1: COUNT 10, DEL 10

PL/SQL 过程已成功完成。

SQL> COMMIT;

提交完成。

下面重新执行导入工作。

这次错误信息进一步减少,其中IMP-错误还有375个,ORA-错误还有135个。检查错误信息中发现开始的时候遇到了很多用户不存在的问题。于是尝试删除用户后对象后,重新建立用户。

SQL> DECLARE
2 TYPE T_VARCHAR_TAB IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;
3 V_DROP_STR T_VARCHAR_TAB;
4 V_CREATE_STR T_VARCHAR_TAB;
5 BEGIN
6 SELECT DBMS_METADATA.GET_DDL('USER', USERNAME) BULK COLLECT INTO V_CREATE_STR
7 FROM DBA_USERS
8 WHERE USERNAME NOT IN ('SYS', 'SYSTEM', 'DBSNMP');
9 SELECT 'DROP USER ' || USERNAME || ' CASCADE' BULK COLLECT INTO V_DROP_STR
10 FROM DBA_USERS
11 WHERE USERNAME NOT IN ('SYS', 'SYSTEM', 'DBSNMP');
12 FOR I IN 1..V_DROP_STR.COUNT LOOP
13 EXECUTE IMMEDIATE V_DROP_STR(I);
14 END LOOP;
15 FOR I IN 1..V_CREATE_STR.COUNT LOOP
16 EXECUTE IMMEDIATE V_CREATE_STR(I);
17 END LOOP;
18 END;
19 /

PL/SQL 过程已成功完成。

SQL> SET SERVEROUT ON
SQL> DECLARE
2 V_CNT NUMBER := 0;
3 V_DEL NUMBER := 0;
4 V_LOOP NUMBER := 0;
5 V_RESULT NUMBER := 0;
6 BEGIN
7 <<LABLE_FOR_LOOP>>
8 FOR I IN (SELECT TABLE_NAME FROM USER_TABLES) LOOP
9 EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || I.TABLE_NAME INTO V_RESULT;
10 IF V_RESULT != 0 THEN
11 BEGIN
12 V_CNT := V_CNT + 1;
13 EXECUTE IMMEDIATE 'DELETE ' || I.TABLE_NAME;
14 V_DEL := V_DEL + 1;
15 EXCEPTION
16 WHEN OTHERS THEN
17 NULL;
18 END;
19 END IF;
20 END LOOP;
21 V_LOOP := V_LOOP + 1;
22 DBMS_OUTPUT.PUT_LINE(V_LOOP || ':' || ' COUNT ' || V_CNT || ', DEL ' || V_DEL);
23 IF V_CNT != V_DEL THEN
24 V_CNT := 0;
25 V_DEL := 0;
26 GOTO LABLE_FOR_LOOP;
27 END IF;
28 END;
29 /
1: COUNT 10, DEL 10

PL/SQL 过程已成功完成。

SQL> COMMIT;

提交完成。

下面再次进行导入工作。错误进一步减少。这时IMP-错误还剩351个,ORA-错误还剩85个。

yangtingkun 发表于:2006.10.01 20:06 ::分类: ( ORACLE ) ::阅读:(4555次) :: 评论 (27)
re: 减少全库导入时发生的错误(一) [回复]

请问下,你的错误是怎么看的?
配置oems做备份也会出现这样的问题么?
我配置了oems之后imp/exp不能导入/导出数据了,只能把表导出来,请问搂主遇到过这个问题么?

若山牧水 评论于: 2007.02.27 21:48
re: 减少全库导入时发生的错误(一) [回复]

我的邮箱:four_kings_feline@yahoo.com.cn
qq:287898491可以加我讨论。。。

若山牧水 评论于: 2007.02.27 21:50
re: 减少全库导入时发生的错误(一) [回复]

把你的详细情况去论坛发个帖子吧,这里说不清楚的。

yangtingkun 评论于: 2007.02.28 09:31
re: 减少全库导入时发生的错误(一) [回复]

你好。
我在执行以下代码后:
DROP USER ANONYMOUS CASCADE;
DROP USER OUTLN CASCADE;
DROP USER WMSYS CASCADE;
DROP USER ORDSYS CASCADE;
DROP USER ORDPLUGINS CASCADE;
DROP USER MDSYS CASCADE;
DROP USER CTXSYS CASCADE;
DROP USER XDB CASCADE;
DROP USER WKSYS CASCADE;
DROP USER WKPROXY CASCADE;
DROP USER ODM CASCADE;
DROP USER ODM_MTR CASCADE;
DROP USER OLAPSYS CASCADE;
DROP USER HR CASCADE;
DROP USER OE CASCADE;
DROP USER PM CASCADE;
DROP USER SH CASCADE;
DROP USER QS_ADM CASCADE;
DROP USER QS CASCADE;
DROP USER QS_WS CASCADE;
DROP USER QS_ES CASCADE;
DROP USER QS_OS CASCADE;
DROP USER QS_CBADM CASCADE;
DROP USER QS_CB CASCADE;
DROP USER QS_CS CASCADE;

出错了,原服务器不能再运行了,全部业务出错,说
ORA-18008: cannot find OUTLN schema

但我使用
1)conn / as sysdba

2)create user outln identified outln;

3)grant connect,resource to outln;

4)exec dbms_outln_edit.create_edit_tables();

重新建立用户OUTLN。但不成功,

提示错误:

ORA-00604: error occurred at recursive SQL level 1

ORA-18008: cannot find OUTLN schema
有什么好的办法恢复过去???

TANG 评论于: 2008.01.18 16:49
re: 减少全库导入时发生的错误(一) [回复]

检查数据库版本
而且,确认一下是否使用了OUTLINE的功能。

yangtingkun 评论于: 2008.01.18 21:29
re: 减少全库导入时发生的错误(一) [回复]

版本号: ORACLE 9.2.0.4
应该是使用了OUTLINE的功能。
现在其它业务都不能使用了.
并且有提示此错误.

边城 评论于: 2008.01.19 12:06
re: 减少全库导入时发生的错误(一) [回复]

先禁止OUTLINE的使用。

导入完成后,如果OUTLINE仍然不能正常使用。
可以重新安装OUTLINE

yangtingkun 评论于: 2008.01.20 14:44
re: 减少全库导入时发生的错误(一) [回复]

怎样进行禁止使用和重新安装???
我使用以下方法,但并不成功.
)conn / as sysdba
2)create user outln identified by outln;
3)grant connect,resource to outln;
4)exec dbms_outln_edit.create_edit_tables();
重新建立用户OUTLN。但不成功,
提示错误:
ORA-00604: error occurred at recursive SQ

边城 评论于: 2008.01.21 11:46
re: 减少全库导入时发生的错误(一) [回复]

如果创建用户没有问题,可以考虑执行$ORACLE_HOME/rdbms/admin目录下的三个文件
@@catol.sql
@@dbmsol.sql
@@prvtol.plb

你现在可以先检查一下:create_stored_outlines初始化参数

yangtingkun 评论于: 2008.01.22 15:35
re: 减少全库导入时发生的错误(一) [回复]

如果实在不行的话,可以尝试备份数据库,然后重新执行catalog.sql和catproc.sql

yangtingkun 评论于: 2008.01.22 15:37
re: 减少全库导入时发生的错误(一) [回复]

你好!

现在是运行什么都提示:
ora-00604 : error occurred at recursive SQL level 1
ORA-18008: cannot find OUTLN schema

你说的
“如果实在不行的话,可以尝试备份数据库,然后重新执行catalog.sql和catproc.sql”

使用什么方式备份数据库?
是把DBF 拷贝到另一个地方吗?还是EXP ,EXP 已不能执行。

我不知是否能在SQLPLUS 中执行catalog.sql和catproc.sql。
是否还是会提示那两个错误。
或是有其它办法执行呢?
---------急。请帮忙,测试服务器已停了几天了。

边城 评论于: 2008.01.24 09:59
re: 减少全库导入时发生的错误(一) [回复]

先做个数据库的冷备份吧。
包括所有数据文件、控制文件和日志文件。

检查alert文件,在启动的时候将create_stored_outlines设置为false
如果仍然存在上面的错误,尝试执行上面的三个sql语句。

yangtingkun 评论于: 2008.01.24 13:55
re: 减少全库导入时发生的错误(一) [回复]

你好!
1、检查ALERT 文件?不太明白。
2、设置
是在启动数据库后使用:
alter session set create_stored_outlines=false
设置吗?

因ORACLE 不懂东西太多,还请详细说明。

边城 评论于: 2008.01.24 14:32
re: 减少全库导入时发生的错误(一) [回复]

先检查alert文件,看看数据库启动的时候是否加载了和OUTLINE相关的初始化信息。

如果是,通过手工修改数据库的初始化参赛PFILE来避免使用OUTLINE。

另外,在做一些危险操作之前一定要备份数据库,否则就可能面对现在的这种情况。
现在你再做其他修改之前,也最好备份一下,这样即使无法解决,也不会进一步破坏。

yangtingkun 评论于: 2008.01.24 16:46
re: 减少全库导入时发生的错误(一) [回复]

你也可以尝试使用下面的脚本来重建OUTLN用户:

set serveroutput on

DECLARE
user_exists EXCEPTION;
outln_user number;
outln_tables number;
extra_outln_tables number;
DDL_CURSOR integer;
BEGIN
select count(*) into outln_user from user$ where name='OUTLN';

select count(*) into outln_tables from obj$ where name in
('OL$', 'OL$HINTS','OL$NODES') and owner#=
(select user# from user$ where name='OUTLN');

select count(*) into extra_outln_tables from obj$ where name not in
('OL$', 'OL$HINTS','OL$NODES') and type#=2 and owner#=
(select user# from user$ where name='OUTLN');

DDL_CURSOR := dbms_sql.open_cursor;
IF outln_user = 0 THEN
dbms_sql.parse(DDL_CURSOR, 'create user outln identified by outln',
dbms_sql.native);
dbms_sql.parse(DDL_CURSOR,
'grant connect, resource, execute any procedure to outln',
dbms_sql.native);
dbms_sql.parse(DDL_CURSOR, 'create table outln.ol$ ( '||
'ol_name varchar2(30), ' ||
'sql_text long, ' ||
'textlen number, ' ||
'signature raw(16), ' ||
'hash_value number, ' ||
'hash_value2 number, ' ||
'category varchar2(30), ' ||
'version varchar2(64), ' ||
'creator varchar2(30), ' ||
'timestamp date, ' ||
'flags number, ' ||
'hintcount number, ' ||
'spare1 number, ' ||
'spare2 varchar2(1000))', dbms_sql.native);
dbms_sql.parse(DDL_CURSOR, 'create table outln.ol$hints ( '||
'ol_name varchar2(30), '||
'hint# number, '||
'category varchar2(30), '||
'hint_type number, '||
'hint_text varchar2(512), '||
'stage# number, '||
'node# number, '||
'table_name varchar2(30), '||
'table_tin number, '||
'table_pos number, '||
'ref_id number, '||
'user_table_name varchar2(64), '||
'cost FLOAT(126),'||
'cardinality FLOAT(126),'||
'bytes FLOAT(126),'||
'hint_textoff number, '||
'hint_textlen number,'||
'join_pred varchar2(2000),'||
'spare1 number, '||
'spare2 number)', dbms_sql.native);
dbms_sql.parse(DDL_CURSOR, 'create table outln.ol$nodes ( '||
'ol_name varchar2(30), '||
'category varchar2(30), '||
'node_id number, '||
'parent_id number, '||
'node_type number, '||
'node_textlen number, '||
'node_textoff number)', dbms_sql.native);
dbms_sql.parse(DDL_CURSOR, 'create unique index outln.ol$name '||
'on outln.ol$(ol_name)', dbms_sql.native);
dbms_sql.parse(DDL_CURSOR, 'create unique index outln.ol$signature '||
' on outln.ol$(signature,category)', dbms_sql.native);
dbms_sql.parse(DDL_CURSOR, 'create unique index outln.ol$hnt_num '||
' on outln.ol$hints(ol_name, hint#)', dbms_sql.native);
dbms_output.put_line('OUTLN CREATION SUCCESSFUL');
ELSE
IF outln_tables!=3 or extra_outln_tables!=0 THEN
dbms_output.put_line('ERROR - OUTLN USER ALREADY EXISTS');
RAISE user_exists;
ELSE
dbms_output.put_line('OUTLN CREATION SUCCESSFUL');
END IF;
END IF;

EXCEPTION
WHEN user_exists THEN
RAISE;

END;
/

yangtingkun 评论于: 2008.01.24 17:14
re: 减少全库导入时发生的错误(一) [回复]

你好!

上面代码我前几天在网上找到过,我是这样运行的:

把代码另存为SQL,再用数据库管理员身份登录,
执行代码,但第一个错误就是ORA-18008.
回到问题本身了。我不知是否是我运行方法错误,还是
其它原因。

ERROR at line 1:
ORA-18008: cannot find OUTLN schema
ORA-06512: at "SYS.DBMS_SYS_SQL", line 826
ORA-06512: at "SYS.DBMS_SQL", line 32
ORA-06512: at line 21

边城 评论于: 2008.01.24 17:24
re: 减少全库导入时发生的错误(一) [回复]

你能就此话题再展开说明吗?

"先检查alert文件,看看数据库启动的时候是否加载了和OUTLINE相关的初始化信息。

如果是,通过手工修改数据库的初始化参赛PFILE来避免使用OUTLINE。"

下面是在ALERT.log 文件在出错前后的一段LOG:

Wed Jan 16 14:53:52 2008
Undo Segment 1 Onlined
Undo Segment 2 Onlined
Undo Segment 3 Onlined
Undo Segment 4 Onlined
Undo Segment 5 Onlined
Undo Segment 6 Onlined
Undo Segment 7 Onlined
Undo Segment 8 Onlined
Undo Segment 9 Onlined
Undo Segment 10 Onlined
Successfully onlined Undo Tablespace 1.
Wed Jan 16 14:53:52 2008
SMON: enabling tx recovery
Wed Jan 16 14:53:52 2008
Database Characterset is UTF8
replication_dependency_tracking turned off (no async multimaster replication found)
Completed: ALTER DATABASE OPEN
Wed Jan 16 16:08:45 2008
Thread 1 advanced to log sequence 3870
Current log# 2 seq# 3870 mem# 0: /oracle/u02/oradata/test04/redo02.log
Thu Jan 17 14:48:10 2008
Thread 1 advanced to log sequence 3871
Current log# 3 seq# 3871 mem# 0: /oracle/u02/oradata/test04/redo03.log
Fri Jan 18 15:15:03 2008
Thread 1 advanced to log sequence 3872
Current log# 1 seq# 3872 mem# 0: /oracle/u02/oradata/test04/redo01.log
Fri Jan 18 15:47:58 2008
Errors in file /oracle/u02/admin/test04/udump/test04_ora_18966.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-18008: cannot find OUTLN schema
Fri Jan 18 15:47:58 2008
Errors in file /oracle/u02/admin/test04/udump/test04_ora_18968.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-18008: cannot find OUTLN schema
Fri Jan 18 15:49:13 2008
Errors in file /oracle/u02/admin/test04/udump/test04_ora_19058.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-18008: cannot find OUTLN schema
Fri Jan 18 15:50:37 2008
Errors in file /oracle/u02/admin/test04/udump/test04_ora_19154.trc:
ORA-00604: error occurred at recursive SQL level 1
ORA-18008: cannot find OUTLN schema
Fri Jan 18 15:51:16 2008
Errors in file /oracle/u02/admin/test04/udump/test04_ora_19154.trc:

边城 评论于: 2008.01.24 17:37
re: 减少全库导入时发生的错误(一) [回复]

你应该找到alert文件中数据库启动的时候加载的初始化参数。

确认一下,你再删除所有的SCHEMA后,执行全库导入了?

现在是否进行了备份,如果已经备份。可以尝试执行$ORACLE_HOME/rdbms/admin/catalog.sql

$ORACLE_HOME/rdbms/admin/catproc.sql

yangtingkun 评论于: 2008.01.25 09:35
re: 减少全库导入时发生的错误(一) [回复]

如果执行全库导入的DMP文件还在,你可以重建一个新数据库,在不删除用户OUTLN的情况下重新导入。

yangtingkun 评论于: 2008.01.25 09:46
re: 减少全库导入时发生的错误(一) [回复]

你应该找到alert文件中数据库启动的时候加载的初始化参数。
确认一下,你再删除所有的SCHEMA后,执行全库导入了?

这两步我不知怎样做,还请详细说明一下.

我直接运行了catalog.sql,catproc.sql
但运行时还是有
ORA-18008: cannot find OUTLN schema
没有成功.

边城 评论于: 2008.01.25 15:04
re: 减少全库导入时发生的错误(一) [回复]

先确认一件事情,你drop了用户之后,是否执行了全库导入?

yangtingkun 评论于: 2008.01.25 16:06
re: 减少全库导入时发生的错误(一) [回复]

对,执行过,但也是出错了.
ORA-18008: cannot find OUTLN schema
错误.

边城 评论于: 2008.01.25 16:29
re: 减少全库导入时发生的错误(一) [回复]

那么现在最简单的方法是重建一个数据库,在不删除用户OUTLN的情况下,执行全库导入或者只导入你的业务用户。

当然如果数据库不重要,那么我们可以慢慢尝试,看看有没有恢复的方法。

yangtingkun 评论于: 2008.01.25 16:42
re: 减少全库导入时发生的错误(一) [回复]

有使用SQL 代码重新建立一个数据库的方法吗?
因服务器老,不知是什么显卡了.现进不了XWINDOWS,
前几天我使用DBCA 想重新建立数据库时,
不能执行.(xhost + 不能打开)

边城 评论于: 2008.01.25 17:13
re: 减少全库导入时发生的错误(一) [回复]

解决这个的办法很多,比如silent模式建库,或者在其他服务器上执行dbca然后保存建库脚本,通过脚本建库。

yangtingkun 评论于: 2008.01.26 00:45
re: 减少全库导入时发生的错误(一) [回复]

谢谢yangtingkun !

我最后使用DBCA 生成新的数据库,并使用IMP导入前面的备份
了事.
另一台备份服务器导入时乱码问题,另想办法解决.

边城 评论于: 2008.01.28 09:35
re: 减少全库导入时发生的错误(一) [回复]

最近手工的事情很多,等有时间,我会尝试重现这个错误,看看有没有解决的方法。

yangtingkun 评论于: 2008.01.28 14:39

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...