三更半夜折腾分库分表备份脚本,搞了半天没搞成,今天才发现写错了一个变量,白白浪费一小时。


   下面贴出内容,主要是使用两个for循环把每个库的每个表列出来,然后使用mysqldump进行备份。

   此脚本是在主从复制的从库中进行的,从库my.cnf有read-only,另外在备份前使用stop slave SQL_THREAD命令停止SQL线程,这样,除了拥有SUPER权限的用户可以进行更改外,在备份过程中就不会有数据更新了。从库有开binlog日志记录,flush logs之后记录下新binlog的文件名和位置以便恢复时使用。


#!/bin/bash
BACKUP_DATE=`date +%F\ %T`
WEEK=`date +%w`
IP=`/sbin/ifconfig eth0|/bin/grep "inet addr"|/bin/cut -d : -f 2|/bin/awk '{print $1}'`
BACKUP_PATH="/backup/${IP}/mysql"
LOG_FILE="${BACKUP_PATH}/mysql_${BACKUP_DATE}.log"
MYSQL_USER='root'
MYSQL_PASSWORD='baichi'
MYSQL_PATH="/usr/local/mysql/bin"
MYSQL="${MYSQL_PATH}/mysql -u${MYSQL_USER} -p${MYSQL_PASSWORD}"
MYSQL_DUMP="${MYSQL_PATH}/mysqldump -u${MYSQL_USER} -p${MYSQL_PASSWORD}"
# if BACKUP_PATH doesn't exists,mkdir
[ ! -d "${BACKUP_PATH}" ] && mkdir -p "${BACKUP_PATH}"
#========================Backup start==========================
echo "--------------backup start ${BACKUP_DATE}-----------------">>${LOG_FILE}
# stop slave SQL_THREAD and flush logs and read from master status to know binlog file name and positon
${MYSQL} -e "stop slave SQL_THREAD;flush logs;"
${MYSQL} -e "show master status \G">>${LOG_FILE}
echo >>${LOG_FILE}
#start backup every table
DBNAME="`${MYSQL} -e 'show databases;'|sed '1d'`"
echo "DATABASE LIST:" >>${LOG_FILE}
echo ${DBNAME}>>${LOG_FILE}
echo >>${LOG_FILE}
for dbname in ${DBNAME}
do
    mkdir -p "${BACKUP_PATH}/${dbname}_${WEEK}"
    #cd /backup/${dbname}_${WEEK}
    echo -e "${dbname} backup start ${BACKUP_DATE}">>"${LOG_FILE}"
    TABNAME=`${MYSQL} ${dbname} -e 'show tables;'|sed '1d'`
        echo "TABLE LIST:" >>${LOG_FILE}
        echo ${TABNAME}>>${LOG_FILE}
        echo >>${LOG_FILE}
    for tabname in ${TABNAME}
    do
        ${MYSQL_DUMP} ${dbname} ${tabname}>${BACKUP_PATH}/${dbname}_${WEEK}/${tabname}.sql
    done
done
${MYSQL} -e "start slave SQL_THREAD;flush logs;"
echo "--------------backup end ${BACKUP_DATE}-----------------">>${LOG_FILE}
mail -s "MySQL fenbiao backup log" root@localhost<"${LOG_FILE}"