MySQL阻塞与死锁的解决

 更新时间:2023年09月07日 14:40:40   作者:柒间  
本文主要介绍了MySQL阻塞与死锁的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

阻塞

因为不同锁之间的兼容性关系,在有些时刻一个事务中的锁需要等待另一个事务中的锁释放它所占用的资源,这就是阻塞。

# 查看等待时间
show variables like 'innodb_lock_wait_timeout';
SET@@innodb_lock_wait_timeout=60;
# 是否在等待超时时对进行中的事务进行回滚操作
show variables like 'innodb_rollback_on_timeout';
#设置等待时间  默认50秒
SET@@innodb_lock_wait_timeout=60;  
#设置是否在等待超时时对进行中的事务进行回滚操作  默认是OFF 代表不回滚
SET@@innodb_rollback_on_timeout=on;

查询:

image-20230814102157758

设置值:

image-20230815165901211

注意:参数 innodb_lock_wait_timeout 参数是动态的,在mysql运行时可进行调整, innodb_rollback_on_timeout 参数是静态的,不可在运行时进行修改,否则会报错。

需要特别注意:在默认情况下InnoDB存储引擎不会回滚超时引发的错误异常。(其实InnoDB存储引擎在大部分情况下都不会对异常进行回滚。)

异常实例演示:

左边为会话A,右边为会话B。初始状态数据库表film中有3条数据,ID,分别为3,5,6;

首先会话A 开启了事务A,并且在Next-Key Lock算法下锁定了小与5包含5的记录。事务B正常插入记录ID:7,当插入ID:4 时就进人阻塞状态了

image-20230815174128914

当事务B达到事务超时间时间时,报错 ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction .

image-20230815174608612

这时事务B在此查询会发现,**ID:7 这条记录依然存在,这是因为事务B虽然抛出了异常,但是既没有进行commit 操作也没有进行 rollback操作。**这是非常危险的,因为此时数据库一致性特性被打破了。因此此时用户必须判断是否需要COMMIT还是ROLLBACK,之后再进行下一步的操作。

image-20230815175103979

一般情况这时事务B需要进行 rollback操作,具体情况具体分析。

image-20230815175620413

死锁

死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象。

当发生死锁的时候,若无外力作用事务都将无法进行下去。

死锁产生的条件:

  • 互斥条件
    临界资源是独占资源,进程应互斥且排他的使用这些资源。
  • 占有和等待条件
    进程在请求资源得不到满足而等待时,不释放已占有资源。
  • 不剥夺条件
    又称不可抢占,已获资源只能由进程自愿释放,不允许被其他进程剥夺。
  • 循环等待条件
    又称环路条件,存在循环等待链,其中,每个进程都在等待链中等待下一个进程所持有的资源,造成这组进程处于永远等待状态。

如何解决死锁问题:

1.超时机制:当两个事务互相等待时,如果等待时间超过设置的某一阈值时,其中一个事务进行回滚,另一个等待的事务就能继续进行。在InnoDB存储引擎中, innodb_lock_wait_timeout 设置超时的时间。

我们知道,一条记录是有很多undo log的或者undo 版本链有很多版本的,如果一个事务操作更新了很多行,这时候如果要进行回滚所占用的时间可能就会很多。

2.使用wai t-for graph (等待图)进行死锁检测,数据库需要保存锁的信息链表和事务等待链表。我们通过锁的信息链表和事务等待链表就可以构造出一张图,如果图中存在回路那就说明出现了死锁。

image-20230815235528149

​ 事务和锁状态图

上图中,transaction wait list 中有四个事务,事务t2对row1加了x锁,事务t1对row1加了s锁,并且事务t1需要等待事务t2中的row1资源,因此wait-for graph图中有一条边冲节点t1指向t2。 row2记录的情况同理。

image-20230816001239711

​ wait-for graph

观察发现,t1 和 t2 存在回路,因此存在死锁。

阅读到这里,我们需要意识到因为MySQL数据库是一个并发的程序,所以才存在死锁。因为如果程序是串行的,那么也就不会发生死锁了。

死锁示例:

有两个事务A,B: 事务A当前读查询记录ID:5 ,事务B当前读查询ID:6。

image-20230816002539299

接着交换一下:

事务A当前读查询记录ID:6 ,事务B当前读查询ID:5

image-20230816003007483

会发现两个事务中的事务B立马就报错: ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

通常来说InnoDB存储引擎选择回滚undo量最小的事务。

到此这篇关于MySQL阻塞与死锁的解决的文章就介绍到这了,更多相关MySQL阻塞与死锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySql使用存储过程进行单表数据迁移的实现

    MySql使用存储过程进行单表数据迁移的实现

    近期在进行业务解耦,对冗余在一起切又属于不同业务的代码进行分离,同时也将数据库进行分离存储,那么这时候就涉及到多个表的数据要进行迁移,本文就来介绍一下MySql使用存储过程进行单表数据迁移,感兴趣的可以了解一下
    2023-11-11
  • mysql 5.7.11 winx64初始密码修改

    mysql 5.7.11 winx64初始密码修改

    这篇文章主要为大家详细介绍了mysql 5.7.11 winx64初始密码修改的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • 解决修改mysql的data_dir所引发的错误问题

    解决修改mysql的data_dir所引发的错误问题

    本文给大家分享解决修改mysql的data_dir所引发的错误问题,非常不错具有参考借鉴价值,需要的朋友参考下吧
    2017-04-04
  • 使用sysbench来测试MySQL性能的详细教程

    使用sysbench来测试MySQL性能的详细教程

    这篇文章主要介绍了使用sysbench来测试MySQL性能的详细教程,包括介绍了从sysbench的编译安装到初始化测试库环境等一系列操作,需要的朋友可以参考下
    2015-05-05
  • 详细解读MySQL的触发器trigger

    详细解读MySQL的触发器trigger

    触发器是由事件来触发某个操作,这些事件包括INSERT、UPDATE和DELETE语句。如果定义了触发程序,当数据库执行这些语句的时候就会激发触发器执行相应的操作,需要的朋友可以参考下
    2023-05-05
  • 项目从MYSQL迁移至MARIADB教程

    项目从MYSQL迁移至MARIADB教程

    本文给大家分享的是将项目从MySQL迁移至MariaDB的详细步骤,非常的实用,有需要的小伙伴可以参考下
    2017-07-07
  • mysql 计算函数详情

    mysql 计算函数详情

    这篇文章主要介绍了mysql 计算函数,函数没有SQL的可移植性强 能运行在多个系统上的代码称为可移植的(portable)。相对来说,多数SQL语句是可移植的,在SQL实现之间有差异时,这些差异通常不那么难处理,下面来看看文章的具体内容吧
    2021-10-10
  • MySQL 5.7安装好后打开命令行窗口闪退的解决方法

    MySQL 5.7安装好后打开命令行窗口闪退的解决方法

    这篇文章主要给大家介绍了关于MySQL 5.7安装好后打开命令行窗口闪退的解决方法,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起看看吧
    2018-12-12
  • 区分MySQL中的空值(null)和空字符('''')

    区分MySQL中的空值(null)和空字符('''')

    这篇文章主要介绍了如何区分MySQL中的空值(null)和空字符(''),帮助大家更好的理解和使用MySQL数据库,感兴趣的朋友可以了解下
    2020-09-09
  • MySQL的备份工具mysqldump的基础使用命令总结

    MySQL的备份工具mysqldump的基础使用命令总结

    这篇文章主要介绍了MySQL的备份工具mysqldump的基础使用命令总结,除了基本的导入导出,还介绍了其他一些命令参数的用法,需要的朋友可以参考下
    2015-12-12

最新评论