Oracle 大数据量下的数据迁移

来源:互联网 发布:sql注入攻击 0.0.0.1 编辑:程序博客网 时间:2024/05/01 16:51

本文梗概:

本文主要描述了从oracle 9i至oracle 10g的单表大数据量的迁移过程,其间作者尝试了不同方法,对比之后,主要使用了DB Link。

正文:

由于公司服务器升级,原Oracle 9i RAC(裸设备)系统也升级到了Oracle 10g RAC(ASM),原数据库中的数据也要导入到新建的数据库中。
数据迁移要求:
环境原系统:Sun Slaris 8.0(UltraSPARC_64)
Oracle 9i R2 RAC

新系统:RHEL 5.5(x86_64)
Oracle 10g R2 RAC要求全数据量迁移(约300G)
原系统数据库不可下线
Oracle的数据迁移有很多种方法:RMan的备份/恢复方式、EXP/IMP、DB Link + extent等。
RMan:
由于系统环境的差异(SPARC -> x86)和数据库版本的问题,RMAN不予考虑。

EXP/IMP
最开始使用此方式,实际上在TOAD中提供的exp/imp工具非常好用,基本无视数据库的编码格式和版本,图形化的界面,可以实时看到导入、导出的进度,可以导出数据库结构,但由于原数据库的某些表数据量较大,在导出时提示exp kgefec: fatal error 0,基本每表可以导出6G数据后,就会报这个错误。这个错误我想应该是与数据库有关,应该不是TOAD的问题。总之,数据部分导出和没导是一样的,所以该方式也被放弃了。

DB Link + extent
DB Link实际上是尝试的第一种方式,建立这种模式的DB Link请参考如下代码:
CREATE DATABASE LINK RC CONNECT TO CSDN IDENTIFIED BY <PWD> USING '(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 10.1.0.62)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = RAC)))';
在建立好DB Link后,使用Insert into select ....
INSERT INTO tb SELECT * FROM tb@rc
问题大了!在第一试导入数据量在1.8G的表时,新数据库的UNDO表空间开始狂飙,最后占用到了6.5G,其间又手工为UNDO建立了一个新的数据文件,可是最后用不上了,删除也删除不了。
上网找方法,发现可以使用INSERT /**APPEND**/来避免UNDO激增的问题
INSERT /**APPEND**/ INTO tb SELECT * FROM tb@rc
但发现如果表的数据量很大的话,这一过程非常慢,一个7G左右的表,大概用时5个小时。后来发现原表中是建立了extent的,于想到了按区块导,多个进程并行。
注意:在导入前最好删除或禁止新表中的KEY和INDEX,这样导入会快得多。

操作:
1、在新数据库上建立一个ROW_ID表
create table MY_ROWID
(
ID NUMBER,
ROWID_MIN VARCHAR2(100),
ROWID_MAX VARCHAR2(100),
HAS_DEAL NUMBER
);
2、在原数据库上建立一个DB Link,主要用于向新数据库的ROW_ID表提供目标表数据区块列表
3、导入目标表的区块列表,在原数据库执行
insert into my_rowid@RC(id,rowid_min,rowid_max,has_deal)
select rownum,
DBMS_ROWID.ROWID_CREATE(1,o.data_object_id,e.RELATIVE_FNO,e.BLOCK_ID,0),
DBMS_ROWID.ROWID_CREATE(1,o.data_object_id,e.RELATIVE_FNO,e.BLOCK_ID+e.BLOCKS-1,10000),
0
from dba_extents e,dba_objects o
where e.segment_name=upper('base_table')
and e.owner='CSDN'
AND o.object_name = upper('base_table')
AND o.owner='CSDN';
4、在新数据库建立存储过程,用于多个进程同时调用。
  
注:这个过程是在CSDN找的,写的非常精妙(我修改了一下,在其中也加入了/*+APPEND */),如果调用过程中,被用户不小心被取消了,也可以重新调用继续导入,我就犯了这个错误,由于是termial到一台windows上,再toad+sqlplus到数据库服务器,由于是半夜了,所以去看了MESSI VS CR9,中场回来发现笔记本长时间没有操作进入了休眠,登陆的termial过期了,调用该过程的sqlplus也被杀了,杯催的同时,还有更杯催的,我一开始没有想太清楚,上去就truncate了新表的所有数据,回头仔细看了看过程,发现完全可以接着调用。在此向此过程的作者致意,并提醒和我一样的菜鸟们,林子大着呢......

5、调用过程,开了10个SQLPLUS
set serveroutput on;--打开输出,这样可以看到错误
call SP_XF_COPY_TABLE(0);
call SP_XF_COPY_TABLE(1);
call SP_XF_COPY_TABLE(2);
......
call SP_XF_COPY_TABLE(9);
这里的调用是在10个窗口中同时进行了,回头看看表空间,数据表空间在飞快增长着,而UNDO基本没有变化,其间出几个调用出现了ORA-02049: timeout: distributed transaction waiting for lock,网上也没找到太好的答案,应该是我反反复复重启的问题导致锁了表,于是关闭了出错的过程,只同时调用4个没有发现问题,4个做完再做接下来的4个、2个,BINGO,37G的表大概用了3个小时。
因为300G的数据主要集中在十几个表中,可以建立个多个ROW_ID表,所以可以把马力开到最大。如果数据是分布在更多的表中,每表数据也不多,我还是建议用EXP/IMP。总之,恼人的新数据库建立基本搞定了,测试的工作还在等待着我,革命还在继续。
原创粉丝点击