设为首页 收藏本站
查看: 1323|回复: 0

[经验分享] 用脚本实现表的远程准实时同步

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-3-18 09:04:06 | 显示全部楼层 |阅读模式
要同步某个数据库下的少数几个表,轻量级的方案有oracle的高级复制(物化视图方式)和mysql的主从复制,但均需要主库到从库有较好的网络环境,跨机房的话,最好走专线。如果主库到从库的网络环境不好,甚至主库无法直接ping通从库,需要从跳板机跳转呢,此时只有用最原始的方式,手工编写脚本来实现。场景有两种:

一、主表的数据是纯增量型(如cdr话单之类的表,主表只有insert操作),以mysql为例
需求:每天凌晨00:30将昨天的数据从A库同步至C库

网络环境:主库香港库A(172.17.5.14)无法直接访问北京从库C(10.10.10.64),需要从跳板机深圳B服务器(192.168.40.47)跳转。
这种场景相对简单,以mysql为例子,先在B库上导出数据,脚本片段:
dt=`date -d '-24 hours' +%Y%m%d`
mt=`date -d '-24 hours' +%Y%m`
/usr/bin/mysqldump -uroot -pxxxxxx -h 172.17.5.14 globallink_g g_cdr_gprs_$mt --where="substr(cdr_time_stamp,1,8)='$dt'" --no-create-info --single-transaction >$sqlfile1 2>>$errlogfile
......

if scp -P 2222 $bz_file root\@192.168.40.47:/hkcdr/ >/dev/null 2>>$errlogfile;then
  mv $bz_file /opt/get_hkcdr/bak/
  echo `get_time` "success to copy $bz_file to remote! " >>$logfile
else
  echo `get_time` "fail to copy $bz_file to remote, please read $errlogfile to get detail" >>$logfile   
  exit 1
fi

跳板机B上做端口转发,将本机收到的2222端口转发至10.10.10.64
#ssh -CfNgL 192.168.40.47:2222:10.10.10.64:22 root@192.168.40.47

此定时任务00:15执行,然后在北京库上部署入库定时任务,00:30执行:
#!/bin/bash
# Writed by Weikle in Dec., 2015, import cdr files to beijing bss db in /hkcdr
#
db_name=("globallink_g" "globallink_k" "globallink_ey" "globallink_y")
logfile="/hkcdr/import_hkcdr.log"
errlogfile="/hkcdr/import_hkcdr_error.log"

get_time() {
echo "[`date '+%Y-%m-%d %H:%M:%S'`]:"
}

imp_cdr() {
/usr/bin/mysql -uroot -pxxxxxx $1 <$2
}

for i in ${db_name
  • }
    do
    sqlfile="/hkcdr/${i}_cdr_`date -d '-24 hours' +%Y%m%d`.sql"
    bzip2 -d $sqlfile.bz2
    if imp_cdr $i $sqlfile >/dev/null 2>$errlogfile.$i;then
      mv $sqlfile "$sqlfile".processed
      echo `get_time` "import $sqlfile success!" >>$logfile
    else
      cat $errlogfile.$i >>$logfile
      echo `get_time` "fail to import $sqlfile!" >>$logfile
      mv $sqlfile "$sqlfile".err
      exit 1
    fi
    done

    注意:如果入库失败,须将sql文件增加err后缀作为标识。由于主库是增量数据,所以入库的时候,可以不处理以前的err文件,不会引起数据混乱。后续单独处理即可。

    二、主表的数据有各种DML(包括insert/update/delete),以oracle为例

    这种情况就复杂一些,需要在主表建立触发器,将主表上的DML语句单独存到一个表里去。
    触发器片段如下:
    create or replace trigger simm_trigger  after insert or update or delete  on uprg_simm_h_f_master for each row
    declare
      v_log    varchar2(500):= '';
      errcode  number;
      errmsg   varchar2(100);
      --output_file utl_file.file_type;
    begin
    --output_file := utl_file.fopen ('RWDIR','simmr_sync.sql', 'A');
    if inserting then
       v_log :='insert into uprg_simm_h_f_master values('
       ||''''||:new.imsi_h||''''||','
       ||''''||:new.msisdn_h||''''||','
       ||'null'||','
       ||''''||:new.msisdn_f||''''||','
       ||:new.status||','
       ||:new.sendout||','
       ||''''||:new.instance_name||''''||','
       ||'to_date('||''''||to_char(:new.last_modified_dat,'YYYY-MM-DD HH24-MI-SS')||''''||','||''''||'YYYY-MM-DD HH24-MI-SS'||''''||')'||','
       ||:new.networkid||','
       ||''''||:new.mcc||''''||','
       ||''''||:new.mnc||''''||','
       ||''''||:new.instance_gt||''''||','
       ||''''||:new.product_name||''''||')'||';' ;
    ......
    end if;
      --utl_file.put_line (output_file, v_log);
      --UTL_FILE.FCLOSE(output_file);
      --create table simmr_sync(sql varchar2(500),sync_time date);
      insert into simmr_sync values(v_log,sysdate);
    exception
      when others then
      errcode:=sqlcode;
      errmsg:=sqlerrm(sqlcode);--sqlerrm(100) means'ORA-1403:no data found',error code is +100
      insert into simmr_sync_err values(errcode,errmsg,sysdate);
    end;

    此时,将主表的DML存入了simmr_sync表,如下:
    QQ截图20160318090358.png

    同样,这里每个小时同步一次,比如每个小时的10分将其scp至从库,然后从库每个小时的15分入库,
    入库脚本片段如下:
    ls -rt /u01/simmr_sync/*.sql|while read aa;do
    /u01/app/oracle/product/11.2.0/bin/sqlplus -s 'rwuser/xxxxxx@RWDB'  <<EOF >$db_result
    set FEEDBACK off
    set TERM  on
    set TRIM  on
    set TRIMS on
    set linesize 500
    set pagesize 0
    set heading off
    @$aa
    EOF
      if grep "ORA-" $db_result >/dev/null 2>&1;then
        echo -e "fail to import $aa:sqlplus or sql execution error at `date '+%Y-%m-%d %H:%M:%S'`\n" >>$logfile
        cat $db_result >>$logfile
        mv $aa "$aa".err
        exit 1
      else
        mv $aa "$aa".bak
        echo -e "success to import $aa at `date '+%Y-%m-%d %H:%M:%S'`\n" >>$logfile
        find /u01/simmr_sync -name "*.bak" -mtime 1 -exec rm {} \;
      fi
      done
    else
      echo -e "no file to import at `date '+%Y-%m-%d %H:%M:%S'`\n" >>$logfile
    fi

    注意:这里在读取/u01/simmr_sync/*.sql的时候,必须用ls -rt的方式按时间顺序入库,不能乱,因为数据在主库上可能随时间被反复更新,如果漏掉了前面的sql,单独执行后面的sql会引起数据混乱。

  • 运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
    2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
    3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
    4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
    5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
    6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
    7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
    8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

    所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-192319-1-1.html 上篇帖子: windows 2003 2008安装IIS + PHP + MYSQL的一般方法 下篇帖子: window dos命令删除服务!创建私密文件夹!等等.
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码加入运维网微信交流群X

    扫码加入运维网微信交流群

    扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

    扫描微信二维码查看详情

    客服E-mail:kefu@iyunv.com 客服QQ:1061981298


    QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


    提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


    本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



    合作伙伴: 青云cloud

    快速回复 返回顶部 返回列表