脚本功能:

1. 将指定的报告文件按照指定的字段、切库切表策略切分

2. 将切分后的文件并发导入到对应的Mongodb中

3. 生成日志文件和done标识文件

使用手册:

-h    打印帮助信息,并退出";

-f     需要切分的数据文件";

-g    清理昨日或历史全部数据: 1 昨日数据  2 历史全部数据";

-k     拆分字段在文件中列数,从1开始";

-o    需要切分的数据文件格式 tsv或csv ";

-d    切分的库数目";

-t     切分的表数目";

-m   切分后,需要入库的mongodb未拆分库名,比如拆分前cpc, 拆分后cpc_01";

-c    切分后,需要入库的mongodb未拆分库名,比如拆分前cpc, 拆分后cpc_0102";

-a    入库fieldFile";

-p    配置文件",

使用步骤:

1. 在配置文件中设置日志、切割后数据临时路径$LOG_HOME 和 $DATA_SPLIT_HOME目录,如果不存在,则手动创建;

在配置文件中设置目标Mongodb参数信息,用来作为导入数据的目标库;

在配置文件中设置Mongodb程序的主目录$MONGO;

2. 按照具体的参数意义,仿照下面的格式执行脚本:

举例:./mongo-split-importer.sh -f /data/shell/test.ata -g 1 -o tsv -k 3 -d 3 -t 3 -m idea -c idea -p ../conf/demeter_conf_qa.sh -a ../conf/idea-head-file

-f 切分目标文件   -o 文件格式 tsv    -k 切割字段,第三个  -d 切割成3个库 -t 每个库3个表

-m 导入的mongodb未拆分名称idea -c 导入的mongodb未拆分表名idea -p 环境配置文件 -a 导入目标表的fieldFile文件 -g 清理昨日数据

mongo-split-importer.sh执行脚本:

#!/bin/bash
SPLITFILE="" #目标切割文件
FILEFORMAT="" # 目标切割文件格式 , \t
FILEFORMATNAME="" #切割目标文件格式名称 csv tsv
SPLITKEY=1
SPLITDBNUM="" #目标切割库数目
SPLITTBNUM="" #目标切割表数目
IMPORTDBNAME="" # 目标入库未分割库名
IMPORTTBNAME="" #目标入库未切割表名
PROFILE="" #配置文件
FIELDFILE="" #入库fieldFile
CLEAN=0  #清理数据, 0:默认不清理, 1 : 清理昨日的数据    2: 清理所有以前的数据
SPILTTMPDIR="" #目标切割文件存放临时目录
FULLPATH=$(cd `dirname $0`;pwd -P)
SCRIPTFILE=`basename $0`
TOTLE_RECORD_NUM=0 #文件切割前的记录条目
SUBFILE_RECORD_NUM=0 #切割后所有文件汇总的记录条目
_mongo_count="-1"
#------------------------------------------------函数---------------------------------------------------------------
function usage(){echo "$SCRIPTFILE - 分库分表后将数据导数据到mongodb"echo "SYNOPSIS"echo "OPTIONS" echo "  -h    打印帮助信息,并退出";echo "  -f     需要切分的数据文件";echo "  -g    是否清理历史数据,默认不清理   1:清理昨日数据  2:清理以前所有数据";echo "  -k     拆分字段在文件中列数,从1开始";echo "  -o    需要切分的数据文件格式 tsv或csv ";echo "  -d    切分的库数目";echo "  -t     切分的表数目";echo "  -m   切分后,需要入库的mongodb未拆分库名,比如拆分前cpc, 拆分后cpc_01";echo "  -c    切分后,需要入库的mongodb未拆分库名,比如拆分前cpc, 拆分后cpc_0102";echo "  -a    入库fieldFile";echo "  -p    配置文件,绝对或相对路径文件",exit
}
function setFileFormat(){FILEFORMATNAME=$1case $1incsv)  FILEFORMAT=",";;tsv)   FILEFORMAT="\t";;*) echo "unknow profile -o $1"; usage;;esac
}
while getopts ':hf:g:o:k:d:t:a:p:m:c:' OPTION
docase $OPTIONinh) usage;;f) SPLITFILE=$OPTARG;;g)CLEAN=$OPTARG;;o) setFileFormat $OPTARG;;k) SPLITKEY=$OPTARG;;d) SPLITDBNUM=$OPTARG;;t) SPLITTBNUM=$OPTARG;;a) FIELDFILE=$OPTARG;;p) PROFILE=$OPTARG;;m) IMPORTDBNAME=$OPTARG;;c) IMPORTTBNAME=$OPTARG;;:) echo "选项 \"-$OPTARG\" 后面缺少对应值, 将使用默认值";;\?)echo " 错误的选项 -$OPTARG, 将退出"; usage;;esac
done
#记录日志信息
function logInfo(){echo "[`date +"%Y-%m-%d %H:%M:%S"`] $@ " | tee -a $LOGFILE
}
function checkError(){if [ $? -ne 0 ]; thenecho "[`date +"%Y-%m-%d %H:%M:%S,%s"`][$SCRIPTFILE, $$] ERROR OCCURS! - $1" | tee -a $ERRORFILEexit 1;fi
}
function check_ready() {tmp_done_file=`printf "$reportDoneFile" "$TABLE" "$1"`while [ "$isok" = "false" ]; dorsync  --list-only ${tmp_done_file}if [ $? -eq 0 ]; thenisok="true";break;fiif [ "$isok" = "false" ]; thensleep 300fitime_now=`date  +%s`if [ `expr ${time_now} - ${time_start}` -ge $max_interval ]; thenreturn 255;fidonereturn 0;
}
#从数据库列表里选择主库
function selectMongoMaster(){tmp="TARGET_MONGO_HOST_LIST_0$1"TMP_HOST=${!tmp}echo $TMP_HOST#replica setfor DUBHE_MONGO_HOST in $TMP_HOST; doif [ $? -eq 0 ] ; thenbreak;fidone# single server#for DUBHE_MONGO_HOST in $TMP_HOST; do#TARGET_MONGO_HOST=$DUBHE_MONGO_HOST#echo $TARGET_MONGO_HOST#done
}
#切割
function split() {logInfo "spilt data file"echo "split db num"$SPLITDBNUMecho "split tb num"$SPLITTBNUMecho "Start to split file: "$SPLITFILEawk 'BEGIN {FS="'${FILEFORMAT}'";}ARGIND==1{#分库分表DBN=$'${SPLITKEY}' % '${SPLITDBNUM}' + 1;TBN=int($'${SPLITKEY}' / '${SPLITDBNUM}')TBN=TBN % '${SPLITTBNUM}' + 1;DBN="0"DBN;TBN="0"TBN;print $0 > "'${SPILTTMPDIR}'""/""'${IMPORTTBNAME}'""_"DBN""TBN}END {}' ${SPLITFILE};ls $SPILTTMPDIRecho "Split file successfully : "$SPLITFILE
}
#导入
function import() {#importDatalocal iter=1;while [ $iter -le $SPLITDBNUM ]; dothread_import $iter &iter=`expr $iter + 1`done#wait for child-threadswait;
}
#导入子线程
function thread_import() {local num=1;targetFileName=$IMPORTTBNAME"_0"$1"0"$numtargetFile=$SPILTTMPDIR/$IMPORTTBNAME"_0"$1"0"$numtargetDB=$IMPORTDBNAME"_0"$1targetCollection=$IMPORTTBNAME"_0"$1"0"$numif [ ! -f $targetFile ]; thenlogInfo "spilt file does not exits : " $targetFilenum=`expr $num + 1`continuefiuser="TARGET_MONGO_USER_0"$1TMP_USER=${!user}password="TARGET_MONGO_PWD_0"$1TMP_PASSWORD=${!password}#选择master   selectMongoMaster $1;#clean dirty dataif [ $CLEAN -gt 0  ]; thenlogInfo "$qdate $targetDB.$targetCollection cleaning up dirty data in mongodb"clean_dirty_datacheckError "whether error occurs during cleaning dirty data from mongodb"fi#import dataimport2mongo $1 $targetFile  $targetDB  $targetCollection#record done filestatusfile="$STATUS_LOG_HOME/$targetFileName.done.`date -d $qdate +"%Y-%m-%d"`"touch $statusfilenum=`expr $num + 1`donelogInfo "thread $1 ends"
}
#把指定的文件导到指定的库指定的表,并建立索引,mongodb自身会判断索引是否存在
#不存在的情况下才创建新索引
function import2mongo(){if [ "$FIELDFILE" != "" ]; thenMONGO_FIELD_FILE=$FIELDFILEelseMONGO_FIELD_FILE=$FULLPATH/../conf/${IMPORTTBNAME}-head-filefiDATAFILE=$2if [ ! -f $DATAFILE ]; thenlogInfo "mongodb [${DB}.${COLL}] imported 0 objects"return 0fiTMPLOGFILE=$INFO_LOG_HOME/$DB.$COLL.tmp.logtmp=$?if [ "$tmp" != "0" ]; thenreturn $tmpfi#data check_mongo_count=`tail $TMPLOGFILE | grep imported`_mongo_count=`expr 0$_mongo_count + 0`#start to ensure indexensureIndexlogInfo "mongodb [${DB}.${COLL}] imported $_mongo_count objects"return $tmp
}
function ensureIndex(){
}
#垃圾数据清理
function clean_dirty_data(){day=`date -d ${1:-' -1day'} +"%y%m%d"`if [ $CLEAN -eq 1  ]; then_mongo_condition="{\"_id\":{\"\$gte\":\"${day}_0\",\"\$lte\":\"${day}_9\"}}"else_mongo_condition="{\"_id\":{\"\$lte\":\"${day}_9\"}}"filogInfo "waiting for the clean task.."echo  $_mongo_conditiontmp=$?if [ "$tmp" != "0" ]; thenreturn $tmpfisleep 5slogInfo "dirty data cleaned: "$targetDB  $targetCollection  $dirtyCountecho "dirty data cleaned: "$targetDB  $targetCollection  $dirtyCountreturn $tmp
}
#parameter check
function checkParams() {if [ 1 -ne $CLEAN -a 2 -ne $CLEAN ]; thenlogInfo "-g the parameter clean is not in [1, 2] : "$CLEANreturn 1;fiif [  $FILEFORMAT != "," -a  $FILEFORMAT != "\t"  ]; thenlogInfo "-o the parameter file format  is not in [csv, tsv] : "$FILEFORMATreturn 1;fiif [ $SPLITKEY -lt 1 ]; thenlogInfo "-k split key must not be less  than 1 : "$SPLITKEYreturn 1;fiif [ $SPLITDBNUM -lt 1 ]; thenlogInfo "-d database number must not  be less  than 1 : "$SPLITDBNUMreturn 1;fiif [ $SPLITTBNUM -lt 1 ]; thenlogInfo "-t collection number must not  be less  than 1 : "$SPLITTBNUMreturn 1;fiif [ ! -f  $FIELDFILE ];  thenlogInfo "-a field file is not a common file or not exits : "$FIELDFILEreturn 1;fiif [ "" = $IMPORTDBNAME ] ; thenlogInfo "-m import  database name is empty  : "$IMPORTDBNAMEreturn 1;fiif [ "" = $IMPORTTBNAME ] ; thenlogInfo "-m import  table name is empty  : "$IMPORTTBNAMEreturn 1;fi
}
#主函数
function main() {set +xecho "check split file and profile: " $SPLITFILE   $PROFILEif [ ! -f  $SPLITFILE ];  thenecho  "-f split file is not a common file or not exits : "$SPLITFILEreturn 1;fiif [ ! -f  $PROFILE ];  thenecho  "-p profile file is not a common file or not exits : "$PROFILEreturn 1;fisource $PROFILEqdate=`date +"%Y-%m-%d"`last_day=`date -d "-1day" +"%Y-%m-%d"`BASEFILENAME=$(basename $SPLITFILE)echo "base split file name is : "$BASEFILENAMEif [ ! -d $LOG_HOME ] ; thenlogInfo  " log home  is not a common directory or not exits : "$LOG_HOMEreturn 1;fiLOGFILE=$INFO_LOG_HOME/$BASEFILENAME.$qdate.logif [ -f $LOGFILE ]; thenmv $LOGFILE $LOGFILE.$last_dayfitouch $LOGFILEERRORFILE=$ERROR_LOG_HOME/$BASEFILENAME.error.logif [ -f $ERRORFILE ]; thenmv $ERRORFILE $ERRORFILE.$last_dayfitouch $ERRORFILE#空行echoechologInfo "start to check parameters!"checkParamscheckError "whether error occurs during check parameters : $SPLITFILE"#空行echoechologInfo "start to split file: "$SPLITFILEif [ ! -d $DATA_SPLIT_HOME ] ; thenlogInfo  " data split home  is not a common directory or not exits : "$DATA_SPLIT_HOMEreturn 1;fiSPILTTMPDIR=$DATA_SPLIT_HOME/$BASEFILENAMEecho "split temple directory : "$SPILTTMPDIRif [ -d ${SPILTTMPDIR} ]; thenrm -rf ${SPILTTMPDIR}fimkdir -p ${SPILTTMPDIR}splitcheckError "whether error occurs during split data : $SPLITFILE"logInfo "split data completely : $SPLITFILE"statusfile=$STATUS_LOG_HOME/$BASEFILENAME".split.done."$qdatetouch  ${statusfile}#空行echoechologInfo "start to import split  file to mongodb"importlogInfo "import data completely : $SPLITFILE"statusfile=$STATUS_LOG_HOME/$BASEFILENAME".import.done."$qdatetouch  ${statusfile}#空行echoecho#remove temple directory#       if [ -d ${SPILTTMPDIR} ]; then#               rm -rf ${SPILTTMPDIR}#       fi
}
#-------------------------------------------------入口----------------------------------------------------------------
source /etc/profile

demeter_conf_cpc_qa.sh 脚本:

#!/bin/bash
source /etc/profile
#logger path
INFO_LOG_HOME="${LOG_HOME}/info"
STATUS_LOG_HOME="${LOG_HOME}/status"
if [ ! -d $ERROR_LOG_HOME ]; then
if [ ! -d $INFO_LOG_HOME ]; thenmkdir -p $INFO_LOG_HOME
fi
if [ ! -d $STATUS_LOG_HOME ]; thenmkdir -p $STATUS_LOG_HOME
fi
if [ ! -d $DATA_HOME ]; thenmkdir -p $DATA_HOME
fi
#data path for source  and target data path
DATA_SPLIT_HOME=/data/demeter/sdata
#import target mongodbs
TARGET_MONGO_PORT_01=XXX
TARGET_MONGO_USER_01=XXX
TARGET_MONGO_PWD_01=XXX
TARGET_MONGO_HOST_LIST_01="test01.mongodb01:$TARGET_MONGO_PORT_01 test01.mongodb02:$TARGET_MONGO_PORT_01 test01.mongodb03:$
TARGET_MONGO_PORT_01"
TARGET_MONGO_PORT_02=XXX
TARGET_MONGO_USER_02=XXX
TARGET_MONGO_PWD_02=XXX
TARGET_MONGO_HOST_LIST_02="testt02.mongodb01:$TARGET_MONGO_PORT_02 test02.mongodb02:$TARGET_MONGO_PORT_02 test02.mongodb03:$
TARGET_MONGO_PORT_02"
TARGET_MONGO_PORT_03=XXX
TARGET_MONGO_USER_03=XXX
TARGET_MONGO_PWD_03=XXX
TARGET_MONGO_HOST_LIST_03="test03.mongodb01:$TARGET_MONGO_PORT_03 test03.mongodb02:$TARGET_MONGO_PORT_03 test03.mongodb03:$
TARGET_MONGO_PORT_03"
#mongodb utils
MONGO=/opt/mongodb

xuri-cpc-head-file

a
b
c
d
e
f
g
h
i
j
k
l
m
n
0
p
q
r
s

host:

XX.XX.XX.XX  test01.mongodb01
XX.XX.XX.XX  test01.mongodb02
XX.XX.XX.XX  testt01.mongodb03
XX.XX.XX.XX  test02.mongodb01
XX.XX.XX.XX  test02.mongodb02
XX.XX.XX.XX  test02.mongodb03
XX.XX.XX.XX  test03.mongodb01
XX.XX.XX.XX  test03.mongodb02
XX.XX.XX.XX  test03.mongodb03

转载于:https://blog.51cto.com/andashu/1390092

mongodb拆库分表脚本相关推荐

  1. Springboot2.x +JPA 集成 Apache ShardingSphere 同库分表

    分库分表背景: 数据库性能瓶颈:主要分为按照业务来划分或者按照数据量来划分. 拆分方式: 水平拆分(每个表的结构都一样):订单表数据量大,我们可以水平拆分 ,分成order表1.order表2.ord ...

  2. MySQL-分库分表初探

    文章目录 生猛干货 官方文档 主从复制 解决不了 主节点DB写的的压力 常见的分库分表的方式 分库 分表 DB分片前的准备 如何选择分区键 ,尽量避免跨分片查询 如何存储无需分片的表 如何在节点上部署 ...

  3. mysql 多张表公用一个序列_Mysql--序列3--分库分表策略

    分库分表是存储层设计中一个普遍而重大的问题,什么时候分?怎么分?分完之后引发的新问题,比如不能Join.分布式事务? 本篇将从最基本的策略出发,逐步深入讲解这里面涉及的一序列策略. 分库-业务分拆 & ...

  4. mysql---分库分表

    一. 相关概念 1)什么是分库分表 将存放在一台数据库服务器中的数据,按照特定方式进行拆分, 分散存放到多台数据库服务器中,以达到分散单台服务器负载的效果 2)分库分表分割方式 垂直分割(纵向切分) ...

  5. 95-分库分表技术之ShardingJDBC

    分库分表技术之ShardingJDBC ShardingJDBC: 回顾上一章的分库分表方式: 分库分表的目的就是将我们的单库的数据控制在合理范围内,从而提高数据库的性能 垂直拆分(按照结构分): 垂 ...

  6. hive动态分区shell_Hive/Shell 创建Hive 库 ,表脚本,Hive 动态增加分区脚本

    最近工作中使用到了Hive,  并对Hive 的数据库,表完成创建. 创建的表为分区表,也涉及到了分区表 的按天动态增加分区. 代码组织结构: 创建数据库: create_dmp.hql --dmp ...

  7. mysql-分库分表概述

    分库分表概述 互联网系统需要处理大量用户的请求.比如微信日活用户破10亿,海量的用户每天产生海量的数量:美团外卖,每天都是几千万的订单,那这些系统的用户表.订单表.交易流水表等是如何处理呢? 数据量只 ...

  8. mysql-分库分表方案

    垂直拆分比较简单,也就是本来一个数据库,数据量大之后,从业务角度进行拆分多个库.如下图,独立的拆分出订单库 和 用户库. 水平拆分的概念,是同一个业务数据量大之后,进行水平拆分. 上图中订单数据达到了 ...

  9. MySQL----分库分表

    参考:https://mp.weixin.qq.com/s?__biz=MzI5MzYzMDAwNw==&mid=2247487130&idx=2&sn=7d384ef9ca4 ...

最新文章

  1. Go对Python产生的冲击
  2. Openstack_通用模块_Oslo_vmware 创建/删除 vCenter 虚拟机
  3. 成功导入并运行breeze jar库
  4. C# 控件缩写大全+命名规范+示例
  5. 揭秘更加开放的数据库服务:阿里云数据库专属集群
  6. 1704班3组—高级软件测试作业—如何计算团队成员贡献分
  7. java多态的好处_java萌新,对象的多态有什么好处?
  8. 马斯克称自己可能染上中度新冠肺炎
  9. nginx trac mysql svn_nginx+php+mysql+svn+http
  10. drawboard pdf拆分文件_掌握在线PDF拆分技巧,从此打开文件不再处于“加载中”...
  11. Hue中Sqoop导数报错Could not load db driver class: com.mysql.jdbc.Driver
  12. linux pv命令,pv命令 – 管道查看器
  13. spidev 驱动 probe 获取 dts 节点参数
  14. golang清空切片
  15. linux 蓝牙打印机驱动安装失败,win10蓝牙驱动安装失败的最佳解决方法
  16. 老宇哥带你玩转ESP32,12篇基础教程已经更新完毕,接下来是进阶教程
  17. 使用Audacity制作ACX有声读物 ACX Audiobook Production Using Audacity
  18. 微信支付-vue 实现微信支付-前端篇
  19. python基础-PyYaml操作yaml文件
  20. js 中文转拼音缩写

热门文章

  1. 五张动图,看清神经机器翻译里的Attention!
  2. 无人驾驶汽车想要“普渡众生”,还要经历15个磨难
  3. 吴恩达机器学习笔记 —— 10 神经网络参数的反向传播算法
  4. 我们不知道答案的125个科学问题(16)群体合作行为的演化
  5. ​Arm芯片的新革命在缓缓上演
  6. 国家脑库:神经科学研究的基础设施
  7. 学界 |《nature》杂志:我们有义务搞懂我们所创造出来的技术
  8. 清华自动驾驶前沿报告!解密六大关键技术,全球人才分布【附下载】| 智东西内参...
  9. Google提出新型学习范式「Deep Memory」,或将彻底改变机器学习领域
  10. Nature Human Behavior:大脑对不公平的反应有助预测抑郁症