mysql数据库如何备份binlog

栏目:云苍穹知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

mysql数据库如何备份binlog

一 背景

mysql数据库的二进制日志binlog记录了对数据库的全量ddl和dml操作,对数据库的point to point灾难恢复起着无法替代的关键作用。因此,需要对生产环境产生的binlog做好相应的备份措施。

二 方案

基本原理

基于flush logs方式实现binlog文件的切换。
通过last_binlog_pos.txt文件记录上一次备份的位置点信息,下一次备份基于该位置点信息进行增量备份。如果是首次备份(last_binlog_pos.txt文件不存在,则全量备份binlog)。通过flush logs的方式强行切换binlog文件(只备份到次新的binlog文件),避免备份binlog过程中,mysql仍对其进行写入操作。备份每个binlog文件对其生产侧和备份侧的binlog文件md5值进行校验,校验不通过则通过配置重传次数$num,超过重传次数仍md5值校验不通过的话,放弃该binlog备份并记录到日志。

脚本

#!/bin/sh

######脚本功能:本地定时备份生产目录的binlog到备份目录。#####

user="root"

password=" "

port=" "

host="localhost"

socket='指定sock的绝对路径'

name=`hostname`

last_binlog_dir="../binlog/chkpoint"                    #备份位置点

last_binlog_pos="$last_binlog_dir/last_binlog_pos.txt"  ###上一次备份的位置点

binlog_backup_dir="../binlog"                           ###binlog备份存放目录

mysqlcommand="mysql -u$user -p$password --socket=$socket  -N  -e "

logdir="../log"                                         #mysql日志目录

baklog="$logdir/binlogbak_$(date +%Y%m%d%H%M).log"

 

###脚本运行日志存放的目录必须先行存在,否则后续写日志会报日志文件不存在的问题

if [ ! -d $logdir ]

then

    mkdir -p $logdir

fi

function create_timestamps()

{

    text=$1

    echo "$(date +%Y%m%d-%H:%M:%S):$text" >>$baklog

}

function init_binlog_backup_dir()

{

    ###判断存放上一次备份位置点的目录是否存在,不存在就创建

    if [ ! -d $last_binlog_dir ]

    then

        #echo "$(date +%Y%m%d-%H:%M:%S):last binlog save dir is not existed, now create it !!!">>$baklog

        create_timestamps "last binlog save dir is not existed, now create it !!!"

        mkdir -p $last_binlog_dir

    fi

    ###判断备份目录是否存在,不存在就创建

    if [ ! -d $binlog_backup_dir ]

    then

        #echo "$(date +%Y%m%d-%H:%M:%S):binlog backup dir is not existed, now create it !!!">>$baklog

        create_timestamps "binlog backup dir is not existed, now create it !!!"

        mkdir -p $binlog_backup_dir

    fi

}

function binlog_backup()

{

    ###获取存放binlog日志的目录

    binlog_dir=`$mysqlcommand "show variables like 'log_bin_index';" 2>/dev/null|awk '{print "dirname "$2}'|sh`

    ###获取binlog日志的index文件名

    binlog_index=`$mysqlcommand "show variables like 'log_bin_index';" 2>/dev/null|awk '{print $2}'`

   

    ###获取binlog日志的个数信息

    binlog_num=`wc -l $binlog_index|awk '{print $1}'`

    ###如果是首次备份,偏移量binlog_start为1;如果非首次备份,偏移量binlog_start为上次偏移量+1。

    if [ ! -f "$last_binlog_pos" ] 

    then

        binlog_start="1"

    else

        binlog_last_file=`cat $last_binlog_pos|awk -F \/ '{print $NF}'`

        binlog_last=`grep -n $binlog_last_file $binlog_index|awk -F \: '{print $1}'`

        binlog_start=`expr ${binlog_last} + 1 `

    fi

   

    #echo "binlog_start is $binlog_start"

    #flush logs,强制切换到新的binlog文件,避免备份当前最新的binlog文件时,mysql仍对其进行写操作###

    $mysqlcommand "flush logs" 2>/dev/null  

    for (( i=$binlog_start;i<=$binlog_num;i++ ))

    do

        if [ $i == $binlog_num ]

        then

            ##记录当次备份的最后一个binlog文件,作为本次备份的位置点信息

            sed -n "${i}p" $binlog_index > $last_binlog_pos

        fi

        cd $binlog_dir

        logfile=`sed -n "${i}p" $binlog_index|awk '{print "basename "$1}'|sh`

       

        num=5       ###重传次数限制

        ###如果拷贝的binlog文件md5值对应不上,尝试重传$num次,md5值依然对不上,放弃备份binlog并记录日志。

        for(( j=1;j<=$num;j++ ))

        do

            cp $logfile $binlog_backup_dir

            md5_source=`md5sum $logfile|awk '{print $1}'`

            md5_backup=`md5sum $binlog_backup_dir/$logfile|awk '{print $1}'`

            if [ "$md5_source" = "$md5_backup" ]

            then

                gzip $binlog_backup_dir/$logfile

                echo "$(date +%Y%m%d-%H:%M:%S):$logfile backup to the $binlog_backup_dir sucessfully." >> $baklog

                break

            fi

            if [ "$j" == "$num" ]

            then

                rm -fr $binlog_backup_dir/$logfile

                echo "$(date +%Y%m%d-%H:%M:%S):$logfile can not backup to the $binlog_backup_dir sucessfully,please check !!!"  >> $baklog

            fi

        done

    done

}

create_timestamps "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

create_timestamps "the binlog backup start now !!!"                                   

init_binlog_backup_dir                                                                

binlog_backup                                                                          

create_timestamps "the binlog backup end   now !!!"                                   

create_timestamps "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

 

# Cleanup

echo "delete gz files of 1 days ago"

find $binlog_backup_dir/ -mtime 1 -name "*.gz"  -exec rm -rf {} \;

echo "delete backup logs of 1 days ago"

find $logdir -mtime 1 -name "binlog*.log"  -exec rm -rf {} \;

总结

通过验证md5值的方式确保备份同生产的一致性。

备份的逻辑简单,便于理解。

注意事项:通过定时调度的方式实现备份,极端情况下存在丢失binlog的可能(在两个定时调度的窗口时间,mysql异常并且所有生产binlog不可用,这个窗口时间产生的binlog无法备份到)。例如每小时调度备份binglog的备份作业,1000备份,1059 MySQL异常并且所有生产binlog不可用.1100的备份调度作业会出错。




mysql数据库如何备份binlog

一 背景mysql数据库的二进制日志binlog记录了对数据库的全量ddl和dml操作,对数据库的point to point灾难恢复起着无法替代的关键作用。...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息