首页 > 代码库 > 较复杂情况下小型数据库的数据迁移

较复杂情况下小型数据库的数据迁移

虽然在操作之前作过一些测试,但主要考虑脚本的正确与否以及对数据库对象的影响。并没有完全在实际系统上运行。这也成为后来
出现的一个问题没有预计到的根源。毕竟比较早的版本我没有用过:)。那就是8.0.6的exp工具并支持到处数据到多个文件,file=file1,
file2不能使用,而且也不清楚老的hp-unix是32位的时候支持大于2g的文件,而且8.0.6是否可以导出一个大于2G文件。后来出现问题之后
经过查证系统支持,此避免使用磁带机或者文件压缩的方式(具体方法网络上有相关资料)。
   由于考虑到加快数据导入速度,我在数据导入的时候将数据库指定用户所有not unique index全部删除,注意因为新数据库中已经有
一部分数据,为保证不导入重复数据不能够禁止PK,这样也就无法将unique index删除或者unusable。这里要提醒大家的是如果是PK的
unique index设置为unusable之后将不能向其中插入数据,这样在imp 时使用skip_unusable参数也不起作用,不管数据重复与否都无法
插入表。所以当表由数据的时候,要保证没有重复数据,并且可以插入新数据就不能将unique index设置为unusable。
   这里我采用的方法是删除所有not unique index,保留PK对应索引。这样既保证数据不重复,有提高速度。

老系统运行环境:
  os      hp-unix
  db      8.0.6
  memory  2G
  cpu     2个
数据文件大小22G(包括数据、索引、临时),经过分析实际的数据量大概8.5G。其中表数据经过分析大小不到4G。后来导出数据的确是不到
3G多,说明是前的分析还是比较准确。
  我使用分析脚本是:其它还有一些脚本也差不多,就是从几个关键字典表分析。
  SELECT a.NAME, b.tablespace_name,
  SUBSTR(‘Free: ‘||SUM(b.bytes)/1024/1024,1,30) File_Size
  FROM dba_free_space b, v$DATABASE a
  GROUP BY b.tablespace_name, a.NAME
  UNION
  SELECT a.NAME, b.tablespace_name,
  SUBSTR(‘Total: ‘||SUM(b.bytes)/1024/1024,1,30)
  FROM dba_data_files b, v$DATABASE a
  GROUP BY b.tablespace_name, a.NAME
  ORDER BY 1,2,3

  SELECT TABLESPACE_NAME, SUM(BYTES)/(1024*1024)  FREE_SPACE
  FROM DBA_FREE_SPACE  GROUP BY TABLESPACE_NAME;
  
  SELECT TABLESPACE_NAME, BYTES, AUTOEXTENSIBLE,FILE_NAME  FROM DBA_DATA_FILES;

二、数据迁移目标
    将原来运行在8.0.6下的数据库迁移到8.1.7。应用系统在新数据库基础上运行正常,数据迁移尽快完成,数据不丢失。

三、数据迁移条件

   1、导出需要的条件 
      应用系统在数据导出之前切换到新的系统,这样原来数据库将不再有应用系统访问,保证数据导出期间的一致性。
      新的数据库在导出开始之前安装好,并建立应用系统所需要的数据库。
   2、导入需要的条件
      开始数据导入的时候,为加快数据导入过程需要应用暂时不访问新的数据库,为加快数据导入修改数据库运行参数和索引处理。
      数据导入完成并恢复相关索引系统可以进入正常运行状态。

四、数据迁移策略
    
    因为系统实际数据不是很大,数据结构相对独立。采用exp/imp方式对数据进行逻辑备份和恢复。
   
    在新的服务器上应用系统所需要的物理和逻辑数据结构都已经在数据迁移之前配置好,并保证和原有数据结构完全一样。所以
    只需要导出原来数据库中的表的数据和索引。

    数据导入的时候只需要导入表数据,因为在导入之前已经有一部分新的数据进入系统,需要在数据导入的时候处理数据重复。在数据
    导入的时候不禁止primary key,并且设置ignore=y保证重复数据不进入数据库,并且不影响其它数据的正常导入。
  
    为加快数据导入速度,在数据导入的时候删除原来的索引。在数据导入完成之后重新建立。

五、数据导出准备
    1、新服务器准备
       需要建立好数据库系统(保证新旧数据库采用同样的字符集)。lns_lang环境变量一样,数据库的字符集:ZHS16CGB231280。
       如果没有设置nls_lang参数,需要在执行导出任务之前添加如下环境变量设置。
       
       以Oracle 用户进入,修改 $HOME/.bash_profile文件,添加:
       export NLS_LANG=AMERICAN_AMERICA.ZHS16CGB231280;
       export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data;
       添加完成之后,退出oracle用户。再次进入并使用env命令验证设置生效。  
   
       
     
    2、导出、导入磁盘空间准备
       准备好用于存放导出数据的磁盘空间=15G,为加快导出数据速度必须使用硬盘存放数据。最好将导出数据存放在和原始数据库文件不同
       的硬盘上减少I/O冲突,加快文件访问速度。
       在新服务器上准备15G磁盘空间,并且也不要和数据库文件所在磁盘分区在同一个硬盘上。

    3、确认旧服务器环境变量设置正确
       
       如果没有设置nls_lang参数,需要在执行导出任务之前添加如下环境变量设置。
       以Oracle 用户进入,修改 $HOME/.bash_profile文件,添加:
       export NLS_LANG=AMERICAN_AMERICA.ZHS16CGB231280;
       export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data;
       添加完成之后,退出oracle用户。再次进入并使用env命令验证设置生效。    
   
         
    4、将系统切换到新的数据库,保证应用不再访问该数据库。
         

    
六、数据导出
    
    因为导出数据文件大小可能突破系统允许单个文件大小限制,使用多个导出文件。
    
    
    exp parfile=/不和数据库文件在同一个硬盘上的目录/exp.txt
    
    执行该命令之后,察看exp.log文件中记录的日志信息。
    如果最后一行Export terminated successfully without warnings执表示到处数据成功。
    如果最后一行Export terminated successfully with warnings,表示数据到处完成,但是发生一些报警。
        需要分析该log之后确定不会影响imp操作。
    如果最后一行EXP-00024: Export views not installed, please notify your DBA类似的信息,表明操作失败
        需要分析日志查找原因之后才可进行后续操作。导出数据失败不影响数据库系统。


七、数据导入准备
    
    1、将正在运行的系统暂时断开和新数据库的连接。保证没有其他系统访问新数据库。
         拷贝上面产生的导出数据文件到新机器上预先准备好的目录。
         拷贝imp.txt到该目录。
        
    2、修改新系统的运行参数文件为导入数据作准备。
       修改initPMORCL2.ora文件中的下列参数。按照服务器内存2G来计算,分配SGA大约820M左右内存空间,
       其中share pool=200M,block_buffers=600m
        db_block_size=16384
        shared_pool_size=209715200
        db_block_buffers=38400
        SORT_AREA_SIZE=33554432
        sort_area_retained_size =33554432
        SORT_MULTIBLOCK_READ_COUNT=20
        其他参数保持不变。
   
    3、对新进入系统的数据进行逻辑备份。保证导入数据失败时,这部分数据不会丢失。
       
       a、在新机器上执行:
       拷贝exp_new.txt,imp_back.txt,create_user.sql文件到预先准备好存放新数据库备份的目录。
      
       exp parfile=/保存新数据库导出文件的目录/exp_new.txt
       
       注意这里的文件目录不要和准备用来存放需要导入的数据文件目录一样。
       执行完成之后察看产生的exp_new.log文件,没有错误才进行后面处理。
            
       b、执行一个数据库物理备份。
        因为新的数据库处于no archivelog模式,所以执行关闭数据库的冷备份。

        svrmgrl connect internal
        shutdown normal

        在操作系统上执行文件拷贝命令
        cp db1 db2 db3 三个目录下所有文件到备份磁盘。(包括所有*.dbf *.ctl *.log文件).
     
    4、 重新启动数据库
        执行命令:
        svrmgrl 
            connect internal
            startup force
        屏幕显示数据库正常关闭。            
        屏幕显示数据库正常启动。
        进入sqlplus执行如下命令核对系统参数。
        Col name FORMAT a20;
        Col value FORMAT a20;
        Select name,value  from v$parameter where  lower(name)=‘shared_pool_size‘;
        Select name,value  from v$parameter where  lower(name)=‘db_block_buffers‘;
        Select name,value  from v$parameter where  lower(name)=‘sort_area_size‘;
        核对屏幕上显示的value字段的值和前面设置一样。     
     


    5、建立用于维护数据库索引的存储过程。
       拷贝数据库脚本drop_nonunique_index.sql 到/home/oracle。
       在新数据库的sqlplus中执行如下命令:注意一定要使用pmexp用户完成命令!!!
       connect pmexp/pmexp 
       @/home/orale/drop_nonunique_index.sql 
       查看执行结果,返回 PL/SQL 存储过程建立完成信息之后继续下面操作。 
       删除索引存储过程说明:
           因为新的数据库已经建立,并且包含新的运行数据所以,在导入数据的时候需要避免重复数据进入,所以不能够禁止
       constraint和primary key。由于建立unique constraint时也同时建立unique index,而删除unique index必须禁止对应的
       constraint造成重复数据插入,所以在删除索引的时候对于unique index不删除。这将对数据导入导入速度造成一定影响。      
     
       
       记录新数据库原有索引数目:
       在sqlplus中执行:
        connect pmexp/pmexp
        select count(*) from user_indexes; 
       记入统计结果用于后面重新建立索引后比对。

    6、删除新数据库中已经建立的索引。
       在sqlplus中执行命令:注意一定要使用pmexp用户完成命令!!!
       connect pmexp/pmexp
       SET serveroutput ON
       EXECUTE drop_nonunique_index(‘PMEXP‘); 
       返回PL/SQL procedure successfully completed,表示执行成功,可以进行后续操作。
    
八、数据导入


    
    
    1、 单独导出数据库索引,生成旧数据库上建立索引脚本,用于完成数据倒入之后重新建立索引。
         
         imp =/存放需要导入数据的目录/checkout_old_index.txt
         
         执行完成之后,检查文件checkout_old_index.sql是否生成。
         检查日志内容。
       

    2、 开始执行数据导入任务。
         
         imp parfile=/存放需要导入数据的目录/imp.txt    
         修改imp.txt文件中的TABLES=(表名称1, 表名称2,表名称3)。将多个表名称加入并用","分开。
         执行该命令之后,察看imp.log文件中记录的日志信息。


    3、 恢复数据库索引
        在sqlplus中执行第1步中生成的索引建立脚本checkout_old_index.sql:
        connect pmexp/pmexp
        SET serveroutput ON
        @/存放需要导入数据的目录/checkout_old_index.sql  
        因为要对大量数据重新建立索引,执行时间比较长。
        观察执行时屏幕的输出信息,记录所有报错信息。对于已经存在的索引再次建立会产生报警信息,不影响数据库。        
        上面命令执行完成之后,确认索引恢复正常 
        在sqlplus中执行:
        connect pmexp/pmexp
        select count(*) from user_indexes;
        将统计结果和前面记录的(七、数据导入准备  第5步)结果进行比对,应该数目一样。


   6、   恢复参数设置
         
        这些参数专门用于重建索引的时候使用,建立完成之后需要恢复数据库原来设置。          
          修改参数    SORT_AREA_SIZE=1638400
          取消该设置  SORT_MULTIBLOCK_READ_COUNT=20
          其他修改保持不变。
        进入
        svrmgrl
        connect internal
        startup force
        显示数据库关闭之后,又重新启动。

九  操作失败或者出现错误的处理。
    
     按照上面顺序执行每一部操作,每一步执行完成之后都核对产生的日志或者屏幕输出信息。没有错误才进行下一步处理。
     如果数据导出的时候发生错误:
          1、exp会自动退出运行,或者其他系统受到影响通过ctrl + c强行推出。
          2、分析日志文件。
          3、解决错误之后再次执行.
          
     如果数据导入的时候发生错误:
          1、imp会自动退出。
          2、分析错误日志。
          3、如果解决之后可以继续执行,再次运行imp工具。
             如果短时间不能继续执行。恢复新数据库到导入数据之前状态。
              a、 进入sqlplus
                  sqlplus system/manager@pmorcl2
                  SQL>drop user pmexp cascade;
                  SQL>@/保存新数据库导出文件的目录/create_user.sql
              b、 执行imp操作恢复新产生数据:
                  导入数据
                  imp parfile=/保存新数据库导出文件的目录/imp_back.txt
                  检查日志文件imp_back.log。
               
               *********************************************************
                  如果数据库进行过物理备份:(七、数据导入准备 中 2 步中说明).
                  关闭数据库
                  直接将备份文件拷贝会原来位置。             
           

             测试数据恢复正常之后,开始运行系统。
          
          4、分析问题,如果需要建立新数据库,准备下一次重新执行上述任务(从头开始)。

script.rar

脚本链接地址:http://www.itpub.net/attachment.php?aid=NDIyNzN8ODUwOTViOTZ8MTM5OTAyNzAzN3wwfDE3ODcyOA%3D%3D&fid=2