首页 > 数据库 >MySQL主从同步不一致解决办法

MySQL主从同步不一致解决办法

时间:2025-01-12 09:37:16浏览次数:1  
标签:+-----+-------+------+ 解决办法 slave students MySQL mysql 从库 主从

一般主从同步错误首先要考虑是不是在从库中误操作导致的。结果发现,有人在从库中进行了一条针对有主键表的 sql 语句的插入,导致主库再插入相同 sql 的时候,主从状态出现异常。发生主键冲突的报错。

解决方法:

在确保主从数据一致性的前提下,可以在从库进行错误跳过。

像从库如果不提供什么服务的话可以在从库中开启 read_only 参数,禁止在从库进行写入操作,还有用户必须没有super 权限,设置read_only才会生效。

1 一般主从复制错误的解决办法

这是正常的状态

10.0.0.150 是主

10.0.0.151 是从

先模拟故障

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 # 这是本次的表结构 mysql> show create table students; | students | CREATE TABLE `students` (   `sid` int(11) NOT NULL,   `sname` varchar(20) DEFAULT NULL,   `sex` int(11) DEFAULT NULL,   PRIMARY KEY (`sid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 #主库执行,是个空表 mysql> select from students; Empty set (0.00 sec)   #在从库 ,给students 加1条数据: mysql> insert into students  values (1,'keme',0); mysql> show slave status\G; ...  Slave_IO_Running: Yes  Slave_SQL_Running: Yes ... 看主从状态是正常的 # 从库查看students 数据 mysql> select from students; +-----+-------+------+ | sid | sname | sex  | +-----+-------+------+ |   1 | keme  |    0 | +-----+-------+------+     # 在主库查看students 表 mysql> select from students; Empty set (0.00 sec)   # 插入相同主键的值 mysql> insert into students values (1,'keme',1);   # 查看students表 mysql> select from students; +-----+-------+------+ | sid | sname | sex  | +-----+-------+------+ |   1 | keme  |    1 | +-----+-------+------+     # 查看从库状态 mysql> show slave status\G; ... Slave_IO_Running: Yes Slave_SQL_Running: No Last_SQL_Error: Could not execute Write_rows event on table beta.students; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000023, end_log_pos 11789 ... # 主从状态不一致了,造成的原因是主键冲突

  

解决办法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # 停止从库 mysql> stop slave;   # 在从库删除主键冲突的那条语句, 把主库执行的那条语句在从库执行 mysql> delete from students where sid=1; mysql> insert into students values (1,'keme',1);   # 同步跳过临时错误 mysql> set global sql_slave_skip_counter = 1; mysql> start slave; mysql> show slave status\G; ... Slave_IO_Running: Yes Slave_SQL_Running: Yes ...   # 主库再次插入数据,看看从库是不是能够同步 mysql> insert into students  values (2,'keme',1);   # 从库查看 mysql> select from students; +-----+-------+------+ | sid | sname | sex  | +-----+-------+------+ |   1 | keme  |    1 | |   2 | keme  |    1 | +-----+-------+------+ 2 rows in set (0.00 sec)   # OK,同步成功了, 一般主从错误也就解决了

  

那这时候有问题,主从问题不一致了, 主上面插入了很多数据, 这时候该怎么解决了。

首先主从问题不一致了,你的监控预警机制了,给你发短信或者钉钉,这时候你应该尽快去修复从库,比如就像上面跳过临时同步错误,暂时让其恢复正常同步。

其次 后期就是用pt工具:比如用pt-table-checksum 找出主从表数据不一致的, pt-table-sync进行修复从库

 

2 GTID 主从复制错误解决办法

现在修改我的主从模式为GTID,这是我的测试环境随便改,

生产环境不能这样瞎改

搭建GTID主从时,需要注意的 mysql 参数:

server_id:设置 mysql 实例的 server_id,每个实例的server_id必须不一样

gtid_mode=on:MYSQL 实例开启GTID 模式。

enforce_gtid_consitency=on :使用GTID模式复制时,需要开启此参数,用来保证GTID的一致性。

log-bin=on :Msql 做主从必须开启binlog

log-slave-updates=1 :觉得slave 从master 接收到的更新且执行完之后,执行的binlog是否记录到slave的binlog中,建议开启

binlog_format=row :强烈建议binlog_format使用row格式 在mysql 5.7.6 版本以后默认就是row

skip-slave-start=1 :当slave 数据库启动的时候,slave 不会自动开启复制

 

主库操作,在[mysqld] 加一下参数,我这个做过主从, 只加一部分参数

1 2 3 4 5 # my.cnf 中内容 [mysqld] gtid-mode=on enforce-gtid-consistency=on log-slave-updates=1

  

从库操作

1 2 3 4 5 6 # my.cnf 中内容 [mysqld] gtid-mode=on enforce-gtid-consistency=on log-slave-updates=1 skip-slave-start=1

重启主从数据库

 

 

在从库 操作重新设置主从库的复制关系

1 2 3 4 5 6 7 8 9 10 11 12 13 14 mysql> CHANGE MASTER TO MASTER_HOST = '10.0.0.150', MASTER_PORT = 3306, MASTER_USER = 'repl', MASTER_PASSWORD = '123456', MASTER_AUTO_POSITION = 1; mysql> start slave;   #查看主从状态 mysql> show slave status\G; ...  Slave_IO_Running: Yes  Slave_SQL_Running: Yes ...

  

 

如果是在GTID模式下出现复制报错, 则使用SQL_SLAVE_SKIP_COUNTER语句会报错

在GTID 模式的复制情况下,如果slave 发生错误,则可以通过跳过该事务的方式恢复主从复制。

 

 现在人为制造slave错误

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # 在从库的sutdents 表插入一条数据 mysql> select from students; +-----+-------+------+ | sid | sname | sex  | +-----+-------+------+ |   1 | keme  |    1 | |   2 | keme  |    1 | +-----+-------+------+ mysql> insert into students values (3,'keme',0);   # 在查看从库的数据 mysql> select from students; +-----+-------+------+ | sid | sname | sex  | +-----+-------+------+ |   1 | keme  |    1 | |   2 | keme  |    1 | |   3 | keme  |    0 | +-----+-------+------+   # 主库也插入主键为3这条数据,引发主从同步错误 mysql> insert into students values (3,'keme',1);

  

 

 主从报错了:

 

 从图中可以看出,出错事务的binlog文件为mysql-bin.000026

开始位置(Exec_Master_Log_Pos)是154 ,结束位置是(end_log_pos ) 395,可以去主库分析下binlog ,看一下发生冲突的事务是哪个。

可以看到接收并且执行了GTID事件 是

1 2 3 4 5 6 从库执行了这些 5a13910d-1496-11e9-8375-000c29f859ce:1-3, f6c31435-38dd-11e9-ac93-000c299bcbee:1-53096   收到却没执行的事务号: Retrieved_Gtid_Set: f6c31435-38dd-11e9-ac93-000c299bcbee:53097

  

可以看出发现冲突的事务号是:f6c31435-38dd-11e9-ac93-000c299bcbee:53097,这时候就要确定哪一个事务发生了冲突,还可以直接从show slave status\G;结果中通过比对的方式找到冲突位置。

严谨起见,通过对binlog 内容分析得知冲突事务是插入了一条数据,主键为3。在从库中查看这条记录是否真的存在

1 2 3 4 5 6 mysql> select from students where sid=3; +-----+-------+------+ | sid | sname | sex  | +-----+-------+------+ |   3 | keme  |    0 | +-----+-------+------+

  

发现slave 中存在这条记录了,这时,可以通过跳过该事务的方式来放弃该事务在slave上的执行,使slave 能够正常运行。

基于GTID模式的复制,跳过一个事务,需要利用一个空事务来完成。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 mysql> stop slave; Query OK, 0 rows affected, 1 warning (0.00 sec)   mysql> set GTID_NEXT='f6c31435-38dd-11e9-ac93-000c299bcbee:53097'; Query OK, 0 rows affected (0.00 sec)   mysql> begin;commit; Query OK, 0 rows affected (0.00 sec)   Query OK, 0 rows affected (0.00 sec)   mysql> set GTID_NEXT='AUTOMATIC'; Query OK, 0 rows affected (0.00 sec)   mysql> start slave; Query OK, 0 rows affected (0.00 sec)

  

查看slave 状态

 

 哪主从库数据是否一致,就看3那条

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # 主库数据 mysql> select from students where sid=3; +-----+-------+------+ | sid | sname | sex  | +-----+-------+------+ |   3 | keme  |    1 | +-----+-------+------+   #从库数据 mysql> select from students where sid=3; +-----+-------+------+ | sid | sname | sex  | +-----+-------+------+ |   3 | keme  |    0 | +-----+-------+------+

  

解决不一致数据:

1 手动修改或者插入

2 用pt用具 来修复或者检查不一致数据

 

由于我这是我的本地环境,我只手动修改数据,再看主从状态

1 2 3 mysql> update students set  sex=1 where sid=3; Query OK, 1 row affected (0.03 sec) Rows matched: 1  Changed: 1  Warnings: 0

 

注:不止是要主从解决错误,还要主从数据的一致性 

如果是生产的核心库主从不一致,一定要查明原因,不然老是 dba 或者运维 背锅

还有如果主从不一致性实在是太多太多不一致了,就重做数据库吧

如果检查的数据某几张表不一致的情况下,可以把这几张道出来,恢复到从库

标签:+-----+-------+------+,解决办法,slave,students,MySQL,mysql,从库,主从
From: https://www.cnblogs.com/gdjgs/p/18666599

相关文章

  • MySQL数据库出现乱码怎么解决
    为什么我的数据库总会出现中文乱码的情况。一堆中文乱码不知道怎么回事?当向数据库中写入创建表,并插入中文时,会出现这种问题。此报错会涉及数据库字符集的问题。.1解决乱码的几个方面对于中文乱码的情况,从三个方面数据终端:就是我们连接数据库的工具设置为utf8操作系统层面:l......
  • MySQL can't opet file(errno:24)
    有的时候,数据库跑得好好的,突然报不能打开数据库文件的错误了。解决思路:首先我们要先查看数据库的errorlog。然后判断是表损坏,还是权限问题。还有可能磁盘空间不足导致的不能正常访问表,操作系统的限制也要关注下,相关应用限制也要关注下;123#ulimit-n查看系统的......
  • MySQL 中删除重复数据 SQL 写法
    要在MySQL中删除重复的数据并只保留一条,可以使用下面的方法(要用的时候直接复制小改下条件和表名称即即可)方法一:使用leftjoin+子查询删除重复数据(推荐)温馨提示:本人在500w数据下执行此SQL耗费15s-30s左右使用leftjoin(推荐方法删除重复数据,添加唯一组......
  • MySQL练习2
    1.单表查询(1)素材表名:worker--表中字段均为中文,比如“部门号,工资,职工号,参加工作”等(2)创建worker表CREATETABLEworker (部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政......
  • Mysql--重点篇--索引(索引分类,Hash和B-tree索引,聚簇和非聚簇索引,回表查询,覆盖索引,索引
    索引是数据库中用于加速查询操作的重要机制。通过索引,MySQL可以快速定位到满足查询条件的数据行,而不需要扫描整个表。合理的索引设计可以显著提高查询性能,但不合理的索引可能会导致性能下降和磁盘空间浪费。因此,理解索引的工作原理、类型以及如何优化索引非常重要。一、索......
  • 多个环境的anaconda中jupyter只有一个Python 3 (ipykernel)解决办法
    用anaconda打开jupyternotebook后发现,只有一个Python3(ipykernel),其他anaconda创造的虚拟环境都没法显示。解决方法:win+R调出cmd用condaenvlist调出总共有多少环境 再用activatename切换到想要的环境中,name为环境变量名然后在此环境中先输入pipinstallipykerne......
  • 老毛子PADAVAN为何不能挂载大容量移动硬盘/U盘?解决办法竟然如此简单
    问题:我用的是极路由B70,刷了PADAVAN,B70自身带有一个USB2.0,一个USB3.0,插入一个2TB的移动硬盘,NTFS格式,可以识别到,但没有挂载成功。查看日志,确实提示挂载失败,然后看到挂载的名字带有一些@@@@@。解决办法:联想自己移动硬盘的名字是中文。于是拔下移动硬盘,插上电脑,将移动硬盘卷标名......
  • FTP上传目录路径解析及HTTP错误404解决办法
    问题描述:用户尝试通过FTP上传文件到指定目录(如www),但在浏览器访问时遇到了HTTP404错误。用户想知道正确的上传路径以及如何解决此问题。解决方案:您好,针对您遇到的FTP上传目录路径及HTTP404错误的问题,以下是详细的解决方案:FTP上传路径说明:网页端访问FTP空间:您可以通过FTP......
  • 宝塔面板Nginx无法启动或启动失败的原因及解决办法
    宝塔面板中的Nginx服务在启动时遇到问题可能是由多种原因引起的。为了帮助您诊断和解决问题,以下是详细的排查步骤和解决方法。一、问题概述宝塔面板中的Nginx服务无法启动或启动失败可能发生在以下几种情况:初次安装Nginx即无法启动。安装或修改了相关配置后导致无法启动。正......
  • 【MySQL】常用的内置函数
    文章目录1.日期函数2.字符串函数3.数学函数4.其它函数在MySQL内部,有很多的函数供我们使用1.日期函数获取时间与日期current_date()current_time()current_timestamp()now()date()获取当前的日期时间仅获取当前的日期/时间获取一个时间加/减一个......