linux 自动备份mysql


自动备份mysql分为两步:第一步执行脚本的撰写,第二步定时任务的设置。

执行脚本,前面几个都是初级过程,整合后直接看导入导出结合的终极脚本(export和import)这部分即可。

定时任务,定时执行这个脚本即可。

单脚本文件备份(导出)

#!/bin/bash
dbhost='127.0.0.1'
dbport='3306'
dbname='数据库名'
dbuser='用户名'
dbpass='密码'
bakdir='/datas/backup/mysql/'
ctime=$(date +'%Y%m%d%H%M%S')
filepath="${bakdir}${dbname}_${ctime}.sql.gz"
echo 'backuping databases:'$dbname
mysqldump -h$dbhost -p$dbport -u$dbuser -p$dbpass $dbname | gzip > $filepath
echo 'success filepath:'$filepath

脚本和配置文件结合(导出export)

#!/bin/bash
dbname='数据库名'
baseDir='./'
workTime=$(date +'%Y%m%d%H%M%S')
filePath="${baseDir}bak_${dbname}_${workTime}.sql.gz"

echo 'backuping databases:'$dbname
mysqldump --defaults-extra-file=dbworker.conf $dbname | gzip > $filePath
echo 'success to path:'$filePath

脚本和配置文件结合(导入import)

#!/bin/bash

if [ -z $1 ] || [ ! -f $1 ]
then
    echo "which is .sql.gz"
    exit 1
fi

fileZip=`basename $1`
fileExt=${fileZip##*.}
if [ $fileExt != 'gz' ]
then
    echo 'file ext not .sql.gz'
    exit 1
fi

dbname='amazon'
baseDir='./'

fileSql=${fileZip%.*}
echo 'unzip file...'
gzip -dc $baseDir$fileZip > $baseDir$fileSql

echo 'import sql file...'

mysql --defaults-extra-file=./dbworker.conf $dbname < $baseDir$fileSql

if [ -f $baseDir$fileSql ]
then
    echo 'del file:'$baseDir$fileSql
    rm -f $baseDir$fileSql
fi
echo 'complete'

配置文件dbworker.conf(放在dbworker.sh同级)

[mysqldump]
max_allowed_packet=500M
host=127.0.0.1
user=root
password=数据库密码
[mysql]
host=127.0.0.1
user=root
password=数据库密码

导入导出结合的终极脚本dbworker.sh(export和import)

#!/bin/sh
#
# mysql dump

### BEGIN INTRO INFO
# TIME:20200907
# AUTHOR: KC
### END INTRO INFO

BASEDIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd);
SAVEDIR="${BASEDIR}/bakfiles/"
BASECONF="${BASEDIR}/dbworker.conf"
TIMESTAMP=$(date +'%Y%m%d%H%M%S')

if [ ! -d $SAVEDIR ];then
  mkdir $SAVEDIR
fi

if [ ! -f $BASECONF ];then
    echo "dbworker.conf not exists"
    exit 1
fi


case "$1" in
    export)
        echo BEGIN_TIME:$(date +'%Y-%m-%d %H:%M:%S')
        if [ ! -f $2 ]
        then
            FILEPATH="${SAVEDIR}bak_${2}_${TIMESTAMP}.sql.gz"
            echo 'backuping databases:'$2
            mysqldump --defaults-extra-file=$BASECONF --set-gtid-purged=off $2 | gzip > $FILEPATH
            echo 'success to path:'$SAVEDIR
            ls -sh ${SAVEDIR} |grep "${TIMESTAMP}.sql.gz"
        else
            echo "dbname require"
            exit 1
        fi
        echo END_TIME:$(date +'%Y-%m-%d %H:%M:%S')
        ;;

    import)
        echo BEGIN_TIME:$(date +'%Y-%m-%d %H:%M:%S')
        FILEPATH="${SAVEDIR}${2}"
        if [ -z $FILEPATH ] || [ ! -f $FILEPATH ] || [ -z $3 ]
        then
            echo "which is .sql.gz or dbname"
            exit 1
        fi
        FILEZIP=`basename $FILEPATH`
        fileExt=${FILEZIP##*.}
        if [ $fileExt != 'gz' ]
        then
            echo 'file ext not .sql.gz'
            exit 1
        fi
        TMPSQL=$BASEDIR/${FILEZIP%.*}
        echo 'unziping file...'
        gzip -dc $FILEPATH > $TMPSQL
        echo 'import sql file...'
        mysql --defaults-extra-file=$BASECONF $3 < $TMPSQL
        if [ -f $TMPSQL ]
        then
            echo 'del file:'$TMPSQL
            rm -f $TMPSQL
        fi
        echo 'complete'
        echo END_TIME:$(date +'%Y-%m-%d %H:%M:%S')
        ;;

    dbs)
        DATABASES=$(mysql --defaults-extra-file=$BASECONF -e "show databases" | grep -Ev "Database|sys|information_schema|performance_schema|mysql")
        for db in $DATABASES
        do
            echo $db
        done
        ;;

        
    clear)
        if [ -z $2 ]
        then
            echo "how long days to clear"
            exit 1
        fi
        find $SAVEDIR -type f -mtime +$2 | xargs rm -f
        ;;

    *)
        echo "DBWORKER DEFAULT USAGE e.g.:"
        echo "$ sh dbworker.sh dbs"
        echo "$ sh dbworker.sh export dbname"
        echo "$ sh dbworker.sh import xxx.sql.gz dbname"
        echo "$ sh dbworker.sh clear 30"
        ;;
esac

克隆转移数据库

这个其实就是上面导入导出的几个命令合并而已:

配置好导出和导入的conf之后,确定好数据库:
执行导出:sh dbworker.sh export DATABASENAME
执行导入:sh dbworker.sh import bak_DATABASENAME_20200911223344.sql.gz DATABASENAME

导出数据库

mysqldump -u root -p db_name > test_db.sql

导出数据表:

mysqldump -u root -p test_db users> test_users.sql

导入数据库

mysql进入它的命令行后,show databases,然后use选中数据库,最后执行下述命令即可:
source /path/to/db.sql

其它

如果遇到Warning: A partial dump from a server that has GTIDs will by default include错误,是因为加入的全局事务ID来强调主备一致性:
加参数--set-gtid-purged=off即可

最后,真的不想用mysql了,哪怕是mysql8+,新配置的服务都转战mariadb10+
如果用本备份脚本遇到[ERR] 1273 - Unknown collation: 'utf8mb4_0900_ai_ci'排序字符集问题,则可以套公式解决:

对gz进行解压为sql文件
# gzip -dc bakfiles/aaa.sql.gz > bbb.sql
批量修改排序字符集
# sed -i "s/utf8mb4_0900_ai_ci/utf8mb4_general_ci/g" tt.sql
导入脚本
# mysql --defaults-extra-file=dbworker.conf 库名 < bbb.sql
成功

原文链接:https://blog.yongit.com/note/573002.html