pt-osc改表导致数据不一致案例分析
我们平时除了解决自己问题外,有时候也会协助圈内人士,进行一些故障排查,此案例就是帮某公司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改表导致数据不一致案例分析的更多相关文章
- Redis面试题记录--缓存双写情况下导致数据不一致问题
转载自:https://blog.csdn.net/lzhcoder/article/details/79469123 https://blog.csdn.net/u013374645/article ...
- 三年之久的 etcd3 数据不一致 bug 分析
问题背景 诡异的 K8S 滚动更新异常 笔者某天收到同事反馈,测试环境中 K8S 集群进行滚动更新发布时未生效.通过 kube-apiserver 查看发现,对应的 Deployment 版本已经是最 ...
- 演示stop暴力停止线程导致数据不一致的问题,但是有些有趣的发现 (2017-07-03 21:25)
如注释所言 /** * Created by weiwei22 on 17/7/3. * * 这里主要是为了演示stop导致的数据不一致的问题.stop会暴力的结束线程并释放锁,所以有可能在恰好写了一 ...
- [经验分享] MySQL Innodb表导致死锁日志情况分析与归纳【转,纯学习】
在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下: (1)insert into backup_ta ...
- MySQL Innodb表导致死锁日志情况分析与归纳
发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志 案例描述在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时 ...
- ORA-04031错误导致宕机案例分析
今天遇到一起ORACLE数据库宕机案例,下面是对这起数据库宕机案例的原因进行分析.解读.分析过程中顺便记录一下这个案例的前因后果,攒点经验值,培养一下分析.解决问题的能力. 案例环境: 操作系统 ...
- DML:增、删、改表中数据
1. 添加数据 (1) 常规添加 INSERT INTO 表名(列名,列名,列名) VALUES(值,值,值); (2) 简化添加 INSERT INTO 表名 VALUES(值,值,值); 规则: ...
- UPDATE---修改表中数据
UPDATE table_name SET column1=value1,column2=value2,... [WHERE conditions]; 例: UPDATE userinfo SET n ...
- netcore服务程序暴力退出导致的业务数据不一致的一种解决方案(优雅退出)
一: 问题提出 现如今大家写的netcore程序大多部署在linux平台上,而且服务程序里面可能会做各种复杂的操作,涉及到多数据源(mysql,redis,kafka).成功部署成后台 进程之后,你以 ...
随机推荐
- SpringMVC+Jquery实现Ajax
一.什么是Ajax? Ajax:异步的JavaScript和Json(这里XML改为了Json): 作用:用于完成网页局部刷新功能(修改少量数据只用局部刷新,不用再整个网页重新加载): 二.Sprin ...
- C 语言程序员必读的 5 本书
你正通过看书来学习C语言吗?书籍是知识的丰富来源.你可以从书中学到各种知识.书籍可以毫无歧视地向读者传达作者的本意.C语言是由 Dennis Ritchie在1969年到1973年在贝尔实验室研发的. ...
- ACM_Reverse Bits(反转二进制)
Reverse Bits Time Limit: 2000/1000ms (Java/Others) Problem Description: Reverse bits of a given 32 b ...
- web.xml里,classpath使用范围
比如说在web.xml里,配置spring监听. 在标签<param-value>里,classpath指向的配置文件路径应该是在config资源文件夹下的applicationConte ...
- JSP所需要掌握的部分
JSP基本语法 指令 <%@ 指令%> JSP指令是JSP的引擎 主要的两种指令是page和include(taglib) <%@ page import="java.ut ...
- [转]使用ThinkPHP框架快速开发网站(多图)
本文转自:http://blog.csdn.net/ruby97/article/details/7574851 这一周一直忙于做实验室的网站,基本功能算是完成了.比较有收获的是大概了解了ThinkP ...
- 研磨JavaScript系列(一):回归简单
想要理解JavaScript,你得首先放下对象和类的概念,回到数据和代码的本原.编程世界只有数据和代码两种基本元素,而这两种元素又有着纠缠不清的关系.JavaScript就是把数据和代码都简化到最原始 ...
- React Native 环境搭建踩坑
React Native (web Android)环境搭建踩坑(真的是一个艰辛的过程,大概所有坑都被我踩了 官方文档地址 : https://facebook.github.io/react-nat ...
- unity之Rigidbody属性
Rigidbody属性 Mass表示物体的质量,数值类型为float,默认值为1.大部分物体的质量属性接近于0.1才符合日常生活感官感受,超过10 ,则失去了仿真效果. Drag表示平移阻力,其数值类 ...
- 重现apache commons fileupload DOS漏洞
这个漏洞是2014年2月4日被发现的, 因为该组件试用范围非常广, 所以该漏洞的影响也非常巨大.通过特制的包含畸形header的http请求,可以导致使用该组件的应用程序进入无限循环从而耗尽CPU等资 ...