MySQL备份方案

Xtrabackup|Python

Posted by BY lingjun on May 8, 2019 本文总阅读量

MySQL备份方案

任何系统都不可避免会出现各种形式的故障,而某些故障可能会导致数据库灾难性的损坏,而备份是保护数据库的最后一道防线,重中之重。

备份方式

mysql按照备份恢复方式分为逻辑备份物理备份
逻辑备份:是备份sql语句,在恢复的时候执行备份的sql语句实现数据库数据的重现。
物理备份:就是备份数据文件了,比较形象点就是cp下数据文件,但真正备份的时候自然不是的cp这么简单。

mysql按照数据库的运行状态分为热备冷备温备
热备:在数据库运行时,直接进行备份,对运行的数据库没有影响。
冷备:在数据库停止运行的时候进行备份,这种备份方式最为简单,只需要拷贝数据库物理文件即可。
温备:同样是在数据库运行的时候进行备份的,但对当前数据库的操作会产生影响。

下面介绍下最常用的备份方案:
使用percona提供的xtrabackup,支持InnoDB的物理热备份,支持完全备份,增量备份,而且速度非常快,而且支持InnoDB引擎的数据在不同数据库迁移。

备份策略

采用每周一0点进行一次全备,每日0点进行增备,一星期为一个周期。
如要恢复到某个时间点的数据,只需要找到还原到时间点当天的增量备份,然后再结合binlog日志进行恢复。

备份脚本

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Date: 2018/12/9/009
# Created by 灵均

#-------------------部署脚本前阅读指南---------------------------
#1、需要提前安装后xtrabackupex工具 安装函数installXtrabackup(),默认注释
#2、可自定义修改备份用户名密码及备份目录,bkUser,bkPasswd,bkDir
#3、部署crontab任务最好在0点-1点间
#4、备份策略,每周一0点进行全备,然后每天进行一次增备
#5、全备之前把之前的备份数据打包传到远端服务器,需要配置免密配置
#----------------------------------------------------------------

import sys
reload(sys)
sys.setdefaultencoding('utf8')
import commands
import base64
import datetime
import os
#------------自定义变量-----------
bkUser='bkuser'      #备份数据库账号
bkPasswd='passwd'    #备份数据库账户的密码,需要base64加密
bkDir='/data/backup' #备份目录
tarUser='user'       #备份文件传给异地服务器的系统账号
tarHost='ip'         #异地服务器ip
tarBkDir=''          #异地服务器的备份路径
#---------------------------------
oneday=datetime.timedelta(days=1)
twoday=datetime.timedelta(days=2)
today=datetime.date.today()
formattedYesterday=(today-oneday).strftime('%Y%m%d')
formattedBeforeYesterday=(today-twoday).strftime('%Y%m%d')
week=datetime.datetime.now().weekday()
nowTime=str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

def installXtrabackup():
    commands.getstatusoutput('mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup')
    commands.getstatusoutput('mv /etc/yum.repos.d/epel.repo /etc/yum.repos.d/epel.repo.backup')
    commands.getstatusoutput('wget -O/etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo')
    commands.getstatusoutput('wget -O/etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo')
    commands.getstatusoutput('yum install -y http://www.percona.com/downloads/percona-release/redhat/0.1-6/percona-release-0.1-6.noarch.rpm')
    commands.getstatusoutput('yum install -y percona-xtrabackup-24')

def copyFull():
    print '---全备开始时间---:'+nowTime
    fileName='full_'+ formattedYesterday
    bkFulCmd='innobackupex --no-timestamp /data/backup/%s -u%s -p%s'%(fileName,bkUser,base64.decodestring(bkPasswd))
    commands.getstatusoutput(bkFulCmd)
    print '---全备结束时间---:'+nowTime
    return fileName

def copyIncrement(file):
    print '---增备开始时间---:'+nowTime
    fileName='rec_' + formattedYesterday
    bkRecCmd='innobackupex  --no-timestamp --incremental /data/backup/%s --incremental-basedir=/data/backup/%s -u%s -p%s'%(fileName,file,bkUser,base64.decodestring(bkPasswd))
    commands.getstatusoutput(bkRecCmd)
    print '---增备结束时间---:'+nowTime
    return fileName

def packBackup():
    print '---打包开始时间---:'+nowTime
    os.chdir(bkDir)
    os.chdir('..')
    tarCmd='tar -cvf backup_%s.tar backup/'%(formattedYesterday)
    commands.getstatusoutput(tarCmd)
    commands.getstatusoutput('rm -rf /data/backup')
    print '---打包结束时间---:'+nowTime

def isCopyFulRec():
    if os.path.exists(bkDir) == 0:
       copyFull()
    else:
       dirlist = os.listdir(bkDir)
       if dirlist:
           print dirlist
           tagFul='full'
           tagRec='rec'
           fileName=list()
           for i in dirlist:
              if tagFul in i:
                 fileName.append(1)
              elif tagRec in i:
                 fileName.append(2)
              else:
                 fileName.append(0)
           if 2 in fileName:
               copyIncrement('rec_'+formattedBeforeYesterday)
           elif 1 in fileName:
               copyIncrement('full_'+ formattedBeforeYesterday)
           else:
               copyFull()
       else:
           copyFull()

def scpTarget():
    print '---传包开始时间---:'+nowTime
    os.chdir(bkDir)
    os.chdir('..')
    tarName='backup_%s.tar'%formattedYesterday
    scpCmd='scp %s %s@%s'%(tarName,tarUser,tarHost)
    commands.getstatusoutput(scpCmd)
    rmCmd='rm -rf %s'%tarName
    commands.getstatusoutput(rmCmd)
    print '---传包结束时间---:'+nowTime


if __name__ == "__main__":
#    installXtrabackup()
    if week==0:
        if os.path.exists(bkDir) == 1:
            packBackup() #打包
            copyFull()
        else:
            copyFull()
#        scpTarget() #传到备份服务器
    else:
        isCopyFulRec()

定时任务

0 0 * * * /usr/bin/python /data/scripts/backup.py >>/data/scripts/logs/backup.log