数据迁移脚本备案

一、概述
最近做的一个项目,在很大的程度上面是在做数据迁移。数据迁移往往是项目最大的风险点。在一些大的重构项目中,往往会有一个团队专门负责,可见其重要性。在项目发布中,数据迁移往往会占用很多的时间。数据迁移需要考虑很多的情况,如:迁移方案、数据备份、迁移总时间、迁移时间点、迁移后check。
二、一个例子
项目是想把一个登陆id:member_id换成后台交互的ali_id。为此有一个map表:cbu_member_id_mapping。我们统计了数据量大约在1亿左右。
  1. 为了实现无缝迁移,我们打算先在每个表上面添加一列,命名为:TMP_ALIID
  2. 为了效率,我们打算实现并发执行。实现方式为通过把 主键mod n来实现。
  3. 为了统一脚本,我们打算用动态sql来实现。
  4. 为了看任务执行的进度,我们设计了一个任务表。
  5. 为了记录异常情况,我们记录了异常表
脚本如下:
1、筛选条件表
  create table fin_filtrate_tbd(
   tableName  varchar(64), --需订正的表名
   domain varchar(64),
   sql varchar2(2048)
   );
--添加筛选条件
truncate  table fin_filtrate_tbd;
insert into fin_filtrate_tbd values('fin_contract','nirvana','select p.id,p.ali_member_id_old from fin_contract p where (product_id like ''CTP%'' or product_id = ''EW\EWC'' or product_id like ''ITBU%'' or product_id like ''OTH%'') and p.ali_member_id is  null and ali_member_id_old is not null');
insert into fin_filtrate_tbd values('fin_contract','zeus','select p.id,p.ali_member_id_old from fin_contract p where not (product_id like ''CTP%'' or product_id = ''EW\EWC'' or product_id like ''ITBU%'' or product_id like ''OTH%'') and p.ali_member_id is  null and ali_member_id_old is not null');
2、创建错误日志表
/**
   select * from fin_unifyid_progress_tbd order by now desc; 查看执行过程
	 select * from fin_unifyid_errolog_tbd;查看报错日志
**/
create table fin_unifyid_errolog_tbd(
   tableId varchar(64 ),   --需要订正记录ID
   tableName  varchar(64 ), --需订正的表名
   errcode number,
   errmsg varchar2(1024 )
   );
--记录任务结果
create table fin_unifyid_progress_tbd(
   now date,
   eigenvalue varchar(64),
   num number
   );
3、存储过程
create or replace procedure upgradeMemberId(tableNametemp in varchar2, --更新表名
                                            domaintemp    in varchar2 --中供诚信通代号
                                            --batchtemp     in number --批次
                                            ) as

  v_sql        varchar2(256);
  v_errcode    varchar2(64);
  v_errmsg     varchar2(256);
  v_cursor_sql varchar2(512);
  v_id         number;
  v_member_id  varchar2(256);
  v_ali_id     number;
  TYPE type_cursor is ref cursor;
  v_cursor    type_cursor;
  v_amount    number := 0; -- batch commit number
 -- v_partition number := 3; --v_partition分区数

begin
  begin
    select a.sql
      into v_cursor_sql
      from fin_filtrate_tbd a
     where a.tableName = tableNametemp
       and a.domain = domaintemp;
  
    OPEN v_cursor FOR v_cursor_sql;
     -- using v_partition, batchtemp;
    LOOP
      fetch v_cursor
        into v_id, v_member_id;
      exit when v_cursor%notfound;
    
      if (domaintemp = 'nirvana') then
        v_sql := ' select  NVL(sum(b.ali_id),0)  from cbu_member_id_mapping b where b.member_id=:1 AND ROWNUM = 1';
        execute immediate v_sql
          into v_ali_id
          using v_member_id;
      
        if v_ali_id != 0 then
          v_sql := 'update ' || tableNametemp || ' set ' ||
                   ' TMP_ALIID=:1,ALI_ID=:2 where id=:3';
          execute immediate v_sql
            using to_char(v_ali_id), v_ali_id, v_id;
        end if;
      else
        v_sql := 'update ' || tableNametemp || ' set ' ||
                 ' TMP_ALIID=:1 where id=:2';
        execute immediate v_sql
          using v_member_id, v_id;
      
      end if;
      v_amount := v_amount + 1;
      if (mod(v_amount, 1000) = 0) then
        insert into fin_unifyid_progress_tbd
        values
          (sysdate,
           tableNametemp || '_' || domaintemp || '_' || 3,
           v_amount);
        commit;
      end if;
    end LOOP;
  exception
    when others then
      v_errcode := sqlcode;
      v_errmsg  := sqlerrm;
      insert into fin_unifyid_errolog_tbd
      values
        (v_id, tableNametemp, v_errcode, v_errmsg);
  END;
  commit;
  close v_cursor;
  commit;
end upgradeMemberId;



  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值