MySQL数据库之MySQL:亲测备份策略实例(线上真实备份案例)
小标 2019-04-19 来源 : 阅读 1322 评论 0

摘要:本文主要向大家介绍了MySQL数据库之MySQL:亲测备份策略实例(线上真实备份案例) ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助。

本文主要向大家介绍了MySQL数据库之MySQL:亲测备份策略实例(线上真实备份案例) ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助。

MySQL数据库之MySQL:亲测备份策略实例(线上真实备份案例)

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

说明:

  1. 备份从库,按周计,每周进行一次全备

  2. 每周一的早上六点进行全备,其他时间备份中继日志

  3. 在从库上启用rsync服务,用于异地备份

  4. 在本地服务器使用rsync命令定时同步数据库的备份

  5. 此备份可用于为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 backup0 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.confuid = 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.passremoteuser:password

2、 同步脚本

root@localhost:~# cat /scripts/backup.sh#!/bin/bashSSH=$(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}        do
            rm -f ${filename}        done
        rmdir ${Dest}*  # 删除空目录    fi}# 执行同步命令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    fi}

IFProcess

3、计划任务

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

本文由职坐标整理并发布,希望对同学们学习MySQL有所帮助,更多内容请关注职坐标数据库MySQL数据库频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved