为什么MySQL死锁检测会严重降低TPS

在大量的客户端,更新数据表的同一行时,会造成数据库的吞吐量大幅降低。

很多数据库的前辈和同行分别通过实验和源码的方法,定位到了罪魁祸首----MySQL死锁检测

实验方式:http://blog.csdn.net/zhaiwx1987/article/details/6952285

源码方式:http://www.gpfeng.com/?p=426

请大家尤其注意这段代码

#####

lock_mutex_enter();

ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));

err = lock_rec_lock(TRUE, LOCK_X | LOCK_REC_NOT_GAP,
block, heap_no, index, thr);

MONITOR_INC(MONITOR_NUM_RECLOCK_REQ);

lock_mutex_exit();

#####

可以看出,MySQL在试图获取锁期间,会有lock_mutex_enter 和lock_mutex_exit保护。

  在一般情况下,lock_rec_lock执行速度很快,所以不成问题。

  但是如果有大量锁等待的情况,比如多个客户端试图更新同一行,则这个过程非常缓慢。因此整个innodb层就由并行变成了串行,大幅降低TPS。

解决办法:

  让锁等待尽量少,可以通过在数据库层设置等待队列达到这个效果,而OneSQL内置了这个方案。

测试用例:

update miaosha set mount=mount+1 where id=1;

  测试环境

  MySQL和OneSQL的关键参数配置如下,且均未开启binlog

数据库 innodb_flush_log_at_trx_commit innodb_log_file_size innodb_buffer_pool_size
OneSQL 1 1000M 8G
MySQL 1 1000M 8G

  硬件环境

内存 cpu 磁盘
32g 8c 每个core上有两个超线程
Intel(R) Xeon(R) CPU
 E5620  @ 2.40GHz
2块raid0
7500r

测试结果:

在512个线程情况下,TPS为500/s

我实际测试,同样的环境下使用OneSQL,TPS可以达到15682/s,性能提升达30倍左右。

如有任何疑问,请联系微信onesoft007

时间: 2024-11-08 20:03:04

为什么MySQL死锁检测会严重降低TPS的相关文章

MySQL死锁检测和回滚

最近碰到“TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH, WE WILL ROLL BACK FOLLOWING TRANSACTION”. 重新温习下受益良多,其中死锁的判定规则,其实我们早在5年前解决秒杀场景的第一个版本就已经涉及,并且思路很相似,如果有时间的话,我会补充上一批文章说下如果关闭死锁检测对单行更新能提升多少性能. 下面这一段代码展示的是: “ If the LATEST DETECTED DEADLOCK s

谈谈MySQL死锁之二 死锁检测和处理源码分析

这一篇主要是通过一个实验来进行描述,过程是比较枯燥的. 实验准备 create table test_lock(id int auto_increment primary key ,stock int) engine=innodb; insert into test_lock(id,stock) value(1,50); 这里我把堆栈信息尽可能的简化,25个主要函数的名称和入参 后面为了突出主题,我对事务相关的函数加上这个开头死锁检测函数列表,一共10个函数   死锁检测函数列表A row_se

MySQL 死锁与日志二三事

最近线上 MySQL 接连发生了几起数据异常,都是在凌晨爆发,由于业务场景属于典型的数据仓库型应用,白天压力较小无法复现.甚至有些异常还比较诡异,最后 root cause 分析颇费周折.那实际业务当中咱们如何能快速的定位线上 MySQL 问题,修复异常呢?下文我会根据两个实际 case,分享下相关的经验与方法. 1.Case1:部分数据更新失败 某天渠道同学反馈某报表极个别渠道数据为 0,大部分渠道数据正常.这个数据是由一个统计程序每天凌晨例行更新的,按理来说,要么全部正常,要么全部失败,那会

mysql死锁(锁与事务)

线上某服务时不时报出如下异常(大约一天二十多次):“Deadlock found when trying to get lock;”. Oh, My God! 是死锁问题.尽管报错不多,对性能目前看来也无太大影响,但还是需要解决,保不齐哪天成为性能瓶颈.     为了更系统的分析问题,本文将从死锁检测.索引隔离级别与锁的关系.死锁成因.问题定位这五个方面来展开讨论. 1 死锁是怎么被发现的? 1.1 死锁成因&&检测方法 左图那两辆车造成死锁了吗?不是!右图四辆车造成死锁了吗?是! 我们m

MySQL死锁[转]

案例描述       在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志. 两个sql语句如下:       (1)insert into backup_table select * from source_table      (2)DELETE FROM source_table WHERE Id>5 AND titleWeight<32768 AND joinTime<'$daysago_1week'   

谈谈MySQL死锁 一

数据越来越和我们的生活离不开,数据在生命周期的各个阶段有着不同的痛点和需求以及特殊场景. CURD是数据的四大基本需求:写入,更新,读取,删除. 今天,来谈一谈死锁问题 死锁是高并发下MySQL不可回避的一个问题. 这句话可以引申四个问题: 1.什么是死锁? 2.MySQL什么时候会检测死锁? 3.数据库系统如何处理死锁? 4.有哪些典型的高并发死锁场景? 1.我们先来看看什么是死锁. 在<数据库系统实现>第八章第二节这样定义死锁 并发执行的事务由于竞争资源而到达一个存在死锁的状态:若干事务的

mysql 死锁检查

mysql 死锁检查 今天看了一篇关于死锁检查的blog. Advanced InnoDB Deadlock Troubleshooting – What SHOW INNODB STATUS Doesn’t Tell You, and What Diagnostics You Should be Looking At One common cause for deadlocks when using InnoDB tables is from the existence of foreign

怎么避免mysql死锁

怎么避免mysql死锁 1.以固定的顺序访问表和行.比如两个更新数据的事务,事务A更新数据的顺序为1,2:事务B更新数据的顺序为 2 ,1:.这样更可能会造成死锁. 2.大事务拆小.大事务更倾向于死锁,如果业务允许,将大事务拆小. 3.在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁概率. 4.降低隔离级别.如果业务允许,将隔离级别调低也是比较好的选择,比如将隔离级别从RR调整为RC,可以避免很多因为gap锁造成的死锁. 5.为表添加合理的索引.可以看到如果不走索引将会为表的每一行记

【Todo】Mysql死锁问题解决方式 &amp; 隔离级别等知识

参考了这篇文章:http://www.cnblogs.com/LBSer/p/5183300.html  <mysql死锁问题分析> 写的不错.