点击(此处)折叠或打开
#!/bin/bash
#Author:wwa
USER=
PWD=
HOST=
PORT=
REP=
REPPWD=
REPH=
REPP=
GTID=$2
GTID_START=$3
GTID_END=$4
GTID_PURGE(){
echo "GTID_UUID:$GTID, GTID_START:$GTID_START, GTID_END=%GTID_END"
mysql -u$USER -p$PWD -h$HOST -P$PORT -e "stop slave;reset slave;reset master;set global gtid_purged='$GTID:$GTID_START-$GTID_END';CHANGE MASTER TO MASTER_HOST='$REPH', MASTER_PORT=$REPP, MASTER_USER='$REP',MASTER_PASSWORD='$REPPWD', master_auto_position=1;start slave;"
sleep 1
mysql -u$USER -p$PWD -h$HOST -P$PORT -e "show slave status\G;"
}
GTID_SKIP(){
mysql -u$USER -p$PWD -h$HOST -P$PORT -e "stop slave;set session gtid_next='$GTID:$GTID_START';begin;commit;set session gtid_next="AUTOMATIC";start slave;"
case "$1" in
GTID_PURGE)
echo "Start GTID_PURGE, transaction in $GTID between $GTID_START-$GTID_END will be skipped......"
GTID_PURGE
echo "GTID_PURGE success......"
;;
GTID_SKIP)
echo "Start GTID_SKIP, transaction $GTID:$GTID_START will be skipped......"
GTID_SKIP
echo "GTID_SKIP success......"
*)
echo $"Usage: $0 {GTID_PURGE args1 args2 args3|GTID_SKIP args1 args2}"
exit 1
esac
使用简介
GTID_PURGE() 当同步发生大量的错误时,使用flush table with read lock锁住主库,记录GTID的事务编号(最后那个,例如后面示例里面的142787),然后数据同步到从库,在参数中加上UUID(空格)起始事务编号(空格)中止事务编号
原理:purge掉master log中,同步数据的SCN之前的事务,从同步时间点以后开始读取binlog; 这样做的好处是不用去master操作,清理binlog(手抖清理了其他东西就不好了~)
GTID_SKIP() 当发生少量的错误时,使用show slave status\G;找到UUID和出错的事务编号,参数中加上 UUID(空格)事务编号
原理:生成一个空事务来跳过原本出错的事务,然后继续往下同步
关于如何判断GTID_SKIP()需要跳过的事务编号:
假设出错时,slave status是这个样子,
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiInBnauUjNlRDNzMTN3Y2YmFWM2UzY1YjM4EGM4IGMwITZ2U2MfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.jpg)
箭头所指的代表从主库拉去的日志中,包含哪些事务(以编号的形式);
方框所指的代表从库现在执行了哪些事务;这里的意思就是从库已经执行了编号1到编号139595的事务
如果出错了,说明139596事务出错了,这时候执行脚本里的事务编号写上139596就行
实际使用效果如图(截图时间截晚了,事务ID对不上,不过意思表达清楚了就好~)
结语:任何发生于数据库上的操作一定要三思而后回车,血的教训数不胜数,所以验证无误的固定操作,用脚本来实现是个不错的选择。