iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL中怎么实现死锁
  • 666
分享到

MySQL中怎么实现死锁

2024-04-02 19:04:59 666人浏览 泡泡鱼
摘要

这篇文章将为大家详细讲解有关Mysql中怎么实现死锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1.了解锁等待与死锁出现锁等待或死锁的原因是访问数据库需要

这篇文章将为大家详细讲解有关Mysql中怎么实现死,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

1.了解锁等待与死锁

出现锁等待或死锁的原因是访问数据库需要加锁,那你可能要问了,为啥要加锁呢?原因是为了确保并发更新场景下的数据正确性,保证数据库事务的隔离性。

锁等待也可称为事务等待,后执行的事务等待前面处理的事务释放锁,但是等待时间超过了 mysql 的锁等待时间,就会引发这个异常。等待超时后的报错为“Lock  wait timeout exceeded...”。

死锁发生的原因是两个事务互相等待对方释放相同资源的锁,从而造成的死循环。产生死锁后会立即报错“Deadlock found when trying to  get lock...”。

2.现象复现及处理

下面我们以 Mysql 5.7.23 版本为例(隔离级别是 RR ),来复现下上述两种异常现象。

mysql> show create table test_tb\G *************************** 1. row ***************************        Table: test_tb Create Table: CREATE TABLE `test_tb` (   `id` int(11) NOT NULL AUTO_INCREMENT,   `col1` varchar(50) NOT NULL DEFAULT '',   `col2` int(11) NOT NULL DEFAULT '1',   `col3` varchar(20) NOT NULL DEFAULT '',   PRIMARY KEY (`id`),   KEY `idx_col1` (`col1`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 1 row in set (0.00 sec)  mysql> select * from test_tb; +----+------+------+------+ | id | col1 | col2 | col3 | +----+------+------+------+ |  1 | fdg  |    1 | abc  | |  2 | a    |    2 | fg   | |  3 | ghrv |    2 | rhdv | +----+------+------+------+ 3 rows in set (0.00 sec)  # 事务一首先执行 mysql> begin; Query OK, 0 rows affected (0.00 sec)  mysql> select * from test_tb where col1 = 'a' for update; +----+------+------+------+ | id | col1 | col2 | col3 | +----+------+------+------+ |  2 | a    |    2 | fg   | +----+------+------+------+ 1 row in set (0.00 sec)  # 事务二然后执行 mysql> begin; Query OK, 0 rows affected (0.01 sec)  mysql> update test_tb set col2 = 1 where col1 = 'a'; ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

出现上种异常的原因是事务二在等待事务一的行锁,但事务一一直没提交,等待超时而报错。InnoDB 行锁等待超时时间由  innodb_lock_wait_timeout 参数控制,此参数默认值为 50 ,单位为秒,即默认情况下,事务二会等待 50s  ,若仍拿不到行锁则会报等待超时异常并回滚此条语句。

对于 5.7 版本,出现锁等待时,我们可以查看 infORMation_schema 中的几张系统表来查询事务状态。

  • innodb_trx 当前运行的所有事务。

  • innodb_locks 当前出现的锁。

  • innodb_lock_waits 锁等待的对应关系

# 锁等待发生时 查看innodb_trx表可以看到所有事务  # trx_state值为LOCK WAIT 则代表该事务处于等待状态  mysql> select * from information_schema.innodb_trx\G *************************** 1. row ***************************                     trx_id: 38511                  trx_state: LOCK WAIT                trx_started: 2021-03-24 17:20:43      trx_requested_lock_id: 38511:156:4:2           trx_wait_started: 2021-03-24 17:20:43                 trx_weight: 2        trx_mysql_thread_id: 1668447                  trx_query: update test_tb set col2 = 1 where col1 = 'a'        trx_operation_state: starting index read          trx_tables_in_use: 1          trx_tables_locked: 1           trx_lock_structs: 2      trx_lock_memory_bytes: 1136            trx_rows_locked: 1          trx_rows_modified: 0    trx_concurrency_tickets: 0        trx_isolation_level: REPEATABLE READ          trx_unique_checks: 1     trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL  trx_adaptive_hash_latched: 0  trx_adaptive_hash_timeout: 0           trx_is_read_only: 0 trx_autocommit_non_locking: 0 *************************** 2. row ***************************                     trx_id: 38510                  trx_state: RUNNING                trx_started: 2021-03-24 17:18:54      trx_requested_lock_id: NULL           trx_wait_started: NULL                 trx_weight: 4        trx_mysql_thread_id: 1667530                  trx_query: NULL        trx_operation_state: NULL          trx_tables_in_use: 0          trx_tables_locked: 1           trx_lock_structs: 4      trx_lock_memory_bytes: 1136            trx_rows_locked: 3          trx_rows_modified: 0    trx_concurrency_tickets: 0        trx_isolation_level: REPEATABLE READ          trx_unique_checks: 1     trx_foreign_key_checks: 1 trx_last_foreign_key_error: NULL  trx_adaptive_hash_latched: 0  trx_adaptive_hash_timeout: 0           trx_is_read_only: 0 trx_autocommit_non_locking: 0 2 rows in set (0.00 sec)  # innodb_trx 字段值含义 trx_id:事务ID。 trx_state:事务状态,有以下几种状态:RUNNING、LOCK WAIT、ROLLING BACK 和 COMMITTING。 trx_started:事务开始时间。 trx_requested_lock_id:事务当前正在等待锁的标识,可以和 INNODB_LOCKS 表 JOIN 以得到更多详细信息。 trx_wait_started:事务开始等待的时间。 trx_weight:事务的权重。 trx_mysql_thread_id:事务线程 ID,可以和 PROCESSLIST 表 JOIN。 trx_query:事务正在执行的 SQL 语句。 trx_operation_state:事务当前操作状态。 trx_tables_in_use:当前事务执行的 SQL 中使用的表的个数。 trx_tables_locked:当前执行 SQL 的行锁数量。 trx_lock_structs:事务保留的锁数量。 trx_isolation_level:当前事务的隔离级别。  # sys.innodb_lock_waits 视图也可看到事务等待状况,且给出了杀链接的SQL mysql> select * from sys.innodb_lock_waits\G *************************** 1. row ***************************                 wait_started: 2021-03-24 17:20:43                     wait_age: 00:00:22                wait_age_secs: 22                 locked_table: `testdb`.`test_tb`                 locked_index: idx_col1                  locked_type: RECORD               waiting_trx_id: 38511          waiting_trx_started: 2021-03-24 17:20:43              waiting_trx_age: 00:00:22      waiting_trx_rows_locked: 1    waiting_trx_rows_modified: 0                  waiting_pid: 1668447                waiting_query: update test_tb set col2 = 1 where col1 = 'a'              waiting_lock_id: 38511:156:4:2            waiting_lock_mode: X              blocking_trx_id: 38510                 blocking_pid: 1667530               blocking_query: NULL             blocking_lock_id: 38510:156:4:2           blocking_lock_mode: X         blocking_trx_started: 2021-03-24 17:18:54             blocking_trx_age: 00:02:11     blocking_trx_rows_locked: 3   blocking_trx_rows_modified: 0      sql_kill_blocking_query: KILL QUERY 1667530 sql_kill_blocking_connection: KILL 1667530

sys.innodb_lock_waits 视图整合了事务等待状况,同时给出杀掉堵塞源端的 kill 语句。不过是否要杀掉链接还是需要综合考虑的。

死锁与锁等待稍有不同,我们同样也来简单复现下死锁现象。

# 开启两个事务 # 事务一执行 mysql> update test_tb set col2 = 1 where col1 = 'a'; Query OK, 1 row affected (0.00 sec) Rows matched: 1  Changed: 1  Warnings: 0  # 事务二执行 mysql> update test_tb set col2 = 1 where id = 3; Query OK, 1 row affected (0.00 sec) Rows matched: 1  Changed: 1  Warnings: 0  # 回到事务一执行 回车后 此条语句处于锁等待状态 mysql> update test_tb set col1 = 'abcd' where id = 3; Query OK, 1 row affected (5.71 sec) Rows matched: 1  Changed: 1  Warnings: 0  # 回到事务二再执行 此时二者相互等待发生死锁 mysql> update test_tb set col3 = 'gddx' where col1 = 'a'; ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

发生死锁后会选择一个事务进行回滚,想查明死锁原因,可以执行 show engine innodb status  来查看死锁日志,根据死锁日志,结合业务逻辑来进一步定位死锁原因。

在实际应用中,我们要尽量避免死锁现象的发生,可以从以下几个方面入手:

  • 事务尽可能小,不要讲复杂逻辑放进一个事务里。

  • 涉及多行记录时,约定不同事务以相同顺序访问。

  • 业务中要及时提交或者回滚事务,可减少死锁产生的概率。

  • 表要有合适的索引

  • 可尝试将隔离级别改为 RC 。

关于MySQL中怎么实现死锁就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

您可能感兴趣的文档:

--结束END--

本文标题: MySQL中怎么实现死锁

本文链接: https://www.lsjlt.com/news/58012.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL中怎么实现死锁
    这篇文章将为大家详细讲解有关MySQL中怎么实现死锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1.了解锁等待与死锁出现锁等待或死锁的原因是访问数据库需要...
    99+
    2024-04-02
  • MySQL中怎么实现死锁与日志
    本篇文章给大家分享的是有关MySQL中怎么实现死锁与日志,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、Case1:部分数据更新失败某天渠道...
    99+
    2024-04-02
  • SQLServer中怎么实现死锁
    这篇文章将为大家详细讲解有关SQLServer中怎么实现死锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。  SQLServer怎么死锁  压力测试的业务场...
    99+
    2024-04-02
  • Mysql锁机制中行锁、表锁、死锁如何实现
    这篇文章主要介绍了Mysql锁机制中行锁、表锁、死锁如何实现,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、Mysql锁是什么?锁有哪些类别?锁定义:  ...
    99+
    2023-06-29
  • MySQL中怎么排查死锁
    这篇文章将为大家详细讲解有关MySQL中怎么排查死锁,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。死锁起因先介绍一下数据库和表情况,因为涉及到公司内部真是的...
    99+
    2024-04-02
  • mysql中怎么解除死锁
    这篇文章主要介绍了mysql中怎么解除死锁,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、第一种:查询是否锁表show OPEN TABLES ...
    99+
    2023-06-15
  • Visual Studio怎么实现死锁
    这篇文章主要介绍“Visual Studio怎么实现死锁”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Visual Studio怎么实现死锁”文章能帮助大家解决问题。首先要承认这个标题有那么一丁点标...
    99+
    2023-06-17
  • Mysql锁机制之行锁、表锁、死锁的实现
    目录一、Mysql锁是什么?锁有哪些类别?二、行锁和表锁的区别三、InnoDB死锁概念和死锁案例死锁场景一之select for update:死锁场景二之两个update...
    99+
    2024-04-02
  • mysql怎么防止死锁
    这篇文章主要介绍“mysql怎么防止死锁”,在日常操作中,相信很多人在mysql怎么防止死锁问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”mysql怎么防止死锁”的疑惑有所帮...
    99+
    2024-04-02
  • MySQL中怎么阅读死锁日志
    MySQL中怎么阅读死锁日志,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。MySQL 5.6 事务隔离级别为RRCREATE TABLE `t...
    99+
    2024-04-02
  • Golang怎么实现死锁?怎么避免?
    Golang 是一门高效、强类型、静态类型的编程语言,由 Google 开发,目的是为了解决一些类似于死锁等问题。虽然 Golang 实现死锁十分困难,但是在这篇文章中,我们将要探讨如何使用 Golang 实现死锁。什么是死锁?死锁指的是多...
    99+
    2023-05-14
  • Java中死锁与活锁的具体实现
    目录活锁与死锁活锁死锁死锁的四个必要条件互斥条件请求和保持条件不剥夺条件环路等待条件死锁示例死锁排查总结一下如何避免死锁预防死锁设置加锁顺序活锁示例解决活锁活锁与死锁 活锁 活锁同样...
    99+
    2024-04-02
  • mysql怎么查询死锁的表
    要查询死锁的表,可以使用以下步骤: 执行以下命令,查看当前的死锁情况: SHOW ENGINE INNODB STATUS; ...
    99+
    2024-04-09
    mysql
  • MySQL是怎么处理死锁的
    小编给大家分享一下MySQL是怎么处理死锁的,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、什么是死锁官方定义如下:两个事务都持有对方需要的锁,并且在等待对方释放,并且双方都不会释放自己...
    99+
    2024-04-02
  • mysql怎么查询死锁日志
    要查询MySQL的死锁日志,可以按照以下步骤进行操作: 打开MySQL的配置文件(my.cnf或my.ini),找到并编辑以下配...
    99+
    2024-04-09
    mysql
  • MySQL中怎么实现行级锁
    这篇文章给大家介绍MySQL中怎么实现行级锁,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。  MySQL行级锁怎么实现  mysql>LOCKTABLESreal_tableWR...
    99+
    2024-04-02
  • Mysql中怎么实现 InnoDB行锁
    Mysql中怎么实现 InnoDB行锁,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Mysql InnoDB行锁实现方式&nb...
    99+
    2024-04-02
  • MySQL中怎么实现全局锁和表锁
    今天就跟大家聊聊有关MySQL中怎么实现全局锁和表锁,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1. 全局锁全局锁就是对整个数据库实例加锁。MyS...
    99+
    2024-04-02
  • MySQL中innodb行锁怎么实现
    在MySQL中,InnoDB引擎通过使用锁来实现行级锁。行锁可以通过以下几种方式来实现:1. 自动行锁:InnoDB引擎会根据需要自...
    99+
    2023-10-09
    MySQL
  • MySQL什么情况下会死锁,发生了死锁怎么处理呢?
    🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业...
    99+
    2023-09-22
    mysql 数据库 死锁 innodb 数据库事物 原力计划
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作