MySQL生产全量&增量备份脚本

之前写过一篇 Xtrabackup备份文件恢复 的文章,生产中Mysql备份基本都是使用percona的xtrabackup进行全量&增量备份,简单的话直接使用mysqldump即可。这个脚本比较好的是在一个脚本内实现了全量和增量备份,思路挺好,来源:https://www.modb.pro/db/42779,稍微改了下,加了邮件报警等功能,感谢原作者分享。

脚本内容:mysql_backup_full_incr.sh

#!/bin/bash
# 参考:https://www.modb.pro/db/42779

###############################################
#1. 该备份脚本需要加入到cron中,每天自动执行该脚本
#2. 以周为单位,进行一次全备,比如周六凌晨
#3. 然后一周中其他备份时间执行增量备份
###############################################

##备份策略:
##周日(7): 全备
##周一 ~ 周六(1-6): 增量备份

source /etc/profile
ulimit -HSn 102400 

##
##========== global var ============
##

#如果一台服务器上有多个MySQL,可以使用 BAK_DIR_ROOT进行备份路径的区别
#可增加端口作为区分,例如 /data/backup/mysqk/3306
BAK_DIR_ROOT="/data/backup/mysql"
#默认周日进行全备(1 - 7), 1是周一,7是周日
FULL_BAK_DAY_OF_WEEK=7 
#备份文件保留周期,默认保留35天 (4-5周)
HOLD_DAYS=35

MYSQL_USERNAME="mysql_backup"
MYSQL_PASSWORD="backup_chegva.com"

MYSQL_CNF="/etc/my.cnf"
MYSQL_MULTI_GROUP="--socket=/tmp/mysql.sock"
#如果使用多实例,比如通过ecloud的方式下发安装,默认使用多实例
#MYSQL_MULTI_GROUP="--defaults-group=mysqld3307 --socket=/tmp/mysql3307.sock"

CURRENT_WEEK_OF_YEAR=$(date +%U)
CURRENT_DAY_OF_WEEK=$(date +%u)
CURRENT_DATE=$(date +%F)
CURRENT_TIME=$(date +%H-%M-%S)
CURRENT_DATETIME="${CURRENT_DATE}_${CURRENT_TIME}"
CURRENT_DAYWEEK="${CURRENT_DATE}_${CURRENT_DAY_OF_WEEK}"

BAK_WEEK_DIR="${BAK_DIR_ROOT}/WEEK_${CURRENT_WEEK_OF_YEAR}"
BAK_FULL_DIR="${BAK_WEEK_DIR}/FULL"
BAK_LOG="${BAK_WEEK_DIR}/backup_${CURRENT_DATETIME}.log"

## remote backup vars
IP_HOST="$(hostname -I | awk '{print $1}')_$(hostname)"
MANAGE_IP=192.168.111.222
REMOTE_BACKUP_DIR=/mysqlbackup


##
##========== function =============
##

prepare() {
	
	if [[ ! -d ${BAK_WEEK_DIR} ]];then
		mkdir -p ${BAK_WEEK_DIR}
	fi
	
	echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${CURRENT_DATETIME} Begin Backup <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" >> ${BAK_LOG}
	CONNECT="--defaults-file=${MYSQL_CNF} ${MYSQL_MULTI_GROUP} --user=${MYSQL_USERNAME} --password=${MYSQL_PASSWORD}"
}

# 周日(7): 全备
full_backup() {
	
	if [[ ! -d ${BAK_FULL_DIR} ]]; then
		mkdir -p ${BAK_FULL_DIR}
	fi
	
	echo "*** FULL BACKUP Date : ${CURRENT_DATETIME}" >> ${BAK_FULL_DIR}/full_backup.date
	
	DATA_START=$(date +%s)
	innobackupex ${CONNECT} --no-timestamp --compress --compress-threads=1 --stream=xbstream --parallel=2 --ftwrl-wait-timeout=120 --ftwrl-wait-threshold=120 --ftwrl-wait-query-type=all --extra-lsndir="${BAK_FULL_DIR}/LSN_INFO"  ${BAK_FULL_DIR}  > "${BAK_FULL_DIR}/mysql_backup_${CURRENT_DAYWEEK}_full.xbstream"  2>> ${BAK_LOG}
	DATA_MARK=$?
	DATA_END=$(date +%s)
	DATA_TIME=$((DATA_END-DATA_START))
	if [ ${DATA_MARK} -eq 0 ];then
		techo "mysql full backup success,named ${BAK_FULL_DIR}/mysql_backup_${CURRENT_DAYWEEK}_full.xbstream,took ${DATA_TIME} seconds,size $(du -sh ${BAK_FULL_DIR}/mysql_backup_${CURRENT_DAYWEEK}_full.xbstream | awk '{print $1}')" "succeed"
		# 发送邮件通知
		echo -e "mysql full backup success,named ${BAK_FULL_DIR}/mysql_backup_${CURRENT_DAYWEEK}_full.xbstream,took ${DATA_TIME} seconds,size $(du -sh ${BAK_FULL_DIR}/mysql_backup_${CURRENT_DAYWEEK}_full.xbstream | awk '{print $1}')" | mail -v -s "${IP_HOST}-MySQL全量备份成功-${CURRENT_DATETIME}" chegva@qq.com; 
		# 远程归档备份文件
		upload ${BAK_FULL_DIR}/mysql_backup_${CURRENT_DAYWEEK}_full.xbstream"
	else
		techo "mysql full backup fail" "failed"
		echo -e "${IP_HOST} MySQL全量备份失败-${CURRENT_DATETIME},请检察!" | mail -v -s "${IP_HOST}-MySQL全量备份失败-${CURRENT_DATETIME}" chegva@qq.com;
		rm -f ${BAK_FULL_DIR}/mysql_backup_${CURRENT_DAYWEEK}_full.xbstream"
	fi

}

# 每周周一到周六进行增量备份
incr_backup() {
	
	CURRENT_INCR_DIR="${BAK_WEEK_DIR}/INCR_${CURRENT_DAY_OF_WEEK}"
	PREV_DAY_OF_WEEK=$((${CURRENT_DAY_OF_WEEK} - 1))
	BASE_DIR="${BAK_WEEK_DIR}/INCR_${PREV_DAY_OF_WEEK}"
	
	#如果不存在之前的增量,则使用全量路径作为增量的BASE
	#比如周一的时候
	if [[ ! -d ${BASE_DIR} ]];then
		BASE_DIR=${BAK_FULL_DIR}
	fi
	
	#如果在此函数中,还没有BASE,则认为可能是在项目第一周执行
	#进行一次全量备份
	if [[  ! -d ${BASE_DIR} ]];then
		echo "*** ${BASE_DIR} as BASE_DIR is not exists!" >> ${BAK_LOG}
		echo "***  So Backup Processor into FULL BACKUP " >> ${BAK_LOG}
		full_backup
		exit $?
	fi
	
	#如果存放增量数据的目录已经存在,这里进行添加时间戳处理(一天可备份多次)
	if [[ -d ${CURRENT_INCR_DIR} ]];then
		CURRENT_INCR_DIR="${CURRENT_INCR_DIR}_${CURRENT_DATETIME}"
	fi
	
	#如果BASE_DIR存在,则进行增量备份
	if [[ ! -d ${CURRENT_INCR_DIR} ]];then
		mkdir -p ${CURRENT_INCR_DIR}
	fi
	
	echo "*** INCR BACKUP Date : ${CURRENT_DATETIME}" >> ${CURRENT_INCR_DIR}/incr_backup.date
	
	DATA_START=$(date +%s)
	innobackupex ${CONNECT} --no-timestamp --compress --compress-threads=1 --stream=xbstream --parallel=2 --ftwrl-wait-timeout=120 --ftwrl-wait-threshold=120 --ftwrl-wait-query-type=all --incremental --incremental-basedir="${BASE_DIR}/LSN_INFO" --extra-lsndir="${CURRENT_INCR_DIR}/LSN_INFO"  ${CURRENT_INCR_DIR}  > "${CURRENT_INCR_DIR}/mysql_backup_${CURRENT_DAYWEEK}_incr.xbstream" 2>> ${BAK_LOG}
	DATA_MARK=$?
	DATA_END=$(date +%s)
	DATA_TIME=$((DATA_END-DATA_START))
	if [ ${DATA_MARK} -eq 0 ];then
		techo "mysql incr backup success,named ${CURRENT_INCR_DIR}/mysql_backup_${CURRENT_DAYWEEK}_incr.xbstream,took ${DATA_TIME} seconds,size $(du -sh ${CURRENT_INCR_DIR}/mysql_backup_${CURRENT_DAYWEEK}_incr.xbstream | awk '{print $1}')" "succeed"
		# 发送邮件通知
		echo -e "mysql incr backup success,named ${CURRENT_INCR_DIR}/mysql_backup_${CURRENT_DAYWEEK}_incr.xbstream,took ${DATA_TIME} seconds,size $(du -sh ${CURRENT_INCR_DIR}/mysql_backup_${CURRENT_DAYWEEK}_incr.xbstream | awk '{print $1}')" | mail -v -s "${IP_HOST}-MySQL增量备份成功-${CURRENT_DATETIME}" chegva@qq.com;
		# 远程归档备份文件
		upload "${CURRENT_INCR_DIR}/mysql_backup_${CURRENT_DAYWEEK}_incr.xbstream"
	else
		techo "mysql incr backup fail" "failed"
		echo -e "${IP_HOST} MySQL增量备份失败-${CURRENT_DATETIME},请检察!" | mail -v -s "${IP_HOST}-MySQL增量备份失败-${CURRENT_DATETIME}" chegva@qq.com;
		rm -f ${CURRENT_INCR_DIR}/mysql_backup_${CURRENT_DAYWEEK}_incr.xbstream
	fi
}

# 将备份文件上传到冷备服务器
upload(){
	
	local BAK_FILE="$1"
	ssh -o passwordauthentication=no -o stricthostkeychecking=no ${MANAGE_IP} "[ ! -d ${REMOTE_BACKUP_DIR}/${IP_HOST} ] && mkdir -p ${REMOTE_BACKUP_DIR}/${IP_HOST}"

	techo "mysql backup data ${BAK_FILE} upload start"
	DATA_UPLOAD_START=$(date +%s)
	scp -r -o passwordauthentication=no -o stricthostkeychecking=no ${BAK_FILE} ${MANAGE_IP}:${REMOTE_BACKUP_DIR}/${IP_HOST}/ 2>> ${BAK_LOG}
	DATA_UPLOAD_MARK=$?
	DATA_UPLOAD_END=$(date +%s)
	DATA_UPLOAD_TIME=$((DATA_UPLOAD_END-DATA_UPLOAD_START))
	if [ ${DATA_UPLOAD_MARK} -eq 0 ];then
		techo "mysql remote backup file ${BAK_FILE} upload success,took ${DATA_UPLOAD_TIME} seconds" "succeed"
	else
	    techo "mysql remote backup file ${BAK_FILE} upload fail" "failed"
		ssh ${MANAGE_IP} "rm -rf ${REMOTE_BACKUP_DIR}/${IP_HOST}/${BAK_FILE}"
	fi
}

# 美化输出
techo() {
	local msg=$1
	local msg_level=${2:-'INFO'}
	echo "`date '+%F %T'` - [${msg_level}] ${msg}" >> $BAK_LOG
}

clean_backup() {
	techo "clean backup start..." "warn"
	find ${BAK_DIR_ROOT}  -mtime +${HOLD_DAYS}  >> $BAK_LOG
	find ${BAK_DIR_ROOT}  -mtime +${HOLD_DAYS}  -prune -exec rm -rf {} \;
	techo "clean backup end" "warn"
	echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ${CURRENT_DATETIME} End Backup <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" >> ${BAK_LOG}
}

create_backup_user(){
	#mysql -u root -p < create_backup_user.sql
	set @old_super_read_only=@@super_read_only;
	set @old_read_only=@@read_only; 
	SET global super_read_only = 0;
	SET global read_only = 0; 
	set sql_log_bin=0;
	create user 'mysql_backup'@'127.0.0.1' identified by 'backup_chegva.com';
    GRANT RELOAD, PROCESS, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'mysql_backup'@'127.0.0.1';
	create user 'mysql_backup'@'localhost' identified by 'backup_chegva.com';
	grant reload,lock tables,replication client,process on *.* to 'mysql_backup'@localhost;
	set sql_log_bin=1;
	set global super_read_only=@old_super_read_only; 
	set global read_only=@old_read_only; 
}

################# main #################

prepare 

# 如果指定的全备时间 == 当前的时间,则执行全备
if [[ ${FULL_BAK_DAY_OF_WEEK} -eq ${CURRENT_DAY_OF_WEEK} ]];then
	full_backup
else
	incr_backup 
fi

clean_backup

添加crontab定时备份任务:

# backup mysql
#30 3 * * * /bin/bash /root/mysql_backup_full_incr.sh >/dev/null 2>&1

查看效果:

MySQL生产全量&增量备份脚本

MySQL生产全量&增量备份脚本


参考:Mysql innobackupex物理备份与mysqldump逻辑备份使用

anzhihe 安志合个人博客,版权所有 丨 如未注明,均为原创 丨 转载请注明转自:https://chegva.com/6045.html | ☆★★每天进步一点点,加油!★★☆ | 

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注