MySQL InnoDB如何应付死锁
发表于:2025-11-07 作者:千家信息网编辑
千家信息网最后更新 2025年11月07日,死锁是事务处理型数据库系统的一个经典问题,但是它们并不是很危险的, 除非它们如此地频繁以至于你根本处理不了几个事务。 当因死锁而产生了回滚时,你通常可以在你的应用程序中重新发出一个事务即可。InnoD
千家信息网最后更新 2025年11月07日MySQL InnoDB如何应付死锁死锁是事务处理型数据库系统的一个经典问题,但是它们并不是很危险的, 除非它们如此地频繁以至于你根本处理不了几个事务。 当因死锁而产生了回滚时,你通常可以在你的应用程序中重新发出一个事务即可。
InnoDB 使用自动地行级锁定。你可能恰好在插入或删除单一一条记录时产生死锁。 这是因为这些操作并不是真正"原子(atomic)"级的:他们会自动地在锁定 inserted/deleted 行的索引记录(可能有几个)。
可以通过下面所示的技巧来应付死锁或减少死锁的次数:
在 MySQL >=3.23.52 和 >= 4.0.3 的版本中使用 SHOW INNODB STATUS 来确定引起最后一个死锁的原因。这可以帮助你调整你的应用程序来避免死锁。
总是准备在因死锁而发生错误时重新发出一个事务。死锁并不危险。仅仅只需重试一遍。
经常提交你的事务。小的事务有较少的碰撞可能。
如果使用锁定读取 SELECT ... FOR UPDATE 或 ... LOCK IN SHARE MODE,尽量使用较低的隔离级 READ COMMITTED。
以一个固定秩序(a fixed order)访问你的表和记录。这样事务将形成一个较精细的队列,而避免死锁。
为你的表添加合适的索引。那么你的查询只需要扫描较少的索引,因而设置较少的锁定。使用 EXPLAIN SELECT 来确定 MySQL 为你的查询挑选的适当的索引。
尽量少用锁定:如果可以通过一个 SELECT 在一个较老的数据快照中获得所需数据,就不要再添加子句 FOR UPDATE 或 LOCK IN SHARE MODE 。在这时使用 READ COMMITTED 隔离级是较好的主意,因为在同一个事务中的每个 consistent read 只读取它最先确定的数据快照。
如果仍然没有什么补救效果,使用表级锁定连载你的事务(serialize transactions):LOCK TABLES t1 WRITE, t2 READ, ... ; [do something with tables t1 and t2 here]; UNLOCK TABLES。表级锁定可以使你的事务形成精细的队列。注意 LOCK TABLES 隐含地启动一个事务,就如同命令 BEGIN,UNLOCK TABLES 如同 COMMIT 一样隐含地结束一个事务。
连载事务(serialize transactions)的另一个解决办法就是建立一个仅有一行记录的辅助"信号量(semaphore)" 表。每一个事务在访问其它表之前均更新这个记录。通过这种方式所有的事务将持续执行。注意同时 InnoDB 实时死锁检测算法也在工作着,因为这个持续锁定(serializing lock)是一个行锁定。在 MySQL 中对于表级锁定我们必须采取超时方式。
死锁检测与回滚
InnoDB 会自动检测一个事务的死锁并回滚一个或多个事务来防止死锁。从 4.0.5 版开始,InnoDB 将设法提取小的事务来进行回滚。一个事务的大小由它所插入(insert)、更新(update)和删除(delete)的数据行数决定。 Previous to 4.0.5, InnoDB always rolled back the transaction whose lock request was the last one to build a deadlock, that is, a cycle in the waits-for graph of transactions.
InnoDB 不能检测出由 MySQL 的 LOCK TABLES 语句引起的死锁,或其它的表类型中的锁定所引起的死锁。你不得不通过在 my.cnf 中设置 innodb_lock_wait_timeout 参数来解决这些情形。
当 InnoDB 执行一个事务完整的回滚,这个事务所有所加的锁将被释放。然而,如果只一句的 SQL 语句因结果返回错误而进行回滚的,由这条 SQL 语句所设置的锁定可能会被保持。这是因为 InnoDB r的行锁存储格式无法知道锁定是由哪个 SQL 语句所设置。
InnoDB 使用自动地行级锁定。你可能恰好在插入或删除单一一条记录时产生死锁。 这是因为这些操作并不是真正"原子(atomic)"级的:他们会自动地在锁定 inserted/deleted 行的索引记录(可能有几个)。
可以通过下面所示的技巧来应付死锁或减少死锁的次数:
在 MySQL >=3.23.52 和 >= 4.0.3 的版本中使用 SHOW INNODB STATUS 来确定引起最后一个死锁的原因。这可以帮助你调整你的应用程序来避免死锁。
总是准备在因死锁而发生错误时重新发出一个事务。死锁并不危险。仅仅只需重试一遍。
经常提交你的事务。小的事务有较少的碰撞可能。
如果使用锁定读取 SELECT ... FOR UPDATE 或 ... LOCK IN SHARE MODE,尽量使用较低的隔离级 READ COMMITTED。
以一个固定秩序(a fixed order)访问你的表和记录。这样事务将形成一个较精细的队列,而避免死锁。
为你的表添加合适的索引。那么你的查询只需要扫描较少的索引,因而设置较少的锁定。使用 EXPLAIN SELECT 来确定 MySQL 为你的查询挑选的适当的索引。
尽量少用锁定:如果可以通过一个 SELECT 在一个较老的数据快照中获得所需数据,就不要再添加子句 FOR UPDATE 或 LOCK IN SHARE MODE 。在这时使用 READ COMMITTED 隔离级是较好的主意,因为在同一个事务中的每个 consistent read 只读取它最先确定的数据快照。
如果仍然没有什么补救效果,使用表级锁定连载你的事务(serialize transactions):LOCK TABLES t1 WRITE, t2 READ, ... ; [do something with tables t1 and t2 here]; UNLOCK TABLES。表级锁定可以使你的事务形成精细的队列。注意 LOCK TABLES 隐含地启动一个事务,就如同命令 BEGIN,UNLOCK TABLES 如同 COMMIT 一样隐含地结束一个事务。
连载事务(serialize transactions)的另一个解决办法就是建立一个仅有一行记录的辅助"信号量(semaphore)" 表。每一个事务在访问其它表之前均更新这个记录。通过这种方式所有的事务将持续执行。注意同时 InnoDB 实时死锁检测算法也在工作着,因为这个持续锁定(serializing lock)是一个行锁定。在 MySQL 中对于表级锁定我们必须采取超时方式。
死锁检测与回滚
InnoDB 会自动检测一个事务的死锁并回滚一个或多个事务来防止死锁。从 4.0.5 版开始,InnoDB 将设法提取小的事务来进行回滚。一个事务的大小由它所插入(insert)、更新(update)和删除(delete)的数据行数决定。 Previous to 4.0.5, InnoDB always rolled back the transaction whose lock request was the last one to build a deadlock, that is, a cycle in the waits-for graph of transactions.
InnoDB 不能检测出由 MySQL 的 LOCK TABLES 语句引起的死锁,或其它的表类型中的锁定所引起的死锁。你不得不通过在 my.cnf 中设置 innodb_lock_wait_timeout 参数来解决这些情形。
当 InnoDB 执行一个事务完整的回滚,这个事务所有所加的锁将被释放。然而,如果只一句的 SQL 语句因结果返回错误而进行回滚的,由这条 SQL 语句所设置的锁定可能会被保持。这是因为 InnoDB r的行锁存储格式无法知道锁定是由哪个 SQL 语句所设置。
事务
死锁
数据
索引
语句
检测
危险
可以通过
应用程序
快照
方式
程序
这是
错误
队列
处理
应用
更新
查询
连载
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
软件开发工作胜任能力
服务器 流产
数据库三种常见的备份方法
芯片软件开发好就业吗
房地产数据库有哪些网站
服务器组建
天门放心的软件开发团队
SDH有线传输网络技术
三级网络技术培训视频
服务器怎么代理服务器
网络安全可以分为哪些维度
顺义区大型软件开发经历
广西南宁瑞宁软件开发有限公司
数据库的发展趋势
ibm服务器诊断
网络安全小结心得
天门求职软件开发
软件开发项目经理能力维度
登录韩服服务器安全吗
excel数据库查找品名
计算机通信网络技术vlan
兔博士的房产数据库
法学 数据库
龙源新媒体数据库是什么
软件开发人员工作
你没见过的便宜的云服务器
网络安全意见作文200字
网游账号系统数据库
锦里网络技术
山东柏瑞软件开发