首页 > 数据库 >mysql分区表导致的死锁

mysql分区表导致的死锁

时间:2023-07-23 17:26:50浏览次数:45  
标签:语句 java mdl 写锁 分区 死锁 分区表 mysql

死锁异常:

org.springfreamwork.dao.DeadlockLoserDataAccessException:......

Cause:java.sql.BatchUpdateException:Deadlock found when trying to get lock;try restarting transaction at.....

1、java代码如下

@Transactional

public void handle(){

selectDao.select1(...);

updateDao.insert(...);

}

2、和java代码(碰巧)同时运行的job中的sql代码如下:

alter table add partition .....(添加或者删除分区)

3、被操作的表是一个分区表

4、java代码在一个线程中,job在另外一个线程中

 

发生死锁的原因:

1、java中发起的sql(dao的select方法和insert方法中的sql语句)中的where语句没有分区键,所以就锁定了全部分区。

注:dml sql语句执行前是一定要申请mdl读锁的(mdl表示meta data lock)。目的是防止在dml语句执行期间有其它ddl语句的执行(ddl语句执行前要申请mdl写锁)。而mdl读锁是可以共享的(mdl读和mdl读之间共享),但是和mdl写锁是互斥的。

2、job中的sql因为是alter table的语句(ddl语句),所以要申请mdl写锁(mdl写和mdl写或者mdl写和mdl读之间是互斥的)。

注:ddl sql语句(包括alter table)执行前是一定要申请mdl写锁的。目的是防止在ddl期间其它dml语句执行。

3、如果mdl写锁被block后需要等待持有mdl读锁的事务结束后才可以获取到写锁,而不是事务中的某个sql结束后就能够获取到写锁

4、mdl读、写锁是公平锁。事务中的第一条dml语句先持有了mdl读锁、job发起了mdl写锁申请、同一个事务中的第二条dml语句再发起mdl读锁申请的时候就需要排队等待mdl写锁的释放。

 

时间线 java事务中的代码 java事务中的锁 job代码 job代码中的锁
T1 select 持有mdl读锁    
T2     alter table

想要获取mdl写锁;

等待事务的mdl读锁释放后才可以获取到,所以block住

T3 insert

等待job的mdl写锁释放后获取mdl读锁;

因为job的mdl写锁block住了,所以事务无法提交

   

 

 

 

 

 

 

 

分析:T2时刻在等待整个事务的释放以便获取到mdl写锁,T3时刻等待T2时刻申请的mdl写锁释放掉。即,T2等T3释放资源、而T3也在等T2释放资源,于是死锁。

 

解决办法:把java代码方法上的事务删除掉,使得select语句结束后持有的mdl读锁就立刻释放掉。

思考:

1、如果java方法上的事务必须使用,那么在方法中的sql语句中的where语句上使用分区键是否可以解决问题?

因为mysql的分区表是innodb引擎层的概念,在server层仍然认为是一张表,也只有一个mdl锁(所有分区共用一个mdl锁);

2、如果java事务必须存在(比如事务中有两个insert语句),那么这个死锁的发生是不可避免的?那么最终如何解决?

死锁是不可避免的。只能尽量使用短事务。可以在ddl语句上使用timeout,具体而言:

 

对于分区表的一些知识补充:

1、所谓分区是对innodb存储层而言的。在上层(比如server层或者应用层)看来这就是一张表。对于mysql分区表而言,是由server层来决定使用哪个分区,而对于手工分表(比如sharding jdbc)而言是由应用层代码决定使用哪个分区。而从innodb角度看来,多个分区到底是由server层还是由代码来决定的,这两种方式并无区别。

2、在server层看来,分区表就是一张表,比如,一张表的多个分区共用一个mdl锁。

3、mysql在第一次访问分区表的时候必须要访问所有分区,因此性能会有损失(相对于真正的单表而言)

4、在innodb层看来,分区表就是多张表,因此mdl锁之后的执行过程(比如dml或者ddl)会根据分区表规则只访问必要的分区,这相对于单表而言又有了一定性能优势(如果是等值分区键那么性能优势明显,如果是范围那么可能没那么明显)。

5、使用分区表的场景:业务代码更简介,因为对于业务代码而言这就是一张表;删除历史记录更容易,因为可以直接alter table drop partition,效果和drop 单表类似。

6、对业务代码而言,到底使用分区表还是使用分库分表中间件,这个要看中间件的成熟度。

7、分区表如果使用了自增主键,mysql要求主键中必须包含分区字段(唯一索引也必须包含分区字段),这对于业务编码而言也是有一定复杂性的。

 

标签:语句,java,mdl,写锁,分区,死锁,分区表,mysql
From: https://www.cnblogs.com/NorthPoplar/p/17574685.html

相关文章

  • MySql —— Buffer Pool
    有了缓冲池后:当读取数据时,如果数据存在于BufferPool中,客户端就会直接读取BufferPool中的数据,否则再去磁盘中读取。当修改数据时,首先是修改BufferPool中数据所在的页,然后将其页设置为脏页,最后由后台线程将脏页写入到磁盘。 BufferPool有多大?BufferPool是在M......
  • 如何配置Apache24+PHP8+Mysql8包括安装
    一、PHP版本的选择与安装配置PHP官方PHP下载页面选择自己想要的版本点击Zip链接即可下载,x64是操做系统的位数,ThreadSafe是线程安全版本(多线程版Apache服务器使用),NoneThreadSafe是非线程安全版(单线程版IIS服务器使用)然后解压出来后把Apache24根目录的php.ini-developm......
  • MySQL - 2
    Smiling&Weeping----我用什么才能留住你?我给你瘦弱的街道、绝望的日落、荒郊的月亮。我给你一个久久望着孤月的人的悲伤。......
  • Mysql手贱修改了User表下的配置,导致本地连接不上去了,或者忘记密码
    ①停止MySQL服务查看mysql服务状态:systemctlstatusmysqld停止mysql服务:systemctlstopmysqld②特殊命令启动mysql服务mysqld--skip-grant-tables& 该命令可以绕过user表,免密登录进入mysql③登录mysql服务器现在直接登录mysql,不用输入密码④修改user表的配置,或者创建......
  • MYSQL
    Smiling&Weeping----或许换个时间,我们真的很合适1.1初识数据库数据库是将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合。该数据集合称为数据库(Database,DB)。用来管理数据库的计算机系统称为数据库管理系统(DatabaseManagemen......
  • MySQL之存储过程(循环)
    MySQL之存储过程变量@@是系统变量@是用户自定义的变量系统变量系统变量是MySQL服务器提供,不是用户定义的,属于服务器层面。分为全局变量(GLOBAL)、会话变量(SESSION)。查看系统变量模板 SHOW[SESSION|GLOBAL]VARIABLES;--查看所有系统变量 SHOW[S......
  • go语言mysql驱动
    连接数据库是典型的CS编程,服务器端被动等待客户端建立TCP连接,并在此连接上进行特定的应用层协议。但一般用户并不需要了解这些细节,这些都被打包到了驱动库当中,只需要简单的调用打开就可以指定协议连接到指定的数据库。数据库的种类和产品太多,协议太多,Go官方很难提供针对不同数据......
  • mysql auto_increment怎么删除
    MySQL中的auto_increment如何删除在MySQL中,auto_increment是一个非常有用的功能,它允许我们在插入数据时自动为表的主键字段生成唯一的递增值。然而,有时候我们可能需要删除表中的某些数据行,这就会导致auto_increment值出现断层。本文将介绍如何在MySQL中删除数据行时保持auto_incre......
  • mysql rpm包选择
    MySQLRPM包选择MySQL是一种流行的关系型数据库管理系统,被广泛用于开发和生产环境中。在Linux系统上安装MySQL,我们可以选择使用RPM包进行安装。RPM(RedHatPackageManager)是一种软件包管理系统,用于在RedHat系列的Linux发行版上进行软件安装、升级和卸载。本文将介绍如何选择适......
  • mysql arm dockerfile
    MySQLonARMwithDockerfileIntroductionWiththeincreasingpopularityofARM-baseddevices,itisbecomingmorecommontorunapplicationsandservicesonARMarchitecture.OnesuchapplicationisMySQL,apowerfulandwidelyusedrelationaldatabasem......