2016-06-10 李丹 dba流浪猫

我们平时除了解决自己问题外,有时候也会协助圈内人士,进行一些故障排查,此案例就是帮某公司DBA进行的故障分析,因为比较典型,特分享一下,但仅仅是分享发生的过程,不对该案例的产生以及如何避免做过多评价!

pt-online-schema-change:是对大表进行在线alter操作,并尽量避免影响线上业务,这是最优秀的mysql管理工作之一,在平时的工作中,帮助我们胜多。

环境说明

pt-osc 版本:percona-toolkit-2.2.14

mysql版本: percona-server-5.5

数据库架构:双主复制(本次pt-osc改表是在未在线主库上执行的)

问题描述

某天接到圈内朋友求助,反馈使用pt-online-schema-change 添加字段却意外产生了死锁的情况,并且数据可能有问题了,哥们百思不得骑姐希望我能帮忙分析分析。不过因线上环境没法测试复现,因此只给了死锁发生时的引擎日志(执行 SHOW ENGINE  innodb STATUS 查看)。

我们来看看当时存储引擎的日志情况,这里为了方便只截取了事务相关日志,其他日志信息略过,具体日志如下:

TRANSACTION1

*** (1) TRANSACTION:

TRANSACTION 107BF2CDD, ACTIVE 1 sec setting auto-inc lock

mysql tables in use 2, locked 2

LOCK WAIT 4 lock struct(s), heap size 1248, 1 row lock(s), undo log entries 2

MySQL thread id 6, OS thread handle 0x7fd210190700, query id 1080843123 Reading event from the relay log

*** (1) WAITING FOR THIS LOCK TO BE GRANTED:

TABLE LOCK table `redcliff`.`_rider_new` trx id 107BF2CDD lock mode AUTO-INC waiting

这里我们能读懂两个信息:

1:事务是从relaylog 读取日志                                                      2:事务1(事务id为107BF2CDD)正在等待_rider_new表AUTO-INC锁

TRANSACTION2

*** (2) TRANSACTION:

TRANSACTION 107BF2CDC, ACTIVE 1 sec fetching rows

mysql tables in use 2, locked 2

253 lock struct(s), heap size 31160, 10864 row lock(s), undo log entries 10616

MySQL thread id 22433333, OS thread handle 0x7fc781b16700, query id 1080843120 127.0.0.1 dwbdba_mgr Sending data

INSERT LOW_PRIORITY IGNORE INTO `redcliff`.`_rider_new`

************************************(省略中)

`frozen_provision`, `bloc…. LOCK IN SHARE MODE  /*pt-online-schema-change 18153 copy nibble*/

*** (2) HOLDS THE LOCK(S):

TABLE LOCK table `redcliff`.`_rider_new` trx id 107BF2CDC lock mode AUTO-INC

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:

RECORD LOCKS space id 636 page no 4599 n bits 112 index `PRIMARY` of table

`redcliff`.`rider` trx id 107BF2CDC lock mode S waiting

*** WE ROLL BACK TRANSACTION (1)

我们能读懂如下信息:

1、事务2(事务id 为107BF2CDC)持有表_rider_new 的auto-inc 自增锁

2、事务2等待rider表S锁

3、pt-osc工具通过LOCK IN SHARE MODE来实现读取当前读取之后还需要保证其他并发事务不能修改当前读取的记录,确保数据的新老数据的100%一致,故要对读取记录加S锁

通过上面读懂的信息我们分析如下:

事务1

1、Reading event from the relay log 要执行对rider表的修改

(这里事后通过解析relaylog确认是对rider表进行的修改)

故持有rider表记录上的x锁

2、等待_rider_new 表上的auto-inc lock

(注:pt-osc工具对表进行修改会在表上创建增删改三个触发器。故rider表上有已有三个触发器,并且对rider表的update,insert操作触发器触发后会转换为_rider_new表上的replace 操作,在有自增id的表上replace操作会产生新的自增id值)

事务2

1、INSERT LOW_PRIORITY IGNORE INTO `redcliff`.`_rider_new` (`id`, `city_id`,

该语句需要往_rider_new表批量写入数据,这里已经持有 _rider_new 表上的auto-inc lock, 从上面的分析可以看到事务需要等待rider 表上的共享读锁!

删繁就简

事务一:

持有:rider表记录上的x锁

等待:rider_new 表上的auto-inc lock

事务二:

持有:_rider_new 表上的auto-inc lock

等待:rider 表上的S锁

完美的死锁

最后回滚事务1(即复制更新操作被回滚,主从数据不一致)

我的观点

在以上的分析中,我们得出,pt-osc工具在某些情况下,可能会因为死锁回滚而导致数据的不一致,根据原理,我们无法避免,只能尽量缓解(例如: --chunk-size参数设置的更小,或者在TPS极大的线上不使用pt-osc),在mysql online ddl 发展尚不完善的情况下,相信当前mysql DBA 线上使用的改表工具主流还是pt-online-schema-change ,所以希望通过本次的分享让大家少踩点坑,早回家睡会好觉。

pt-osc改表导致数据不一致案例分析的更多相关文章

  1. Redis面试题记录--缓存双写情况下导致数据不一致问题

    转载自:https://blog.csdn.net/lzhcoder/article/details/79469123 https://blog.csdn.net/u013374645/article ...

  2. 三年之久的 etcd3 数据不一致 bug 分析

    问题背景 诡异的 K8S 滚动更新异常 笔者某天收到同事反馈,测试环境中 K8S 集群进行滚动更新发布时未生效.通过 kube-apiserver 查看发现,对应的 Deployment 版本已经是最 ...

  3. 演示stop暴力停止线程导致数据不一致的问题,但是有些有趣的发现 (2017-07-03 21:25)

    如注释所言 /** * Created by weiwei22 on 17/7/3. * * 这里主要是为了演示stop导致的数据不一致的问题.stop会暴力的结束线程并释放锁,所以有可能在恰好写了一 ...

  4. [经验分享] MySQL Innodb表导致死锁日志情况分析与归纳【转,纯学习】

    在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下: (1)insert into backup_ta ...

  5. MySQL Innodb表导致死锁日志情况分析与归纳

    发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志   案例描述在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时 ...

  6. ORA-04031错误导致宕机案例分析

    今天遇到一起ORACLE数据库宕机案例,下面是对这起数据库宕机案例的原因进行分析.解读.分析过程中顺便记录一下这个案例的前因后果,攒点经验值,培养一下分析.解决问题的能力. 案例环境:   操作系统 ...

  7. DML:增、删、改表中数据

    1. 添加数据 (1) 常规添加 INSERT INTO 表名(列名,列名,列名) VALUES(值,值,值); (2) 简化添加 INSERT INTO 表名 VALUES(值,值,值); 规则: ...

  8. UPDATE---修改表中数据

    UPDATE table_name SET column1=value1,column2=value2,... [WHERE conditions]; 例: UPDATE userinfo SET n ...

  9. netcore服务程序暴力退出导致的业务数据不一致的一种解决方案(优雅退出)

    一: 问题提出 现如今大家写的netcore程序大多部署在linux平台上,而且服务程序里面可能会做各种复杂的操作,涉及到多数据源(mysql,redis,kafka).成功部署成后台 进程之后,你以 ...

随机推荐

  1. 湖南集训day4

    难度:☆☆☆☆☆☆☆ 题解: 有个定理,另sum(x)表示小于等于x的数中与x互质的数的和 sum(x)=φ(x)*x/2    最后可知f(x)=x  (f(1)=2)  当然打表能知道. 然后就转 ...

  2. AcWing算法基础1.1

    排序 快速排序(快排) 写题的时候用的不多基本都是直接sort ( ),面试可能要手撸快排,上模板 void quick_sort(int q[], int l, int r) { if(l > ...

  3. 关于swoole 和golang 的压力测试结果

    一.环境介绍 linux centos7 php7.1.18 go1.12.1 2核4G内存 二.代码 swoole代码 <?php $http = new swoole_http_server ...

  4. linux 查看 cpu

    如何获得CPU的详细信息: linux命令:cat /proc/cpuinfo 用命令判断几个物理CPU,几个核等: 逻辑CPU个数:# cat /proc/cpuinfo | grep " ...

  5. Codeforces 771C

    我的树形dp果然是渣... 题意:给一棵树,共n(0<n<=15e4)个节点,可在树上进行跳跃,每次跳的最大距离为k(0<k<=5),定义f(s,t)为(dis(s,t)+k) ...

  6. Java系列学习(九)-多态

    1.final关键字 (1)最终的意思, 可以修饰类,方法,变量 (2)特点: A:它修饰的类,不能被继承 B:它修饰的方法,不能被重写(覆盖) C:它修饰的变量,这个变量其实是一个常量 [扩展] ① ...

  7. java DDD 基于maven开发的探讨

    对于DDD我目前的理解是 1.除了数据的基本操作,也可以把一些公用的方法或者类迁移到Infrastructrue 2.对于domain层可以声明各个聚合根的操作接口:例:IXXXRepository ...

  8. node.js安装步骤

    首先这是node.js的官网:https://nodejs.org/en/ 截至2017年12月9日,node更新在8.9.3该版本,建议开发人员下载6.0以上版本,8以上不是很稳定!  如果有其他需 ...

  9. mysql中返回当前时间的函数或者常量

    引用:http://blog.sina.com.cn/s/blog_6d39dc6f0100m7eo.html 1.1 获得当前日期+时间(date + time)函数:now() 除了 now() ...

  10. Serializable和Parcelable的简单介绍

    Serializable和Pacelable接口可以完成对象的序列化过程,当我们需要通过Intent和Binder传输数据时就需要使用Parcelable或者Serializable. Seriali ...