MySQL定时备份及清理脚本(一劳永逸)-改良版本

时间:2024-02-16 19:31:36

一 创建备份路径

        cd /mysql-backup

        mkdir back

        cd back

二 创建日志文件

        vi mysql-backlog.log

        内容为空,保存

三 创建备份脚本

vi save-all-data.sh

#!/bin/bash
#source /etc/profile
user="root"
password="LXYlxy2:024.#8u}"
host="127.0.0.1"
port="3306"
db=("test" "test3" "test4" "test9")       #数组表示要备份的数据库
local="--single-transaction"
mysql_path="/usr/local/mysql/bin/mysql"   #Mysql命令路径
backup_path="/mysql-backup/data"          #备份文件存储路径
date=$(date +%Y%m%d_%H%M%S)               #备份文件添加时间戳
day=30                                    #定义保存备份天数
backup_log="/mysql-backup/back/mysql-backlog.log"   #备份日志文件路径

if [ ! -e $backup_path ];
 then
 mkdir -p $backup_path
fi
find $backup_path -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1  #/dev/null为特殊设备,输入到该设备内容都会被丢弃,2>:将标准错误输出重定向,$1:标准错误输出到与标准输出相同的地方,结合:将命令的标准输出和标准错误输出都丢弃,不会显示到屏幕和记录到文件中。
echo "开始备份数据库: ${db[*]}"
#使用循环遍历db数组中所有的数据库,调用自定义backup_sql函数备份
backup_sql(){              
dbname=$1          #将函数backup_sql的第一个参数赋值给dbname,即为以下的length
backup_name="${dbname}_${date}.sql"
#--flush-logs:备份前刷新二进制日志,-R:备份时要包括存储过程和函数,保证还原数据完整
/usr/local/mysql/bin/mysqldump -h $host -P $port -u $user -p$password  --default-character-set=utf8 --socket=/data/mysql/tmp/mysqld.sock --flush-logs -R $dbname > $backup_path/$backup_name
if [[ $? == 0 ]];     #$?获取上一个命令退出状态,0为成功,非0为失败
 then
  cd $backup_path
  tar -czvf $backup_name.tar.gz $backup_name --force-local   #只访问本地文件,本地压缩
  size=$(du $backup_name.tar.gz -sh | awk '{print $1}')
  rm -rf $backup_name
  echo "$date 备份 $dbname($size) 成功"
else
 cd $backup_path
 rm -rf $backup_name
 echo "$date 备份 $dbname 失败"
fi
}
#先自定义函数,在调用,这里for循环次数由数据库个数决定,backup_sql第一个传递参数$length
length=${#db[@]}     #@获取整个数组的元素,#为获取数据长度,结合起来:返回db中元素个数
for ((i=0;i<$length;i++));do
backup_sql ${db[i]} >> $backup_log 2>&1
done
echo "备份结束,结果查看 $backup_log"
du $backup_path/*$date* -sh | awk '{print "文件:" $2 ",大小:" $1}'   #使用swk切割管道符前命令的第一和二字段

四 脚本赋权,linux自带定时任务工具配置
     

chmod +x save-all-data.sh


        crontab用法:

                crontab -e 编辑工作表

                crontab -l 列出工作表中的命令

                crontab -r 删除工作表

        HELL=/bin/bash

        00 01 * * * /mysql-backup/back/save-all-data.sh

        sed -i 's/\r//g' 命令可以格式化sh文件,用法为:sed -i 's/\r//g' xxx.sh

        save-all-data.sh 指定12:20和01:00定时间点执行,数据库异地备份

        :wq保存文件即可

五 脚本改进:1.按天数区分备份数据2.自动遍历需要备份的数据库 

以下为改良1

#!/bin/bash
#source /etc/profile
user="root"
password="LXYlxy2:024.#8u}"
host="127.0.0.1"
port="3306"
db=("test" "test3" "test4" "test9")       #数组表示要备份的数据库
local="--single-transaction"
mysql_path="/usr/local/mysql/bin/mysql"   #Mysql命令路径
backup_path="/mysql-backup/data"          #备份文件存储路径
date=$(date +%Y%m%d_%H%M%S)               #备份文件添加时间戳
day=30                                    #定义保存备份天数
backup_log="/mysql-backup/back/mysql-backlog.log"   #备份日志文件路径

#if [ ! -e $backup_path ];
# then
# mkdir -p $backup_path
#fi
#############改进1:区分每一天的备份文件###################### 
current_date=$(date +%Y%m%d)  # 获取当前日期
daily_backup_path="$backup_path/$current_date"  # 每天备份目录
#只需要将后续使用到$backup_path替换成daily_backup_path,上面的可注释掉
if [ ! -e $daily_backup_path ]; then
 mkdir -p $daily_backup_path
fi
##############################################################

find $backup_path -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1  #/dev/null为特殊设备,输入到该设备内容都会被丢弃,2>:将标准错误输出重定向,$1:标准错误输出到与标准输出相同的地方,结合:将命令的标准输出和标准错误输出都丢弃,不会显示到屏幕和记录到文件中。
echo "开始备份数据库: ${db[*]}"
#使用循环遍历db数组中所有的数据库,调用自定义backup_sql函数备份
backup_sql(){              
dbname=$1          #将函数backup_sql的第一个参数赋值给dbname,即为以下的length
backup_name="${dbname}_${date}.sql"
#--flush-logs:备份前刷新二进制日志,-R:备份时要包括存储过程和函数,保证还原数据完整
/usr/local/mysql/bin/mysqldump -h $host -P $port -u $user -p$password  --default-character-set=utf8 --socket=/data/mysql/tmp/mysqld.sock --flush-logs -R $dbname > $daily_backup_path/$backup_name
if [[ $? == 0 ]];     #$?获取上一个命令退出状态,0为成功,非0为失败
 then
  cd $daily_backup_path
  tar -czvf ${backup_name}.tar.gz $backup_name --force-local   #只访问本地文件,本地压缩
  echo " $?"            #调试:tar命令执行成功,但是一直没有.tar.gz包
  size=$(du ${backup_name}.tar.gz -sh | awk '{print $1}')
   rm -rf $backup_name
  echo "$date 备份 $dbname($size) 成功"
else
 cd $daily_backup_name
 rm -rf $backup_name
 echo "$date 备份 $dbname 失败"
fi
}
#先自定义函数,在调用,这里for循环次数由数据库个数决定,backup_sql第一个传递参数$length
length=${#db[@]}     #@获取整个数组的元素,#为获取数据长度,结合起来:返回db中元素个数
for ((i=0;i<$length;i++));do
backup_sql ${db[i]} >> $backup_log 2>&1
done
echo "备份结束,结果查看 $backup_log"
du -sh $daily_backup_path/*${date}*   | awk '{print "文件:" $2 ",大小:" $1}'   #使用swk切割管道符前命令的第一和二字段

改良2: 

#!/bin/bash
#source /etc/profile
user="root"
password="LXYlxy2:024.#8u}"
host="127.0.0.1"    #要给root权限,host三种设置:1.localhost:本地主机连接(默认) 2.%:所有主机 3.固定IP,这里要给root的host权限设置为2或3,否则下面使用-h 选项会报错
port="3307"
#db=("test" "test3" "test4" "test9")       #数组表示要备份的数据库
#db=($($mysql_path -h $host -P $port -u $user -p$password -e "SHOW DATABASES;" | grep -Ev "Database|information_schema|performance_schema|sys"))
#db放在这里,执行的时候会一直报错为找-h -p -u命令,这是因为脚本是按顺序下来执行

local="--single-transaction"
mysql_path="/usr/local/mysql/bin/mysql"   #Mysql命令路径
#db=($($mysql_path -h $host -P $port -u $user -p$password -e "SHOW DATABASES;" | grep -Ev "information_schema|performance_schema|sys"))
#标准输出提示mysql[warning],2>/dev/null 来将标准错误输出重定向到 /dev/null,从而将这个警告信息忽略
#db=($($mysql_path -h $host -P $port -u $user -p$password -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "information_schema|performance_schema|sys"))
#shell脚本中,使用$(命令)来执行命令返回结果,和`命令`效果一样--在shell脚本中,数组存储方式:1.括号赋值 数组=(),2.逐个赋值a[0]="12"3.通过命令的输出来赋值 4.使用declare声明关联数组
db=(`$mysql_path -h $host -P $port -u $user -p$password -e "SHOW DATABASES;" 2>/dev/null | grep -Ev "information_schema|performance_schema|sys"`)
backup_path="/mysql-backup/data"          #备份文件存储路径
date=$(date +%Y%m%d_%H%M%S)               #备份文件添加时间戳
day=30                                    #定义保存备份天数
backup_log="/mysql-backup/back/mysql-backlog.log"   #备份日志文件路径

#if [ ! -e $backup_path ];
# then
# mkdir -p $backup_path
#fi
#############改进1:区分每一天的备份文件###################### 
current_date=$(date +%Y%m%d)  # 获取当前日期
daily_backup_path="$backup_path/$current_date"  # 每天备份目录
#只需要将后续使用到$backup_path替换成daily_backup_path,上面的可注释掉
if [ ! -e $daily_backup_path ]; then
 mkdir -p $daily_backup_path
fi
##############################################################

find $backup_path -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1  #/dev/null为特殊设备,输入到该设备内容都会被丢弃,2>:将标准错误输出重定向,$1:标准错误输出到与标准输出相同的地方,结合:将命令的标准输出和标准错误输出都丢弃,不会显示到屏幕和记录到文件中。
echo "开始备份数据库: ${db[*]}"
#使用循环遍历db数组中所有的数据库,调用自定义backup_sql函数备份
backup_sql(){              
dbname=$1          #将函数backup_sql的第一个参数赋值给dbname,即为以下的length
backup_name="${dbname}_${date}.sql"
#--flush-logs:备份前刷新二进制日志,-R:备份时要包括存储过程和函数,保证还原数据完整
/usr/local/mysql/bin/mysqldump -h $host -P $port -u $user -p$password  --default-character-set=utf8 --socket=/data/mysql/tmp/mysqld.sock --flush-logs -R $dbname > $daily_backup_path/$backup_name 
if [[ $? == 0 ]];     #$?获取上一个命令退出状态,0为成功,非0为失败
 then
  cd $daily_backup_path
  tar -czvf ${backup_name}.tar.gz $backup_name --force-local   #只访问本地文件,本地压缩
  echo " $?"            #调试:tar命令执行成功,但是一直没有.tar.gz包
  size=$(du ${backup_name}.tar.gz -sh | awk '{print $1}')
   rm -rf $backup_name
  echo "$date 备份 $dbname($size) 成功"
else
 cd $daily_backup_name
 rm -rf $backup_name
 echo "$date 备份 $dbname 失败"
fi
}
#先自定义函数,在调用,这里for循环次数由数据库个数决定,backup_sql第一个传递参数$length
length=${#db[@]}     #@获取整个数组的元素,#为获取数据长度,结合起来:返回db中元素个数
for ((i=0;i<$length;i++));do
backup_sql ${db[i]} >> $backup_log 2>&1
done
echo "备份结束,结果查看 $backup_log"
du -sh $daily_backup_path/*${date}*   | awk '{print "文件:" $2 ",大小:" $1}'   #使用swk切割管道符前命令的第一和二字段

参考  优秀文档