Mysql中双机热备比较常见。运维过程中遇到一个问题,备机或主机的其中一台遇到硬盘物理故障,重装系统后需要重新同步数据。这时就遇到了一个问题,用“FLUSH TABLES WITH READ LOCK;”命令锁上所有表或者再mysqldump数据时使用“–lock-all-tables”或“–master-data”参数导出数据,但是数据库被锁不能操作,前台业务会报错,问题很严重。在oracle中有SCN(The System Change Number),在mysql的二进制日志中有position,所以只能从此处考虑。
所以我写一个脚本,思维逻辑如下:
a) 使用语句“show master statusG;” 获得导出开始的position的点
b) 开始导出整库数据
c) 导出完毕,再使用语句“show master statusG;” 获得导出结束的position的点
d) 从binlog中导出开始position点到结束position点得变化的增量数据
导入逻辑:
a) 先导入整库数据
b) 再导入增量的数据
c) 然后确认开始同步的position点,开始同步
做增量的数据需要使用mysql自带的mysqlbinlog命令,mysqlbinlog也可以远程使用,为了防止网络问题所以没有采用远程的方案。
Mysqlbinlog命令的主要参数如下:
-d, –database=name 仅列出该数据库相关的
-F, –force-if-open 强行读出正在使用的二进制文件
-j, –start-position=# 开始读取点
–stop-position=# 结束读取点
–start-date 开始获取时间
–stop-date 结束获取时间
导出完毕,在备机上先恢复整库文件,再恢复增量文件,再设置恢复点。还有几个文件问题没有太仔细考虑,如备份过程中二进制日志切换,数据量大的时候会出现增量和整库的重复等问题未考虑。本处只是抛砖引玉。
脚本如下(注意折行问题):
#!/bin/sh
#————————————————
# file name: mysql_dump_binlog.sh
# Revision: 1.0
# Date: 2011-09-10
# Author: simon-zzm
# Email: simon-zzm@163.com
# ———————————————–
#############set bases value
mysql_path=’/usr/local/mysql’
dump_path=’/usr/local/checksystem’
mysql_host=’192.168.1.12′
mysql_user=’root’
mysql_pass=’qq’
mysql_data=’test’
#############main
start_time=`/bin/date +%Y-%m-%d %H:%M:%S`
${mysql_path}/bin/mysql -h${mysql_host} -u${mysql_user} -p${mysql_pass} -e ‘show master statusg;’>/tmp/mysql_start_read_mast
get_start_f=`tail -1 /tmp/mysql_start_read_mast|/bin/awk ‘ ”{print $1}’`
#${mysql_path}/bin/mysqldump -h${mysql_host} -u${mysql_user} -p${mysql_pass} ${mysql_data}>${dump_path}/${mysql_data}_${now_time}.sql
sleep 30
${mysql_path}/bin/mysql -h${mysql_host} -u${mysql_user} -p${mysql_pass} -e ‘show master statusg;’>/tmp/mysql_end_read_mast
get_end_p=`/usr/bin/tail -1 /tmp/mysql_end_read_mast|/bin/awk ‘ ”{print $2}’`
get_end_f=`/usr/bin/tail -1 /tmp/mysql_end_read_mast|/bin/awk ‘ ”{print $1}’`
echo “dump database ${mysql_data} ok.”
stop_time=`/bin/date +%Y-%m-%d %H:%M:%S`
${mysql_path}/bin/mysqlbinlog -d${mysql_data} -F –start-date=”${start_time}” –stop-date=”${stop_time}” ${mysql_path}/data/${get_start_f}>${dump_path}/${mysql_data}_repair_${now_time}.sql
echo “CHANGE MASTER TO MASTER_LOG_FILE=’${get_end_f}’,MASTER_LOG_POS=${get_end_p} ; “
/bin/rm -rf /tmp/mysql_start_read_mast /tmp/mysql_end_read_mast
echo “repair database ${mysql_data} ok.”
发表评论