MySQL主从同步问题&延时从库的"闪回"

延时从库联动贴:http://blog.itpub.net/29510932/viewspace-1677278/   (渣排版,以后改改_(:з」∠)_)
-------------------------------------------------------------------------------------正文------------------------------------------------------------------------------------
背景:折腾MySQL-5.7.9的副产品;所有的演练和操作都是基于5.7.9,和5.6.2x应该不会有什么区别

问题的现象:Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Slave has more GTIDs than the master has, using the master's SERVER_UUID. This may indicate that the end of the binary log was truncated or that the last binary log file was lost, e.g., after a power or disk failure when sync_binlog != 1. The master may or may not have rolled back transactions that were already replica'

问题发生的原因:在从库start slave时出现错误;

问题分析:
主从同步还是依靠日志来完成的,出现这种问题的原因就是从库的slave_master_info中的信息与主库的状态不一致, slave_IO_thread依靠从库的slave_master_info信息,去主库上“继续”dump binlog的时候,找不到数据了;

问题解决的方法:
1.change master的时候, 指明一个确定的log_file和log_pos,不要图方便用auto_position;
2.确定主从当前的数据是完全一致的情况下(主库处于只读状态or完全停库状态),在slave和master上reset master, 清理掉所有的日志, 然后用auto_position开启新的同步;

方法1更加常用一些,毕竟停库的机会基本不会有;
PS:在多源复制中,如果提示ERROR 3079 (HY000): Multiple channels exist on the slave. Please provide channel name as an argument. 需要用reset slave all去清空多个channel的信息;

-----------------------------------------------------------------------------------问题的延伸------------------------------------------------------------------------------------
提到从库,之前取巧, 用单独的延时从库来实现闪回,出现问题后,如果涉及的数据比较少的时候,可以直接解析binlog去恢复(ROW),
如果涉及到的数据比较多(比如说没有where的update http://blog.itpub.net/29510932/viewspace-1962834/)的时候,利用备份重新生成备库,也会消耗相当多的时间;

延伸:如果存在延时从库,该如何进行“闪回”/数据恢复?

分析&捕捉:
大前提,延时从库还没有执行那条错误的语句,那么在延时从库上就存在着正确的数据,因此可以第一时间停掉slave_SQL_thread,然后控制slave_SQL_thread执行到特定的pos,再进行恢复;

演练:
构造测试用的表

点击(此处)折叠或打开

  1. CREATE TABLE `student` (
  2.   `sid` bigint(20) NOT NULL,
  3.   `sname` varchar(10) DEFAULT NULL,
  4.   `col1` int(11) DEFAULT NULL,
  5.   `col2` bigint(20) NOT NULL,
  6.   `time` datetime NOT NULL DEFAULT '2015-11-11 00:00:00',
  7.   PRIMARY KEY (`sid`),
  8.   KEY `idx_c1_c2` (`col1`,`col2`),
  9.   KEY `idx_c1_c2_si` (`col1`,`col2`,`sid`),
  10.   KEY `idx_time` (`time`),
  11.   KEY `idx_sname` (`sname`),
  12.   KEY `idx_col2` (`col2`)
  13. ) ENGINE=InnoDB DEFAULT CHARSET=utf8

数据:

点击(此处)折叠或打开

  1. INSERT INTO `student` VALUES (10000,'lily',9,10,'2015-11-11 00:00:01'),(10001,'lucy',11,1,'2015-11-01 00:00:01'),(10002,'tom',3,3,'2015-11-10 00:00:01'),(10003,'tommy',4,6,'2015-11-09 00:00:01'),(10004,'jhon',8,15,'2015-11-12 00:00:01'),(10005,'dave',14,27,'2015-11-02 00:00:01'),(10006,'charly',19,36,'2015-11-07 00:00:01'),(10007,'sam',23,21,'2015-11-08 00:00:01'),(10008,'titan',31,7,'2015-11-11 00:00:01'),(10009,'anny',27,12,'2015-11-10 00:00:01');

通过关闭一个从库的SQL_thread来模拟延时从库,(从主库拉取binlog,但是这些binlog的内容没有在从库复现,类似于保持X分钟前的状态

延时从库的测试数据:

在主库上进行操作,正确的语句执行完以后的效果:

错误的语句--没有where的update

假设及时的发现了问题,且从库并没有复现这些语句,那么及时停掉从库的SQL_thread,
就可以变成类似于测试环境的情况,查看从库的状态,可以看到接收到了新的binlog,但是从库并没有复现这些操作

回到主库上,用mysqlbinlog来解析日志

可以看到535的事务是这个有问题的事务, 那么可以在从库指定这个事务作为终止事务,
在命令行下输入START SLAVE SQL_THREAD UNTIL SQL_BEFORE_GTIDS = 'dfe44b6e-940a-11e5-89a6-005056a94f05:535';
指定 SQL_THREAD执行到535之前的事务,然后SQL_THREAD会自动停止,看一下slave的status

可以看到slave执行完了533和534之后,没有执行535,然后停下来了,看看从库的表数据,可以发现数据正好在错误的语句之前,

接下来就比较简单了, 把表数据导出来,然后在主库上恢复;

-----------------------------------------------------------------------------------额外的唠叨------------------------------------------------------------------------------------
现实中的情况永远要复杂很多,如果业务繁忙,在这个错误语句之后如果还有其他的业务在对这张表做操作的话,只做上文的步骤,就会有丢事务/业务操作的情形出现,这种情况下,就要准备折腾这个延时从库了;

新的问题&需求:虽然执行了错误的语句,但是后续还是有业务相关的SQL产生,而且都很重要, 不能丢

解决的办法:
直到上一步为止,刚好是让延时从库停在了错误的事务之前,为了能让后续的操作不丢失,需要在延时从库上生成一个空事务,跳过有问题的这个535事务,然后去掉延时从库的延时,
等追上主库的时候,这个表的数据就是完整的数据
PS:GTID跳过错误事务的方法参考http://blog.itpub.net/29510932/viewspace-1736132/

-----------------------------------------------------------------------------------唠叨的最后------------------------------------------------------------------------------------

对于额外的唠叨这一部分,只是实际情况中的一种,好的处理方案一定是和实际的业务特点结合在一起的,谨慎的对待已有的“解决方案
任何操作都尽可能要在测试环境验证过再去生产环境上面操作;
平时的演练很重要,不要等出问题了再去测试环境验证.......(少偷点懒,养兵千日,用兵一时_(:з」∠)_...)
折腾完了记得把延时从库恢复了......

新年第一篇博客,over~

时间: 2024-10-14 22:10:54

MySQL主从同步问题&延时从库的"闪回"的相关文章

mysql主从同步

MySQL编译安装 shell> groupadd mysql shell> useradd -g mysql mysql shell> gunzip < mysql-VERSION.tar.gz | tar -xvf - shell> cd mysql-VERSION shell> ./configure --prefix=/usr/local/mysql shell> make shell> make install shell> cp suppo

怎样重配 重置mysql主从同步

重置mysql主从同步(MySQL Reset Master-Slave Replication) 在mysql主从同步的过程中,可能会因为各种原因出现主库与从库不同步的情况,网上虽然有一些解决办法,但是有时很难彻底解决,重置主从服务器也许不是最快的办法,但却是最安全有效的. 下面将自己重置主从同步的步骤总结一下,以备不时之需. master与slave均使用:centos6.0+mysql 5.1.61 ,假设有db1,db2两个数据库需要热备. 文中shell与mysql均使用root账号,

一种MySQL主从同步加速方案

一.问题起源 MySQL的主从同步一直有从库延迟的问题,背景资料网上很多,原因简单描述如下: 1. MySQL从库上有一个IO线程负责从主库取binlog到写到本地.另外有一个SQL线程负责执行这些本地日志,实现命令重放: 2. 正常网络状况下IO线程没有性能问题(这个待会会用到),问题是SQL线程只有一个,更新速度跟不上.所以经常会看到从库的CPU idle很高,但同步性能就是上不去. 二.方案雏形 单线程的SQL线程是造成这个问题的主要原因.比较直接的想法是把它改成多线程版本,这个据说官方版

mysql 主从同步

mysql cmake install 过程我在这边就不说了,如果要看的朋友,点击我以前的博客 ,mysql version : 5.6.13 http://blog.csdn.net/wanglei_storage/article/details/48262141 下一篇是mysql 主从同步 + atlas读写分离,也就是目前比较热门的技术了 http://blog.csdn.net/wanglei_storage/article/details/48808777 好,下面进入正题.通过两台

centos 6.5设置mysql主从同步过程记录

在centos 6.5上设置了mysql主从功能,记录一下. 服务器1(主) IP:192.168.1.201 系统版本:centos 6.5 mysql版本:mysql 5.5 服务器2(从) IP:192.168.1.202 系统版本:centos 6.5 mysql版本:mysql 5.5 这里两台服务器的系统版本和mysql版本均一致,这也是官方推荐的做法.在开始设定之前,最好能确保主库和从库一致. 1.主库和从库创建同步用户 mysql> grant replication slave

Linux下MySQL主从同步监控shell脚本

说明: 操作系统:CentOS 目的:定时监控MySQL主从数据库是否同步,如果不同步,记录故障时间,并执行命令使主从恢复同步状态 1.创建脚本文件 vi /home/crontab/check_mysql_slave.sh   #编辑,添加下面代码 #!/bin/sh # check_mysql_slave status # author www.111cn.net ip=eth0  #网卡名称 mysql_binfile=/usr/local/mysql/bin/mysql mysql_us

Linux环境中MySQL主从同步--添加新的从库

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dgd2010.blog.51cto.com/1539422/1689171 当前我认为数据库主从有两大应用价值: 1.从库相当于主库的备份.虽然数据库的主从并不能代替/取代备份,例如错误的数据可能毁掉所有的数据库,但主从也是在一种可读的状态下保持备份的一种实现方式. 2.从库可以缓解主库的压力,能提高性能.由于从库是只读的,因此在读取查询方面,从库可以代替主库,承担一定的压力,

MySQL主从同步原理介绍

  概述 Mysql的Replication(复制)是一个异步的复制过程,从一个 Mysql instance(我们称之为 Master)复制到另一个Mysql instance(我们称之 Slave).在 Master 与 Slave之间的实现整个复制过程主要由三个线程来完成,其中两个线程(Sql线程和IO线程)在 Slave 端,另外一个线程(IO线程)在Master端. 主从同步需求 要实现 MySQL 的 Replication ,首先必须打开 Master 端的BinaryLog(my

MySQL主从同步加速 Transfer-- FAQ

  Q: Transfer是什么 A: 是一个解决MySQL原生主从同步延迟的方案. Transfer本身是一个在MySQL源码上打的patch,可以用于当Slave,也可以用于当第三方工具,将Master的数据同步发给Slave. 利用多线程实现主从无延迟.   Q: Transfer目前的发布形式? A: 目前的发布形式是可执行的mysqld文件. 最后更新日期 2013-12-01 Transfer.2.3 下载地址    Q: Transfer模式下,主库执行grant 语句会导致同步停