日期:2014-05-16  浏览次数:20423 次

ORACLE 表空间的转换
    由于前期的规划和人员的原因,有些表的表空间并没有统一,同一用户下出现多个表空间,这次数据库要升级,从ORACLE 9i 到 10g ,之前是导出一直出问题,后来发现是那台导出机器的问题,在其他的机器上用EXP导出都没有碰到类似的问题,唯独那一台机器。可怜那几天晚上,连续几天搞到晚上两三点,还以为是我们数据库结构的问题。由于数据量比较大,导出一次最大的一个用户下面是60G左右,所以一般导出是需要一个空间足够大的机器才行的。导出总算搞定了,导入又有点问题了,刚开始总是报错,特别是遇到行数比较多且含有blob字段的表,就是过不去,起初还以为是导出文件有问题,后来baidu了下,发现有的提到,导入10g是需要用10g的IMP的,花了一个晚上果真如此。由于要升级,就决定将以前没有完全规划好的表空间给整理下,结果又碰到一堆的问题,特别是含有blob字段的大表,迁移其表空间是件困难的事情,搞不好还把数据库给弄崩溃了。普通的表迁移表空间可以采用 alter table table_name move tablespace new_tablespace 语句来执行,含有blob的就不行了,执行该语句没错,但是一但将其原先的old_tablespace删除,该会提示该表或视图不存在,实际上是没有迁移成功的,只是将dba_tables中表对应的表空间字段修改了,内部blob字段索引等还是在原先的表空间中而原先的表空间已经删除,故报错。还是求助于baidu,找了些类似的问题看了看,发现下面的这个方式可行,我自己新建了一个表空间和一个含有blob字段的表,按照步骤操作成功。我们数据库用到的表有六七百个,需要调整表空间的初步估计有接近八十个,郁闷,估计今天晚上又得搞到很晚了,希望能成功。
--------------
1.导出表
EXP username/password@db_server FILE=c:\exp_filename.dmp LOG=c:\exp_logname.LOG
2.删除表和表空间
3.采用导出参数 indexfile 导入表
IMP username/password@db_server FILE=c:\exp_filename.dmp LOG=c:\imp_indexfile.LOG INDEXFILE=c:\altertablespace_table_index.SQL FULL= y
这步的操作并不是要导入表和数据,真正的目的是获取创建表和索引的脚本。
其中,指定参数INDEXFILE后,系统就将创建表和索引的语句写到一个文件,即指定的altertablespace_table_index.SQL 中。该文件中包含了所有创建索引(CREATE INDEX)语句和创建表(CREATETABLE)语句。但是这里所有创建表的语句均加了注释标志。在任何文本编辑器中打开并编辑该文件,去掉所有创建表语句的注释标志,将所有的表空间名称由A替换为B,同时对所有的创建索引语句加上注释标志。这些工作作完以后,在SQL/PLUS中运行该脚本文件,这些表就被创建,其表空间由A变为B(此时仅仅只是表结构而没有数据的)。
4.采用导入参数INDEXES=N 和 IGNORE=Y 将数据导入表中
IMP username/password@db_server FULL=Y INDEXES=N IGNORE=Y FILE=c:\exp_filename.dmp   LOG=c:\imp_tabledata.LOG
其中,参数INDEXES=N是指将数据导入数据库中时不加索引。IGNORE=Y是指在导入数据过程中,忽略表已经存在(table already exists)的错误。这样Oralce就将数据和一些约束条件导入到第3步创建的表中。
5. 创建索引
在文本编辑器中重新打开在第3步中创建的altertablespace_table_index.SQL 脚本文件,这次,将所有创建表(CREATE TABLE)的语句加上注释标志,然后将所有的创建索引(CREATE INDEX)语句去掉注释标志。在SQL/PLUS中再次运行该脚本文件。
至此,我们就成功完成了将数据表从表空间A转换到表空间B的工作。