MENU

Shell多进程并发执行

November 15, 2020 • Linux运维工作

有一个需求,需要迁移大量数据库,并且数据库都并不大,需要快速的将其全量迁移过去。

这里通过Shell脚本多进行进行,这里记录一下,后续有其他需要进行多线程的也可以随便改一下就可以用。

#!/bin/bash
# MySQL 迁移正式脚本
start_time=`date +%s`
#创建有名管道
[ -e /tmp/fd1 ] || mkfifo /tmp/fd1
#创建文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的所有特性
exec 3<>/tmp/fd1
#关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除,我们留下文件描述符来用就可以了
rm -rf /tmp/fd1
# i=5 5个并发
for ((i=1;i<=5;i++))
do
        #&3代表引用文件描述符3,这条命令代表往管道里面放入了一个"令牌"
        echo >&3
done
# 打开迁移文件,逐行执行
data=`cat /data/mysql-move/0-mysql-move-last.txt`
IFS=$'\n'
for i in $data
do
#代表从管道中读取一个令牌
read -u3
{
        start_time_two=`date +%s`
        echo $i | sh
        stop_time_two=`date +%s`
        if [ $? -ne 0 ];then
                echo ${i}导入失败 >> /data/mysql-move/logs/move-error.log
                echo "TIME:`expr $stop_time_two - $start_time_two` s" >> /data/mysql-move/logs/move-error.log
        else
                echo ${i}导入成功 >> /data/mysql-move/logs/move-succes.log
                echo "TIME:`expr $stop_time_two - $start_time_two` s" >> /data/mysql-move/logs/move-succes.log
        fi
                #代表我这一次命令执行到最后,把令牌放回管道
        echo >&3
}&
done
wait
stop_time=`date +%s`
echo "TIME:`expr $stop_time - $start_time`" > /data/mysql-move/logs/time.txt
#关闭文件描述符的读
exec 3<&-
#关闭文件描述符的写
exec 3>&-

上图的脚本中,有用到这样一个文件,这个文件其实就是我把 需迁移的库 与 目标库的命令组成每行的Shell命令。

例如

mysqldump -h x.x.x.x -P 3306 -uUser -pPasswd  database1 > database1.sql && mysql -h y.y.y.y -P 3306 -uUser2 -PPasswd2 < database1 && echo "database1 导入成功" >> /data/mysql-move/logs/succes.log && rm -f database1.sql || echo "database1 导入失败" >> /data/mysql-move/logs/error.log && rm -f database1.sql
mysqldump -h x.x.x.x -P 3306 -uUser -pPasswd  database2 > database2.sql && mysql -h y.y.y.y -P 3306 -uUser2 -PPasswd2 < database2 && echo "database2 导入成功" >> /data/mysql-move/logs/succes.log && rm -f database2.sql || echo "database2 导入失败" >> /data/mysql-move/logs/error.log && rm -f database2.sql
mysqldump -h x.x.x.x -P 3306 -uUser -pPasswd  database3 > database1.sql && mysql -h y.y.y.y -P 3306 -uUser3 -PPasswd3 < database3 && echo "database3 导入成功" >> /data/mysql-move/logs/succes.log && rm -f database3.sql || echo "database3 导入失败" >> /data/mysql-move/logs/error.log && rm -f database3.sql
Last Modified: December 19, 2020