mysqlデータベースbinlogログのオフサイトバックアップ


MySQLデータベースのバイナリ・ログbinlogは、データベースに対するDDLとDMLのフル・オペレーションを記録し、データベースのpoint to pointディザスタリカバリに取って代わることのできない重要な役割を果たします.そのため、このような考慮に基づいて、本番環境で発生したbinlogに対して相応のバックアップ措置を講じる必要がある.
ここでは主に2つのバックアップ方法について述べ,スクリプトタイミングスケジューリングによりbinlogを強制的に切り替え,バイナリbinlogをインクリメンタルバックアップする.もう1つはmysqlbinlogのリモートリアルタイムバックアップによりbinlogバックアップを実現することである.
1、flush logs方式に基づいてbinlogファイルの切り替えを実現する
基本原理:last_を介してbinlog_pos.txtファイルは、前回バックアップした位置点情報を記録し、次のバックアップはその位置点情報に基づいてインクリメンタルバックアップを行う.初回バックアップ(last_binlog_pos.txtファイルが存在しない場合、binlogを全量バックアップします).flush logsによってbinlogファイル(次の新しいbinlogファイルにのみバックアップ)を強制的に切り替え、binlogをバックアップする過程でMySQLが書き込み操作を行うことを避ける.各binlogファイルをバックアップしてその生産側とバックアップ側のbinlogファイルmd 5値を検証し、検証は再送回数$numを構成することによって行われず、再送回数を超えてもmd 5値の検証が通過しない場合、binlogバックアップを放棄してログに記録する.
スクリプトは次のとおりです.
#!/bin/sh
######    :           binlog     。#####
user="root"
password="linzj"
port="3306"
host="localhost"
name=`hostname`
last_binlog_dir="/home/mysql/chkpoint"
last_binlog_pos="$last_binlog_dir/last_binlog_pos.txt"  ###         
binlog_backup_dir="/tmp/logbak/$name"                       ###binlog      
mysqlcommand="mysql -u$user -p$password -h$host -P$port -N --protocol=tcp -e "
logdir="/home/mysql/log"
binlogfile="$logdir/binlog_bak.log"
###                 ,                   
if [ ! -d $logdir ]
then
    mkdir -p $logdir
fi
function create_timestamps()
{
    text=$1
    echo "$(date +%Y%m%d-%H:%M:%S):$text" >>$binlogfile
}
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 !!!">>$binlogfile
        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 !!!">>$binlogfile
        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." >> $binlogfile
                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 !!!"  >> $binlogfile
            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 "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

2、mysqlbinlog方式によりリモートオフサイトバックアップbinlogを実現する.
基本原理:mysqlbinlogの--read-from-remote-server、--stop-neverパラメータにより、オフサイトbinlogのリアルタイムバックアップを実現します.whileデッドサイクル方式により,ネットワークなどの異常によるブレークスルーを回避する.
スクリプトは次のとおりです.
#!/bin/sh
BACKUP_BIN="mysqlbinlog"
LOCAL_BACKUP_DIR="/mysqlbackup/logbak/mysql2/"                                          ###    binlog   
BACKUP_LOG="/home/mysql/log/binlog_log"
REMOTE_HOST="192.168.124.132"
REMOTE_PORT="3306"
REMOTE_USER="root"
REMOTE_PASS="linzj"
MYSQLCOMMAND="mysql -u$REMOTE_USER -p$REMOTE_PASS -P$REMOTE_PORT --protocol=tcp -N -e "
FIRST_BINLOG=$($MYSQLCOMMAND "show binary logs" 2>/dev/null|head -1|awk '{print $1}')   ###          binlog
if [ ! $FIRST_BINLOG ]
then
  echo "    binlog  ,                    binlog  "
  exit
fi
#time to wait before reconnecting after failure
SLEEP_SECONDS=10
##create local_backup_dir if necessary
mkdir -p ${LOCAL_BACKUP_DIR}
cd ${LOCAL_BACKUP_DIR}
##   while  ,           ,    
while :
do
  if [ `ls -A "${LOCAL_BACKUP_DIR}" |wc -l` -eq 0 ];then
     LAST_FILE=${FIRST_BINLOG}
  else
     LAST_FILE=`ls -l ${LOCAL_BACKUP_DIR} | tail -n 1 |awk '{print $9}'`
  fi
  ${BACKUP_BIN} --raw --read-from-remote-server --stop-never --host=${REMOTE_HOST} --port=${REMOTE_PORT} --user=${REMOTE_USER} --password=${REMOTE_PASS} ${LAST_FILE} 
  echo "`date +"%Y/%m/%d %H:%M:%S"` mysqlbinlog  ,    :$?" | tee -a ${BACKUP_LOG}
  echo "${SLEEP_SECONDS}           " | tee -a ${BACKUP_LOG}  
  sleep ${SLEEP_SECONDS}
done

以上のように、binlogバックアップの2つの方法にはそれぞれメリットとデメリットがあります.
欠点:
1つ目の方法は、バックアップをタイミングスケジューリングで実現する必要があります.極端にbinlogが失われる可能性があります(2つのタイミングスケジューリングのウィンドウ時間、MySQL異常、およびすべての本番binlogが使用できません.このウィンドウ時間によって生成されたbinlogはバックアップできません).
第2の態様では、mysqlbinlogの機能によりリアルタイムバックアップを実現し、バックアップの可用性を確認できない、すなわちファイルmd 5値を比較することでファイルが本番環境と一致しているか否かを判断できない.極端な場合、ブレークはwhileデッドサイクルによって再接続され、再接続の位置点情報はバックアップパスの最新binlogファイルに基づいているため、異常(ネットワーク異常によるブレークダウン、バックアップパスのbinlogが誤動作)が発生します.
メリット:
第1の方法は、md 5値を検証することによって、バックアップと本番の一貫性を確保することができる.バックアップのロジックは簡単で、理解しやすいです.
第2の方法はbinlogのリアルタイムバックアップ機能を実現することができる.
したがって、上記のメリットとデメリットの分析に基づいて、どのバックアップポリシーを選択するかは、本番環境の実際のニーズに応じて選択する必要があります.