1、概述

      MySQL备份工具常用有mysqldump是MySQL自带工具,支持基于innodb的热备份。但是由于是逻辑备份,所以速度不是很快,适合备份数据比较小的场景。Mysqldump完全备份+二进制日志可以实现基于时间点的恢复。对myisam存储引擎的表,只能使用温备份,这个时候要防止数据的写入,所以先加上读锁。这个时候也可以进入数据库手动加读锁,不过这样比较麻烦。所以在生产环境中是不推荐使用mysqldump这个工具。面对大量数据,在生产环境通常使用的是percona提供的xtrabackup工具,支持innodb的物理热备份,支持完全备份,增量备份,而且速度非常快,支持innodb存储引起的数据在不同数据库之间迁移,支持复制模式下的从机备份恢复备份恢复。

2、安装xtrabackup工具

安装包下载地址:链接:​https://pan.baidu.com/s/1Hcjpr7qyeojPx_QRl1GT6Q​

提取码:m9p6

--来自百度网盘超级会员V4的分享可以先安装percona-xtrabackup-2.3.6-1.el7.x86_64.rpm工具的rpm包,如无法安装再进行依赖包的安装

# pm  -ivh percona-xtrabackup-2.3.6-1.el7.x86_64.rpm

安装成功后的命令是‘innobackupex’,常用参数如下:

--user:该选项表示备份账号

--password:该选项表示备份的密码

--port:该选项表示备份数据库的端口

--host:该选项表示备份数据库的地址

--socket:该选项表示mysql.sock所在位置,以便备份进程登录mysql

--defaults-file:该选项指定读取MySQL配置,一般是my.cnf,第一个选项

--databases:该选项接受的参数为数据名压缩参数:

--compress:该选项表示压缩innodb数据文件的备份。

--compress-threads:该选项表示并行压缩worker线程的数量。

--compress-chunk-size:该选项表示每个压缩线程worker buffer的大小

--incremental:创建一个增量备份,需要指定--incremental-basedir。

--incremental-basedir:该选项表示接受了一个字符串参数指定含有full backup的目录为增量备份的base目录,与--incremental同时使用

3、Python定时脚本

# vim mysql_innoback.py import subprocess
import time
import os
from datetime import datetime
import sys

dir = os.getcwd()
sys.path.append(dir)
import jzlog #使用了这个模块:https://blog.51cto.com/kangfs/3845176

# 备份脚本
def innoback():

weeks = datetime.now().isoweekday()
back_dir = '/data/backup'
userback = 'bakuser' #账号需要登录数据库创建
passwordback = '数据库密码'
date_dir = time.strftime('%Y-%m-%d')
socketbak = '/tmp/mysql.sock' #根据实际情况填写
databack = os.path.join(back_dir, date_dir)
try:
del_bak(back_dir, '7')
except Exception as e:
jzlog.logs(f'{e}','error', 'mysql_innoback')
jzlog.logs(f'删除失败','error', 'mysql_innoback')

if weeks == 7: # 全量备份
cmd_bak = f"innobackupex --user={userback} " \
f"--password='{passwordback}' " \
f"-S {socketbak} --no-timestamp {databack}"

result = subprocess.run(cmd_bak,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
if result.returncode == 0:
jzlog.logs(f'{result}','info', 'mysql_innoback')

else:
jzlog.logs(f'{result}','error', 'mysql_innoback')


else: # 增量备份
Full_backup = os.path.join(back_dir, last_sun())

cmd = f"innobackupex " \
f"--user={userback} " \
f"--password='{passwordback}'" \
f" -S {socketbak} " \
f"--no-timestamp " \
f"--incremental {databack}" \
f" --incremental-basedir {Full_backup}"


result = subprocess.run(cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
if result.returncode == 0:
jzlog.logs(f'{result}','info', 'mysql_innoback')

else:
jzlog.logs(f'{result}','error', 'mysql_innoback')


# 清理前7天的备份
def del_bak(back_dir,log_days):
import datetime
import shutil
log_days = int(log_days)
dayago = (datetime.datetime.now() - datetime.timedelta(days=log_days))
back_name =dayago.strftime('%Y-%m-%d')
del_bak = os.path.join(back_dir, back_name)
if del_bak:
shutil.rmtree(del_bak)
jzlog.logs(f'{del_bak}已删除','info', 'mysql_innoback')

else:
jzlog.logs(f'{del_bak}不存在','error', 'mysql_innoback')


# 获取上一个星期天日期
def last_sun():
import datetime
last_sun = (datetime.datetime.today() -
datetime.timedelta(days=time.localtime().tm_wday + 1)).strftime("%Y-%m-%d")
return last_sun

if __name__ == '__main__':
innoback()

4、在crontab添加定时备份


30 3 * * * python3 /opt/yw/script/mysql_innoback.py