线上MySQL备份实例

作者: 云计算机网 分类: 云安全 发布时间: 2017-04-16 02:58

是否为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) gt; 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 lt; 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    gt;gt;gt;全备    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 gt; %s/%s"%(MysqlDump_Bin,DB,ARG,DB_NAME,Backup_Dir,Back_DBNAME))
            file.writelines("###    backup done amp;amp; 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    gt;gt;gt;全备完成\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    gt;gt;gt;增量备份    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 amp;amp; 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    gt;gt;gt;增量备份完成\n")
            file.writelines("\n\n\n\n\n")
        Del_Old()
else:
    with open(Logs_File, 'a+') as file:
        file.writelines("####----------        分界线        ----------####\n")
        file.writelines("###start    gt;gt;gt;增量备份    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 amp;amp; 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    gt;gt;gt;增量备份完成\n")
        file.writelines("\n\n\n\n\n")
    Del_Old() 
  • 无线上网主要分为两种,一种是通过无线路由器等无线结点连接上网;另外一种就是借助联通或移动的CDMA GPRS以及EDGE实现无线上网功能,哪种更适合自己的需要呢?

    前一种上网方式都有距离的限制,一般室内只有在100米左右的距离内才干获得较好的信号,上网速度较快,特别是IEEE802.11n规范公布以后,基于新标准的无线上网产品可以使上网速度理论达到300Mbp而后一种方式则基本没有距离的限制,只要你有联通功移动手机网络覆盖的地方都可以实现无线上网,但由于技术的限制,基于移动GPRS无线上网卡速度较慢,仅能满足普通的上网或通讯需要,联通CDMA 则要好一些,但还是受到速度不理想的限制,最近新兴发展起来的EDGE则可以达到一个较为理想的效果,但由于其刚发展不久,相应的网络还不是很完善,而且相应的费用较高,也有一定的限制www.it165.net。

    从技术上来分析,GPRS速度方面无法于CDMA 抗衡,而CDMA 速度又无法与EDGE抗衡,但EDGE又受到费用与覆盖范围的限制,EDGE速度又没有方法和WLA N无线上网抗衡,但WLA N无线上网受无线热点分布的密度限制。总体来看是各有各的优势,谁也无法取代谁,那用户到底该怎么样选择呢?

    GPRS适合什么样的人群?GPRS无线上网属于移动公司旗下的产品,手机市场,移动拥有众的用户,其GPRS上网卡也受到很多消费者的喜爱,但是速度无法达到一个很理想的效果。

    另外,由于无线上网都是使用的手机网络,网络布置方面,移动的GSM网络覆盖范围要比联通CDMA 广许多,这个可能大家在使用手机的时候就可以看出来,一些偏远的山区,移动的手机信号要比联通的好一些,基于这两个方面的原因,GPRS无线上网就比较适合对网速要求不高,但对网络的信号以及稳定性要求较高的商务用户选购,主要用于浏览网页、及时通讯以及发送电子邮件等对网速要求不高的业务。

    优点:覆盖面广、可实时在线、沟通交流方便

    缺点:网速较慢、处置大文件事务不方便

  • 相关推荐:

  • 解读两种无线上网适合人
  • MySQL5.7.19执行cmake时报错
  • MySQL中索引优缺点、分类
  • Oracle中print
  • Linux下MySQLshell脚本执行错
  • MySQL表结构变更,不可不
  • MySQL存储引擎MyISAM介绍
  • MySQL索引的设计和使用
  • 用简单程序协助MySQL实现
  • MySQL表查询操作实例
  • 网站内容禁止违规转载,转载授权联系中国云计算网