专栏首页杨建荣的学习笔记MySQL复制的奇怪问题跟进

MySQL复制的奇怪问题跟进

MySQL复制问题的分析

没想到今天在做压力测试的时候,又碰到了类似的问题,这个问题的紧要程度要排上了日程。

从binlog日志的解析结果来看,是这样的语句:

#190709 17:18:04 server id 182 end_log_pos 398120311 CRC32 0x89d5a523 Update_rows: table id 5252840 flags: STMT_END_F

### UPDATE `tbo_db`.`tda_data_20190709`

### WHERE

### @1=749375136 /* LONGINT meta=0 nullable=0 is_null=0 */

### @2=7202 /* INT meta=0 nullable=0 is_null=0 */

### @3=1 /* INT meta=0 nullable=0 is_null=0 */

### @4='2019-07-09 17:18:04' /* DATETIME(0) meta=0 nullable=0 is_null=0 */

### @5='2019-07-09 17:18:04' /* DATETIME(0) meta=0 nullable=0 is_null=0 */

### @6=0 /* LONGINT meta=0 nullable=0 is_null=0 */

### SET

### @1=749375136 /* LONGINT meta=0 nullable=0 is_null=0 */

--

这个语句乍一看有些不合逻辑,所以按照输出的错误和问题发生的场景。如下的错误似乎也有一定的道理。

Could not execute Update_rows event on table tbo_db.tda_data_20190709; Can't find record in 'tda_data_20190709',

修复的过程是常规的思路,从主库的binlog中解析得到相关的偏移量位置附近的语句,然后评估是否可以跳过,如果跳过则需要指向下一个GTID事务。

我上次抛出了几个问题,我们来逐个做下验证:

如果使用类似的语句,在MySQL主库端会直接抛错。

>>update test where id=100 and name='aa' set id=100;

ERROR 1064 (42000):

而如果改为update,set,where的句式,语句可以成功,尽管变更无法匹配到相关数据,但是会生成相关的binlog,从库的复制是正常的.

>>update test set id=100 , name='aa' where id=100;

Query OK, 0 rows affected (0.00 sec)

我们再来看一个案例,首先我们看下数据情况:

select * from test;

+----+------+-------+

| id | name | memo1 |

+----+------+-------+

| 1 | aa | NULL |

| 2 | bb | NULL |

+----+------+-------+

2 rows in set (0.00 sec)

建表语句为:

CREATE TABLE `test` (

`id` int(11) NOT NULL,

`name` varchar(30) DEFAULT NULL,

`memo1` varchar(30) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `idx_name` (`name`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

我们接着使用正常的update做下变更。

>>update test set id=1 where id=1 and name='aaa';

Query OK, 0 rows affected (0.00 sec)

这种情况下的变更结果显示为0,但是依然是正常执行的。

而查看binlog的状态,会发现生成的update语句也是正常的没有做任何的改变。

#190709 23:37:57 server id 213 end_log_pos 149605040 CRC32 0xc6a341aa Query thread_id=288594 exec_time=0 error_code=0

SET TIMESTAMP=1562686677/*!*/;

update test set id=1 where id=1 and name='aaa'

/*!*/;

# at 149605040

#190709 23:37:57 server id 213 end_log_pos 149605120 CRC32 0x22ffd3a3 Query thread_id=288594 exec_time=0 error_code=0

SET TIMESTAMP=1562686677/*!*/;

到了这里,我们基本有一个整体的印象了。我们再来回顾下那个update语句,会发现似乎where和set子句的顺序写反了。

应该是update set xxxxx where xxxx

而顺着这个思路往下思考,似乎这个问题也就解释的通了。

对于我来说,对于这个问题的修复也是需要多方确认,首先需要排除应用端的一些高并发处理的异常情况。

同时在MySQL中查看是否存在一些相关的复制bug,这个问题还会持续跟进。

本文分享自微信公众号 - 杨建荣的学习笔记(jianrong-notes),作者:杨建荣

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 关于MySQL中insert ignore,insert on duplicate和replace into,你可能没想过区别

    在数据流转中或者日常的数据操作中,势必会有数据写入的过程,如果把一些数据写入一张数据库表中,如果写入量有100万,而重复的数据有90万,那么如何让这10%的数据...

    jeanron100
  • 通过Maxwell解析MySQL Binlog,打好业务多活的基础

    在Binlog解析方向和数据流转方向上,经常会提到比较有名的几类工具,阿里的Canal,Zendesk的Maxwell和Yelp的mysql_streamer,...

    jeanron100
  • 一道经典的MySQL面试题,答案出现三次反转

    前几天偶然看到大家在讨论一道面试题,而且答案也不够统一,我感觉蛮有意思,在此就做一个解读,整个过程中确实会有几处反转。

    jeanron100
  • mybatis获取update的id

    平常我门都是更新数据,用更新的条件再查询一次,得到更新的记录。这样我门就进行了两次数据库操作,链接了两次数据库。增加了接口的处理事件,因为链接数据库是很耗时...

    似水的流年
  • LeetCode MySQL 1241. 每个帖子的评论数

    结果表应包含帖子的 post_id 和对应的评论数 number_of_comments 并且按 post_id 升序排列。

    Michael阿明
  • mybatis获取update的id

    平常我门都是更新数据,用更新的条件再查询一次,得到更新的记录。这样我门就进行了两次数据库操作,链接了两次数据库。增加了接口的处理事件,因为链接数据库是很耗时的操...

    似水的流年
  • mybatis获取update的id

    平常我门都是更新数据,用更新的条件再查询一次,得到更新的记录。这样我门就进行了两次数据库操作,链接了两次数据库。增加了接口的处理事件,因为链接数据库是很耗时的操...

    似水的流年
  • 什么是SQL注入?如何预防?

    本次演示使用的是目前最热门的Java快速开发架构:SpringBoot2.3.4 + Mybatis + Mysql8

    甲蛙全栈
  • oracle 中start with ... connect by prior 子句的用法

    小小明童鞋
  • 真假唯一数

    在真实的业务中生成唯一数是常见的功能,也是面试必考题。今天说说在面试过程中面试官在问这个问题时最想得到怎样的答案。

    sibenx

扫码关注云+社区

领取腾讯云代金券