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).成功部署成后台 进程之后,你以 ...
随机推荐
- C#使用Parallel处理数据同步写入Datatable并使用BulkInsert批量导入数据库
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL). 业务流程:选择照片文件夹,分别访问照片-->调用DLL接口传递照片路径-->接收处理返回值-->写入数据 ...
- 【POJ1845】Sumdiv(数论/约数和定理/等比数列二分求和)
题目: POJ1845 分析: 首先用线性筛把\(A\)分解质因数,得到: \[A=p_1^{a_1}*p_2^{a_2}...*p_n^{a_n} (p_i是质数且a_i>0) \] 则显然\ ...
- Android Framework 学习
1. 之前的研究太偏向应用层功能实现了,很多原理不了解没有深究,现在研究framework面存一些资料待有空查看. 2.Android系统的层次如下: 3.项目目录简单分析如下: 4.telphony ...
- Ubuntu 系统的常用快捷键
Ubuntu操作基本快捷键 ibus-setup :设置系统输入法 scp filename username@serverIp:/home/xxx/xxx/filename 回车输入该usern ...
- bootstrap图标乱码问题-解决方案
楼主在使用bootstrap时,出现了图标乱码问题,经过多次查找,才解决了问题(最后发现真的是很好解决的问题(^^)) 如果出现乱码 请直接在自己写的CSS中重新引入一下font文件中的字体就好了 @ ...
- JS——tab函数封装
1.为li标签添加index属性,这个属性正好就是span标签数组的index值 2.函数封装适合页面有多个tab切换,需要注意的在获取的li标签和span标签对象时,必须将对应div对象作为参数传入 ...
- java 操作clob
之前在学校的时候做的都是练习,小儿科,遇到的情况完全都在自己的设想范围内.最近老是遇到字段溢出的情况,但是varchar2好像最长也只有4000个字符.所以不得不另辟蹊径,就找上了clob字段. pa ...
- Caffe:导入caffePython-PyQt failed
在另一台电脑上使用caffe python版本,显示 Backend Qt5Agg is interactive backend. Turning interactive mode on. ...
- Git与SVN版本控制系统
关于版本控制 什么是版本控制?版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统.在本书所展示的例子中,我们仅对保存着软件源代码的文本文件作版本控制管理,但实际上,你可以对任 ...
- ipc (进程间通信
进程间通信(IPC,Inter-Process Communication),指至少两个进程或线程间传送数据或信号的一些技术或方法.进程是计算机系统分配资源的最小单位(严格说来是线程).每个进程都有自 ...