数据迁移的问题A、源数据库:Oracle 9i RAC(裸设备),表空间300GB (Sun Solaris  UltraSPARC_64)B、目标数据库:Oracle 10g RAC(ASM),空的表空间已经建立(RedHat Enterprise Linux 5.5 x86_64)A是业务系统的数据库,不允许停机下线;B为全新数据库,未来代替A的工作。A中的300G表空间基本占满,300GB数据基本上都是小字段的字符数据,集中在20个表中,每表大概10-20亿行数据。
求在保证数据完整性前提下,简单快速的迁移办法。
---------------------------在网上搜了一些,用IMP/EXP工具似乎要生成中间文件,还有说用DB Link方法导的不知道在这个数据量和结构上,什么样的方式才是适合我的。本人对linux DBA等非常的菜,若大侠指点,最好说出具体的命令。多谢!!

解决方案 »

  1.   

    把源数据库的数据文件和控制文件,拿到新机器上去恢复。
    如果新数据库要替换旧数据库,是否需要并行运行一段时间,他们的之间的数据如何同步,也需要考虑.总之,需要一套ETL程序。
      

  2.   

    1:RMAN备份恢复2:DG 数据同步
      

  3.   

    在局域网中数据同步,如果在远程最好不用。
    rman备份。
      

  4.   


    版本不同,也可以用RMAN?
      

  5.   

    网络条件允许的话,写一个批量建表的语句,直接用数据链路建表过来吧,exp是把数据库的数据导出来,其实就变成了一堆的建表,然后插入数据的语句,只是被封装在一个文件中,imp就是把这个文件给执行了。rman没坐过,但是感觉rman是最适合的操作,因为会把数据库整个一模一样的迁移。。
      

  6.   

    应该有不兼容的地方,但是觉得有可行性好像有人成功了
    http://oldboy.itpub.net/post/29104/467554
      

  7.   

    首先你要把握好业务需求,
    可以先把静态数据搞过去,随便怎么整都行,
    关键是动态数据的问题。你可以考虑使用streams来做,
    如果不熟悉也没关系,下载ogg,配置好后,对动态表进行直接加载过去,
    然后增量同步,待数据追上后,直接切换业务。为保证方法的可回退性,最好是配置好双向复制。
      

  8.   

    没有专业DBA做这个东西,不停业务不停的情况,你只有叫开发人员去实现了从源数据端读出来再写到新库去。
    跨版本RAC数据迁移没有DBA介入,会非常痛苦的。不过我觉得奇怪没有DBA去搞RAC环境出问题会比较麻烦的
      

  9.   

    自己搞定了本文梗概:
      本文主要描述了从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、在新数据库建立存储过程,用于多个进程同时调用。
     CREATE OR REPLACE PROCEDURE CSDN.SP_XF_COPY_TABLE(N NUMBER) IS
      V_SQLERRM VARCHAR2(200);
     BEGIN
     FOR C IN (SELECT ID, ROWID_MIN, ROWID_MAX
       FROM MY_ROWID
      WHERE HAS_DEAL = 0
       AND MOD(ID, 10) = N) LOOP --注意这里的10,是该过程被要调用次数
     INSERT /*+APPEND */ INTO    表1
     SELECT * FROM 表1@rc t
      WHERE ROWID >= CHARTOROWID(C.ROWID_MIN)
     AND ROWID <= CHARTOROWID(C.ROWID_MAX);
     UPDATE MY_ROWID SET HAS_DEAL = 1 WHERE ID = C.ID;
     COMMIT;
     END LOOP;
     COMMIT;
     EXCEPTION
     WHEN OTHERS THEN
     V_SQLERRM := SUBSTR(SQLERRM, 1, 200);
     DBMS_OUTPUT.PUT_LINE(V_SQLERRM);
     ROLLBACK;
     END SP_XF_COPY_TABLE;
     /
     注:这个过程是在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。总之,恼人的新数据库建立基本搞定了,测试的工作还在等待着我,革命还在继续。