WINDOWS下的程序员出身,偶尔也写一些linux平台下小程序, 后转行数据库行业,专注于ORACLE和DB2的运维和优化。 同时也是ios移动开发者。欢迎志同道合的朋友一起研究技术。 数据库技术交流群:58308065,23618606
全部博文(599)
分类: Oracle
2010-01-03 17:06:28
在使用EXP/IMP进行数据的迁移,经常会需要转换表空间的操作,简单记录一下,EXP过程碰到表空间的转换时需要注意的问题。
介绍利用10g的改名表空间名称的方法解决表空间的转化问题。
EXP转换表空间:http://yangtingkun.itpub.net/post/468/455820
前一篇文章介绍了解决表空间转化的问题,但是这种方法无法处理包括分区表在内的表中包含多个段的情况。
看一个简单的例子:
SQL> CREATE TABLESPACE TEST DATAFILE 'F:\ORACLE\ORADATA\TEST1\TEST01.DBF' SIZE10M;
表空间已创建。
SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
2 PARTITION BY RANGE (ID)
3 (PARTITION P1 VALUES LESS THAN (100) TABLESPACE TEST,
4 PARTITION P2 VALUES LESS THAN (200) TABLESPACE TEST);
表已创建。
下面要将T_PARTITION迁移到另外一个数据库中,但是目标数据库中不存在TEST表空间:
F:\>exp file=t_partition.dmp tables=t_partition
Export: Release9.2.0.4.0 - Production on星期日3月2 16:55:34 2008
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
连接到: Oracle9i Enterprise Edition Release9.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining option
s
JServer Release 9.2.0.4.0 - Production
已导出ZHS16GBK字符集和AL16UTF16 NCHAR字符集
即将导出指定的表通过常规路径...
. .正在导出表 T_PARTITION
. .正在导出分区 P1 0行被导出
. .正在导出分区 P2 0行被导出
在没有警告的情况下成功终止导出。
对于9i数据库而言,由于分区所在表空间不存在,即使向上一篇文章介绍的那样设置QUOTA的默认表空间,导入仍然是要报错的:
SQL> CREATE USER TEST_IMP IDENTIFIED BY TEST_IMP DEFAULT TABLESPACE YANGTK;
用户已创建
SQL> GRANT CONNECT, RESOURCE TO TEST_IMP;
授权成功。
SQL> ALTER USER TEST_IMP QUOTA UNLIMITED ON YANGTK;
用户已更改。
SQL> REVOKE UNLIMITED TABLESPACE FROM TEST_IMP;
撤销成功。
F:\>imp file=t_partition.dmp tables=t_partition
Import: Release9.2.0.4.0 - Production on星期日3月2 16:56:30 2008
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
连接到: Oracle9i Enterprise Edition Release9.2.0.4.0 - Production
With the Partitioning, Oracle Label Security, OLAP and Oracle Data Mining option
s
JServer Release 9.2.0.4.0 - Production
经由常规路径导出由EXPORT:V09.02.00创建的文件
警告:此对象由TEST导出,而不是当前用户
已经完成ZHS16GBK字符集和AL16UTF16 NCHAR字符集中的导入
.正在将TEST的对象导入到TEST_IMP
IMP-00017:由于ORACLE的959错误,以下的语句失败
"CREATE TABLE "T_PARTITION" ("ID" NUMBER, "NAME" VARCHAR2(30)) PCTFREE 10 P"
"CTUSED 40 INITRANS 1 MAXTRANS 255 TABLESPACE "SYSTEM" LOGGING PARTITION BY "
"RANGE ("ID" ) (PARTITION "P1" VALUES LESS THAN (100) PCTFREE 10 PCTUSED 4"
"0 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS"
" 1) TABLESPACE "TEST" LOGGING NOCOMPRESS, PARTITION "P2" VALUES LESS THAN ("
"200) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL65536 F"
"REELISTS 1 FREELIST GROUPS 1) TABLESPACE "TEST" LOGGING NOCOMPRESS )"
IMP-00003:遇到ORACLE错误959
ORA-00959:表空间'TEST'不存在
成功终止导入,但出现警告。
前面已经提到了9i中唯一的方法只有先手工创建表,然后使用IGNORE=Y执行导入。
但是对于10g来说,可以通过变通的方法解决这个问题:
SQL> CONN
已连接。
SQL> SELECT TABLESPACE_NAME FROM DBA_TABLESPACES;
TABLESPACE_NAME
------------------------------
SYSTEM
UNDOTBS1
SYSAUX
TEMP
USERS
EXAMPLE
YANGTK
LOB_SPACE
已选择8行。
这时,如果直接导入也会报错:
E:\>imp file=t_partition.dmp tables=t_partition
Import: Release10.2.0.1.0 - Production on星期日3月2 17:17:44 2008
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到: Oracle Database10gEnterprise Edition Release10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
经由常规路径由EXPORT:V09.02.00创建的导出文件
警告:这些对象由TEST导出,而不是当前用户
已经完成ZHS16GBK字符集和AL16UTF16 NCHAR字符集中的导入
.正在将TEST的对象导入到YANGTK
.正在将TEST的对象导入到YANGTK
IMP-00017:由于ORACLE错误959,以下语句失败:
"CREATE TABLE "T_PARTITION" ("ID" NUMBER, "NAME" VARCHAR2(30)) PCTFREE 10 P"
"CTUSED 40 INITRANS 1 MAXTRANS 255 TABLESPACE "SYSTEM" LOGGING PARTITION BY "
"RANGE ("ID" ) (PARTITION "P1" VALUES LESS THAN (100) PCTFREE 10 PCTUSED 4"
"0 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREELIST GROUPS"
" 1) TABLESPACE "TEST" LOGGING NOCOMPRESS, PARTITION "P2" VALUES LESS THAN ("
"200) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL65536 F"
"REELISTS 1 FREELIST GROUPS 1) TABLESPACE "TEST" LOGGING NOCOMPRESS )"
IMP-00003:遇到ORACLE错误959
ORA-00959:表空间'TEST'不存在
成功终止导入,但出现警告。
但是由于10g提供了改变表空间名称的SQL,可以通过下面的方式导入分区表:
SQL> ALTER TABLESPACE YANGTK RENAME TO TEST;
表空间已更改。
下面就可以顺利导入:
E:\>imp file=t_partition.dmp tables=t_partition
Import: Release10.2.0.1.0 - Production on星期日3月2 17:11:55 2008
Copyright (c) 1982, 2005, Oracle. All rights reserved.
连接到: Oracle Database10gEnterprise Edition Release10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
经由常规路径由EXPORT:V09.02.00创建的导出文件
警告:这些对象由TEST导出,而不是当前用户
已经完成ZHS16GBK字符集和AL16UTF16 NCHAR字符集中的导入
.正在将TEST的对象导入到YANGTK
.正在将TEST的对象导入到YANGTK
. .正在导入分区 "T_PARTITION":"P1"导入了 0行
. .正在导入分区 "T_PARTITION":"P2"导入了 0行
成功终止导入,没有出现警告。
导入后可以通过修改表空间名称的方法将表空间名称修改会原来的名称:
SQL> ALTER TABLESPACE TEST RENAME TO YANGTK;
表空间已更改。
通过这种方法的导入,可以解决包含多个段的表,无法通过正常方式进行表空间转换的问题。但是上面的方法只是提供了在不提前建表的方式下导入的一种可行性。
且不说修改表空间名称对于一个对外提供服务的数据库系统的影响,就是修改表空间这个动作本身,就未必比提前建表的工作量小多少。
考虑几种情况,如果表中包含多个分区,每个分区所在表空间不同,希望通过迁移将所有的分区都放到目标的表空间中。那么如果目标数据库中,只有目标表空间存在,且分区表每个分区对应的表空间都不存在的话,只能通过修改一次表空间名称,导入一个分区,再次修改表空间名称,再导入一个分区的方法来实现,效率和工作量都比较大。
而对于迁移表的时候,原分区表的分区所在表空间再目标数据库中存在,且导入的时候不希望导入到同名分区中,而是希望统一导入到目标表空间中。这时需要做的是首先将存在的表空间进行重命名,然后将目标表空间改为刚才的名称,导入分区后,还需要将目标表空间修改会来,再将源表空间名称恢复。总之,这个方法对于很多的迁移情况都是一个很费劲的操作。
而且,这个方法有一个局限性,就是一般用于9i或更低版本向10g或更高版本迁移的时候使用。这是因为,只有10g以上的版本才支持表空间重命名,这就要求目标数据库必须在10g版本以上。而如果源数据库的版本超过10g,则可以通过数据泵进行表空间的转化,完全没有必要使用这么麻烦的方法,因此这个方法将数据源限制在9i及以下的版本中。