如何远程备份MySQL binlog

如何远程备份MySQL binlog 以前备份binlog时都是先在本地进行备份压缩然后发送到远程服务器中。但是这其中还是有一定风险的因为日志的备份都是周期性的如果在某个周期中服务器宕机了硬盘损坏了就可能导致这段时间的binlog就丢失了。而且以前用脚本对远程服务器进行备份的方式有个缺点无法对MySQL服务器当前正在写的二进制日志文件进行备份。所以只能等到MySQL服务器全部写完才能进行备份。而写完一个binlog的时间并不固定这就导致备份周期的不确定。从MySQL5.6开始mysqlbinlog支持将远程服务器上的binlog实时复制到本地服务器上。mysqlbinlog的实时二进制复制功能并非简单的将远程服务器的日志复制过来它是通过MySQL 5.6公布的Replication API实时获取二进制事件。本质上就相当于MySQL的从服务器。与普通服务器类似主服务器发生事件后一般都会在0.5~1秒内进行备份。备份命令mysqlbinlog --read-from-remote-server --raw --host192.168.244.145 --port3306 --userrepl --passwordrepl --stop-never mysql-bin.000001解释如下--read-from-remote-server用于备份远程服务器的binlog。如果不指定该选项则会查找本地的binlog。--rawbinlog日志会以二进制格式存储在磁盘中如果不指定该选项则会以文本形式保存。--user复制的MySQL用户只需要授予REPLICATION SLAVE权限。--stop-nevermysqlbinlog可以只从远程服务器获取指定的几个binlog也可将不断生成的binlog保存到本地。指定此选项代表只要远程服务器不关闭或者连接未断开mysqlbinlog就会不断的复制远程服务器上的binlog。mysql-bin.000001代表从哪个binlog开始复制。除了以上选项外还有以下几个选项需要注意--stop-never-slave-server-id在备份远程服务器的binlog时mysqlbinlog本质上就相当于一个从服务器该选项就是用来指定从服务器的server-id的。默认为-1。--to-last-log代表mysqlbinlog不仅能够获取指定的binlog还能获取其后生成的binlog获取完了才终止。如果指定了--stop-never选项则会隐式打开--to-last-log选项。--result-file用于设置远程服务器的binlog保存到本地的前缀。譬如对于mysql-bin.000001如果指定--result-file/test/backup-则保存到本地后的文件名为/test/backup-mysql-bin.000001。注意如果将--result-file设置为目录则一定要带上目录分隔符“/”。譬如--result-file/test/而不是--result-file/test不然保存到本地的文件名为/testmysql-bin.000001。不足这个方式有个问题对于常规的主从复制来说如果主从直接的连接断开了则从会自动再次连接而对于mysqlbinlog如果断开了并不会自动连接。解决方案可通过脚本来弥补上述不足。#!/bin/sh BACKUP_BIN/usr/bin/mysqlbinlog LOCAL_BACKUP_DIR/backup/binlog/ BACKUP_LOG/backup/binlog/backuplog REMOTE_HOST192.168.244.145 REMOTE_PORT3306 REMOTE_USERrepl REMOTE_PASSrepl FIRST_BINLOGmysql-bin.000001 #time to wait before reconnecting after failure SLEEP_SECONDS10 ##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_FILEls -l ${LOCAL_BACKUP_DIR} | grep -v backuplog |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脚本解读1. 实际上定义了一个死循环如果备份失败则10s后重新连接。2. 第一次运行时需指定FIRST_BINLOG的值指从哪个binlog开始复制一般为mysql-bin.000001。后续执行的时候就直接获取备份目录下最新的binlog从最新的binlog开始复制。总结1. 如果指定了--rawmysqlbinlog获取事件后并不会实时落盘而是先保存在本地服务器的内存中每4K刷盘一次。这也就减少了频繁的日志写操作。如果此时mysqlbinlog和主服务器之间的连接断开了则内存中的binlog会马上刷新到磁盘中。2. 尽管mysqlbinlog类似于从服务器但从服务器上的relaylog却是实时存盘的即从服务器获取主服务器产生的事件后会实时写入到relaylog中。3. 如果不指定--raw这个时候会以文本格式存盘此时--result-file/test/不能指定为目录必须明确写上文件名譬如--result-file/test/1.sql此时mysqlbinlog获取事件后是实时落盘的不会每4K刷盘一次。