linuxsir首页 LinuxSir.Org | Linux、BSD、Solaris、Unix | 开源传万世,因有我参与欢迎您!
网站首页 | 设为首页 | 加入收藏
您所在的位置:主页 > Linux数据库 >

线上MySQL备份实例

时间:2019-03-09  来源:未知  作者:admin666

是否为MySQL线上库的备份而烦恼过,这里提供一个完整的备份从属数据库的备份方案,亲测可用。

说明:

备份从库,按周计,每周进行一次全备 每周一的早上六点进行全备,其他时间备份中继日志 在从库上启用rsync服务,用于异地备份 在本地服务器使用rsync命令定时同步数据库的备份 此备份可用于为Master添加新的Slave,也可以用于还原Master

一、服务器端配置

1、 Python编写的备份脚本

root@DBSlave:~# cat /scripts/mysql_slave_backup.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
import os
import datetime,time
# 请在linux系统中安装zip和unzip
# 备份策略示例
 1. 每周进行一次全备,其他都是备份中继日志
 2. 每周一凌晨6:00数据库全备份
 3. 周二至周日,每天中午12:00,下午18:00,早上6:00,备份中继日志
# 规划备份目录
# 备份目录以周为单位进行创建
# "%W":一年中的第几周,以周一为每星期第一天(00-53)
Date_Time = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S") # %F:年月日
Week_Date = datetime.datetime.now().strftime("%Y-%W") # 年/当前是本年的第几周
Dir = "/data/backup"
Backup_Dir = Dir+ '/' + Week_Date
# -- 创建备份目录 ,每周生成一个目录,因为每周做一次全备
if os.path.isdir(Backup_Dir) is False:
 os.makedirs(Backup_Dir)
# 设置数据库连接信息
#mysqldump选项
# --skip-tz-utc : 保持和表导出前的时区是一样的
# --master-data=2 : 备份时写入"change master to"语句并且注释,等于1时,则不会注释
# --dump-slave=2 : 备份slave的数据库,为master新增slave时使用.
# --quick : 一次从行中的服务器检索表的行,作用是加快导出表
# --routines : 导出存储过程
# --triggers : 导出触发器
# --set-gtid-purged=OFF : 防止备份数据导入新的实例时与其GTID发生冲突,所以在备份数据时不添加GTID信息
# --single-transaction : 在从服务器转储数据之前发出BEGIN SQL语句,尽量保证数据的一致性,但是这个参数只适用于innodb这样的存储引擎
# --dump-slave=2 : 备份时写入从库连接主库的change语句并且注释,等于1时,则不会注释
# 设置数据库备份信息
DB = '-uroot -p123456' # 指定登录账号和密码
ARG = '--dump-slave=2 --skip-tz-utc --routines --triggers --quick --default-character-set=utf8 --single-transaction' # 指定备份参数
DB_NAME = "dbname" # 数据库名称
Back_DBNAME = DB_NAME + '_' + Date_Time + '.sql' # 数据库备份名称
Logs_File = Backup_Dir + '/logs' # 指定备份时日志输出的文件
Mysql_Bin = "/usr/bin/mysql" # 指定[mysql]命令所在路径
MysqlDump_Bin = "/usr/bin/mysqldump" # 指定[mysqldump]命令所在路径
Relay_Log_Dir = "/data/logs/relay_log" #指定中继日志
Relay_Log_Info = "/data/logs/relay_log/relay-bin.info" # 用于获取当前正在使用的中继日志
# 定义删除旧备份
def Del_Old():
 '''删除36天前的旧备份'''
 OLD_Files = os.popen("find %s -type f -mtime +36"%(Dir)).readlines()
 if len(OLD_Files) 0:
 for OLD_FIle in OLD_Files:
 FileName = OLD_FIle.split("\n")[0]
 os.system("rm -f %s"%(FileName))
 # 删除空目录
 All_Dir = os.popen("find %s -type d"%(Dir + '/*')).readlines()
 for Path_Dir in All_Dir:
 Path_Dir = Path_Dir.split("\n")[0]
 Terms = os.popen("ls %s | wc -l"%(Path_Dir)).read()
 if int(Terms) == 0:
 os.system("rm -rf %s"%(Path_Dir))
# 备份已经同步完成的中继日志文件
def ZIP_And_Del_Existed():
 压缩已经同步完成的日志文件并删除,
 为防止中继日志还没有同步完成,就被删除,这里作一个判断,只压缩和删除已经同步过的中继日志
 # 获取所有的中继日志
 Relog_List = os.popen("ls %s | grep \"^relay-bin.*\" | grep -v \"relay-bin.in*\"" % (Relay_Log_Dir)).readlines()
 # 获取当前正在使用的中继日志文件
 CurRelay = os.popen("cat %s | head -n 1" % (Relay_Log_Info)).readline().split("\n")[0]
 CurRelay_MTime = os.path.getmtime(CurRelay) # 获取当前正在使用的文件的最后修改时间
 # 循环所有的中继日志文件,通过和中继日志的最后修改时间进行对比,得到需要备份的中继日志
 Need_ZIP_FName = [] # 定义需要压缩和删除的文件名
 for FileName in Relog_List:
 将修改时间小于[当前正在使用的中继日志]文件的文件,加入到 列表 [Need_ZIP_FName] 中,用于备份/删除.
 FName = FileName.split("\n")[0]
 FName_MTime = os.path.getmtime("%s/%s"%(Relay_Log_Dir,FName))
 if FName_MTime CurRelay_MTime:
 Need_ZIP_FName.append("%s/%s"%(Relay_Log_Dir,FName))
 os.system("zip -j %s/Relay_log_%s.zip %s" % (Backup_Dir, Date_Time," ".join(Need_ZIP_FName)))
 # 获取已经压缩的中继日志文件,然后删除
 for Relay_Log in Need_ZIP_FName:
 os.system("rm -f %s"%(Relay_Log))
# 开始执行备份.(判断,如果今天是星期一则进行全备,不是星期一则增量备份)
IF_Week = datetime.datetime.now().strftime('%w')
if int(IF_Week) == 1:
 # 匹配是否已经存在全备
 Test = os.popen('ls %s | grep -E \"^%s.*([0-9]{2}-[0-9]{2}-[0-9]{2}).sql.zip\" | wc -l'%(Backup_Dir,DB_NAME)).readline()
 if int(Test) == 0:
 # 如果星期一已经进行全备,则开始增量备份
 with open(Logs_File,'a+') as file:
 file.writelines("####---------- 分界线 ----------####\n")
 file.writelines("###start 全备 datetime : %s\n"%(datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")))
 file.writelines("### 今天是周%s\n"%(IF_Week))
 file.writelines("### stop slave\n")
 os.system("%s %s -e \"stop slave\""%(Mysql_Bin,DB))
 file.writelines("### status slave\n")
 Show_Slave = os.popen("%s %s -e \"show slave status\G\""%(Mysql_Bin,DB)).readlines()
 file.writelines(Show_Slave)
 file.writelines("### backup\n")
 os.system("%s %s %s %s %s/%s"%(MysqlDump_Bin,DB,ARG,DB_NAME,Backup_Dir,Back_DBNAME))
 file.writelines("### backup done start slave | datetime : %s\n"%(datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")))
 os.system("%s %s -e \"start slave;\""%(Mysql_Bin,DB))
 time.sleep(5)
 file.writelines("### slave status\n")
 Show_Slave = os.popen("%s %s -e \"show slave status\G\"" % (Mysql_Bin, DB)).readlines()
 file.writelines(Show_Slave)
 file.writelines("###done 全备完成\n")
 os.system("zip -j %s/%s.zip %s/%s"%(Backup_Dir,Back_DBNAME,Backup_Dir,Back_DBNAME))
 os.system("rm %s/%s"%(Backup_Dir,Back_DBNAME))
 file.writelines("\n\n\n\n\n")
 Del_Old()
 else:
 with open(Logs_File,'a+') as file:
 file.writelines("####---------- 分界线 ----------####\n")
 file.writelines("###start 增量备份 datetime : %s\n"%(datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")))
 file.writelines("### 今天是周%s\n"%(IF_Week))
 file.writelines("### stop slave\n")
 os.system("%s %s -e \"stop slave\""%(Mysql_Bin,DB))
 file.writelines("### status slave\n")
 Show_Slave = os.popen("%s %s -e \"show slave status\G\""%(Mysql_Bin,DB)).readlines()
 file.writelines(Show_Slave)
 file.writelines("### backup\n")
 ZIP_And_Del_Existed()
 file.writelines("### backup done start slave | datetime : %s\n"%(datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")))
 os.system("%s %s -e \"start slave;\""%(Mysql_Bin,DB))
 time.sleep(5)
 file.writelines("### slave status\n")
 Show_Slave = os.popen("%s %s -e \"show slave status\G\"" % (Mysql_Bin, DB)).readlines()
 file.writelines(Show_Slave)
 file.writelines("###done 增量备份完成\n")
 file.writelines("\n\n\n\n\n")
 Del_Old()
else:
 with open(Logs_File, 'a+') as file:
 file.writelines("####---------- 分界线 ----------####\n")
 file.writelines("###start 增量备份 datetime : %s\n" % (datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")))
 file.writelines("### 今天是周%s\n" % (IF_Week))
 file.writelines("### stop slave\n")
 os.system("%s %s -e \"stop slave\"" % (Mysql_Bin, DB))
 file.writelines("### status slave\n")
 Show_Slave = os.popen("%s %s -e \"show slave status\G\"" % (Mysql_Bin, DB)).readlines()
 file.writelines(Show_Slave)
 file.writelines("### backup\n")
 ZIP_And_Del_Existed()
 file.writelines("### backup done start slave | datetime : %s\n" % (datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")))
 os.system("%s %s -e \"start slave;\"" % (Mysql_Bin, DB))
 time.sleep(5)
 file.writelines("### slave status\n")
 Show_Slave = os.popen("%s %s -e \"show slave status\G\"" % (Mysql_Bin, DB)).readlines()
 file.writelines(Show_Slave)
 file.writelines("###done 增量备份完成\n")
 file.writelines("\n\n\n\n\n")
 Del_Old()

2、计划任务

root@DBSlave:~# cat /etc/cron.d/general
#mysql backup
0 6 * * * root python /scripts/mysql_slave_backup.py
0 12 * * * root python /scripts/mysql_slave_backup.py
0 18 * * * root python /scripts/mysql_slave_backup.py

3、rsync配置

root@DBSlave:~# cat /etc/rsyncd.conf
uid = 0
gid = 0
use chroot = yes
address = "当前主机公网地址"
port = 8638
log file = /var/log/rsync.log
pid file = /var/run/rsync.pid
hosts allow = "只允许某个IP连接"
[databases]
path = /data/backup/
comment = databases
read only = yes
dont compress = *.gz *.bz2 *.zip
# 只允许remoteuser用户
auth users = remoteuser
secrets file = /etc/rsyncd_users.db
root@DBSlave:~# cat /etc/rsyncd_users.db
# 格式: 用户名:密码
remoteuser:password

二、 本地备份主机配置

1、创建rsync密码文件

root@localhost:~# cat /etc/server.pass
remoteuser:password

2、 同步脚本

root@localhost:~# cat /scripts/backup.sh
#!/bin/bash
SSH=$(which ssh)
Logs_Dir="/Backup/logs.txt"
Rsync=$(which rsync)
Project="databases"
Dest="/Backup/"
IF_DEL_FILE=$(find ${Dest} -type f -mtime +36 -name "*" | wc -l)
DEL_FILE=$(find ${Dest} -type f -mtime +36 -name "*")
# 删除旧备份
RMOLD(){
 if [ "${IF_DEL_FILE}" -gt "0" ]
 then
 for filename in ${DEL_FILE}
 rm -f ${filename}
 done
 rmdir ${Dest}* # 删除空目录
# 执行同步命令
Backup(){
 echo "### ---------- datetime : `date +%F-%H-%M-%S` ---------- ###" ${Logs_Dir}
 echo "# start rsync" ${Logs_Dir}
 ${Rsync} -azH --password-file=/etc/server.pass --bwlimit=300 --port=8638 remoteuser@数据库rsync监听的IP地址::${Project} ${Dest} ${Logs_Dir}
 echo "### end rsync ---------- dateime : `date +%F-%H-%M-%S` ---------- ###" ${Logs_Dir}
 echo -e "\n\n\n\n\n" ${Logs_Dir}
 RMOLD
# 判断如果当前正在同步则不再执行同步命令
IFProcess(){
 ps -ef | grep "${Rsync} -azH --password-file=/etc/server.pass --bwlimit=300 --port=8638 remoteuser@数据库rsync监听的IP地址::${Project}" | grep -v "grep" /dev/null
 if [[ "$?" == 0 ]]
 then
 exit 0
 else
 Backup
IFProcess

3、计划任务

root@localhost:~# cat /etc/cron.d/general
01 23 * * * root /bin/sh /scripts/backup.sh

Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx

友情链接
  • Mozilla发布Firefox 67.0.4,修复沙箱逃逸漏洞
  • 蚂蚁金服正式成为CNCF云原生计算基金会黄金会员
  • Firefox 68将采用Microsoft BITS安装更新
  • OpenSSH增加对存储在RAM中的私钥的保护
  • 谷歌想实现自己的curl,为什么?
  • Raspberry Pi 4发布:更快的CPU、更大的内存
  • Firefox的UA将移除CPU架构信息
  • Ubuntu放弃支持32位应用程序实属乌龙,Steam会否重回Ubuntu怀抱
  • Qt 5.13稳定版发布:引入glTF 2.0、改进Wayland以及支持Lottie动
  • 红帽企业Linux 7现已内置Redis 5最新版
  • Slack进入微软内部禁用服务清单,GitHub也在其列?
  • 安全的全新编程语言V发布首个可用版本
  • Windows Terminal已上架,快尝鲜
  • 阿里巴巴微服务开源生态报告No.1
  • 面世两年,Google地球将支持所有基于Chromium的浏览器
  • 推进企业容器化持续创新,Rancher ECIC千人盛典完美收官
  • CentOS 8.0最新构建状态公布,或于数周后发布
  • Debian移植RISC
  • 微软拆分操作系统的计划初现雏形
  • Oracle发布基于VS Code的开发者工具,轻松使用Oracle数据库
  • Ubuntu 19.10停止支持32位的x86架构
  • 微软为Windows Terminal推出全新logo
  • 联想ThinkPad P系列笔记本预装Ubuntu系统
  • 微软发布适用于Win7/8的Microsoft Edge预览版
  • 启智平台发布联邦学习开源数据协作项目OpenI纵横
  • 经过六个多月的延迟,微软终于推出Hyper
  • ZFS On Linux 0.8.1 发布,Python可移植性工作
  • DragonFly BSD 5.6.0 发布,HAMMER2状态良好
  • Linux Kernel 5.2
  • CentOS 8.0 看起来还需要几周的时间
  • 百度网盘Linux版正式发布
  • PCIe 6.0宣布:带宽翻倍 狂飙至256GB/s
  • PHP 7.4 Alpha 发布,FFI扩展,预加载Opcache以获得更好的性能
  • Canonical将在未来的Ubuntu版本中放弃对32位架构的支持
  • Scala 2.13 发布,改进的编译器性能
  • 微软的GitHub收购了Pull Panda,并且使所有订阅完全免费
  • Windows Subsystem for Linux 2 (WSL 2)现在适用于Windows 10用
  • Debian 10 “Buster”的RISC
  • MariaDB宣布发布MariaDB Enterprise Server 10.4
  • DXVK 1.2.2 发布,带来微小的CPU开销优化
  • DragonFlyBSD 5.6 RC1 发布,VM优化,默认为HAMMER2
  • PrimeNG 8.0.0 发布,支持Angular 8,FocusTrap等
  • GIMP 2.10.12 发布,一些有用的改进
  • 清华大学Anaconda 镜像服务即将恢复
  • Debian GNU/Linux 10 “Buster” 操作系统将于2019年7月6日发布
  • 时时彩论坛
  • 五星体育斯诺克
  • 北单比分直播
  • 河北11选5走势图
  • 福建体彩36选7开奖结果
  • 九龙图库下载