- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试调查我的应用程序中的死锁问题。我的 table 看起来像这样。
CREATE TABLE `requests` (
`req_id` bigint(20) NOT NULL auto_increment,
`status` varchar(255) default NULL,
`process_id` varchar(200) default NULL,
PRIMARY KEY (`req_id`),
KEY `status_idx` USING BTREE (`status`),
KEY `pk_idx_requests` USING BTREE (`req_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8
多个客户端在两个单独的事务中按顺序发出以下查询。
更新请求设置 process_id='"+ hostName + "' where status='Received' and process_id is null order by req_id asc limit 100"
select * from requests where process_id='"+ hostName + "' where status='Received';
更新请求设置 status='Processing' where req_id='xyz'
第三个查询中的 Req_id 是从第二个查询中检索到的请求 ID 列表。
但有时在客户端,我们会看到以下异常。
Deadlock found when trying to get lock; try restarting transaction
org.hibernate.exception.LockAcquisitionException: could not execute native bulk manipulation query
以上查询是否会导致死锁,如果是,我们如何解决?还有办法在本地重现这个问题吗?
这是'show innodb status'的输出
LATEST DETECTED DEADLOCK
------------------------
120507 6:03:21
*** (1) TRANSACTION:
TRANSACTION 115627, ACTIVE 1 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1248, 25 row lock(s)
MySQL thread id 432399, OS thread handle 0x419e4940, query id 4111695 * * * Searching rows for update
update requests set process_id='**' where status='Received' and process_id is null order by req_id asc limit 100
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 4 page no 3797 n bits 136 index `PRIMARY` of table `db`.`requests` trx id 115627 lock_mode X locks rec but not gap waiting
Record lock, heap no 67 PHYSICAL RECORD: n_fields 27; compact format; info bits 0
*** (2) TRANSACTION:
TRANSACTION 115626, ACTIVE 1 sec updating or deleting
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 432403, OS thread handle 0x41c19940, query id 4111694 * * * Updating
update requests set status='Processing', process_id='**' where req_id=3026296
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 4 page no 3797 n bits 136 index `PRIMARY` of table `db`.`requests` trx id 115626 lock_mode X locks rec but not gap
Record lock, heap no 67 PHYSICAL RECORD: n_fields 27; compact format; info bits 0
最佳答案
一些背景
MySQL 在它第一次访问记录时在 UPDATE 语句上取得写锁定。它不会将锁从读提升为写。它locks based on the current index .
在您的 UPDATE 语句中,MySQL 很可能使用状态列上的索引,因此 MySQL 锁定状态 = 'Received' 的每条记录。
请注意,任何时候您锁定多个唯一记录(使用唯一索引,例如主键)时,您就是在锁定一个间隙(或范围)。
针对单个记录的更新仍然需要下一个键锁,这意味着它会锁定所选记录和索引中的下一个记录。
同一索引上的两个 UPDATES(都具有 next-key)锁不会发生冲突(它们将始终以相同的顺序被锁定)。但是,由于您的范围锁是针对二级索引的,因此它可能会死锁。
这是正在发生的场景:
假设您有两条 req_id 为 1 和 2 的记录。
您的第一个事务针对状态索引进行更新,需要同时锁定记录 1 和记录 2,但不能保证与主键的顺序相同,因此它锁定了记录 2,并且即将锁定记录 1。
您的第二个事务锁定在 req_id 索引上,需要更新记录 1。它立即锁定记录 1,但它还需要对记录 2 执行下一键锁定。
这两个交易现在陷入僵局。事务1需要锁定记录1,事务2需要锁定记录2。
解决方案
为避免在您的情况下出现死锁,您可以使用 LOCK TABLES
显式锁定整个表,或者在失败时重试事务。 MySQL 将检测到死锁,并且您的一个事务将被回滚。
MySQL 确实提供了一些指令给 help you cope with deadlocks .
您似乎还应该删除冗余键 pk_idx_requests,因为您的主键已经包含该列。
关于java - 在 MySQL InnoDB 中获取以下查询的锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10488223/
我已经在我的 windows7 机器上安装了 bugzilla4.2.5。当我运行 bugzilla 的 checksetup.pl 脚本时,它显示 Use of uninitialized valu
我正在使用 MySQL 5.1.56 我有一个包含大约 70 个表的数据库,我有一个特定损坏的表的问题,例如表_X 当我尝试访问表时mysql> 从 Table_x 中选择 *;ERROR 1105
我最近尝试将 MySQL 5.1 服务器升级到 5.7。当服务器无法启动时,我发现您必须先导出数据,然后再进行大量升级(二进制文件不再可用),所以我回滚到 5.1 进行导出。 问题是,回到 5.1,I
我正处于项目的开始阶段,到目前为止我一直在使用默认的 MySQL 数据库。 对了,默认的数据库有名字吗? 我的问题是如何在不删除当前表和创建新表的情况下将现有表更改为 utf-8 和 InnoDB。是
我最近尝试将 innodb 缓冲池大小增加到 8GB,但在我的 innodb 状态下,池大小看起来像之前配置的值(在我的例子中是 500MB)。 ---------------------- BUFF
我是一家网络酒店的幸运老板,店主会在不知情的情况下更改设置。当这么说时,我的数据库中有一些表正在使用 InnoDB 引擎运行。但是晚上主机禁用了 InnoDB,所以我无法使用 ALTER 命令将其转换
我刚刚将数据库从 MyISAM 引擎迁移到 InnoDB。我使用 mysqldump 备份我的 MyISAM 数据库,但是当我查看 MySQL docs ,对于 InnoDB 表,我还需要保存二进制文
环境: Windows 7(XAMPP 最新版) Apache 2.4.4PHP 5.5MySQL 5.6.11 我正在尝试从 MySQL 5.1 备份数据库并将其导入 MySQL 5.6。 在 My
我正在创建的应用程序主要使用选择,但也有一些是插入、更新等。我想知道在这些情况下哪种性能最好。 其次,当我在 innodb 中有两个相关的表时,如果它与另一个表中的行相关,我该如何删除它而不吐出错误?
我的意思是页面: https://dev.mysql.com/doc/internals/en/innodb-page-structure.html 这些 16KB 的 MySQL 页面会在内存或磁盘
以下是我使用 mysqldump 备份数据库的开关: /usr/bin/mysqldump -u **** --password=**** --single-transaction --databas
我阅读了本网站上的大部分 InnoDB 示例,但我对 InnoDB 的行为一无所知。 据我所知 START TRANSACTION; 声明这是一个事务连接。没关系到这里。现在我有 3 个表: 带有 I
我有一个包含混合表(MyISAM、InnoDB)的 MySQL 数据库。 如何通过 Linux 命令行使用 mysqldump 创建数据库的完整备份,我应该使用什么选项? 最佳答案 在下面使用- 所有
我有一张桌子:。我用Python在这个表中插入了大约400k行。以下是INSERT语句:。我在两个表tab1.col1和tab2.col2上都有一个索引。但是插入大约需要5分钟/1000行的时间。我从
我正在尝试使用 WAMP 在本地服务器上安装 Magento。 InnoDB 被设置为默认引擎,但它仍然向我显示消息: Database server does not support InnoDB
我最近将所有表从 MyISAM 移到了 InnoDB,因为我想摆脱大表上的表锁定。 在以下表上运行 UPDATE 或 INSERT 查询花费的时间比预期的要多很多。 (约 5 分钟) 我如何优化 in
我正在运行带有 XAMPP 的 Windows 10 和在本地主机上安装的几十个 Drupal 站点。几个月来一切都运行良好。 今天早上,我从两天前的还原点执行了 Windows 还原,以删除不需要的
Socialengine 4.8.6 - 启动时显示“白屏”,只能通过浏览器访问 sesystem.com/phpmyadmin 和 sesystem.com/install。 问题开始:我需要一个包
由于 InnoDB 在 B+ 树中组织其数据。树的高度影响 IO 次数,这可能是 DB 变慢的主要原因之一。 所以我的问题是如何断言或计算B+树的高度(例如根据可以通过行大小、页面大小和行号计算的页数
我尝试使用 mysqldump 从系统 A 使用 innodb 默认存储引擎将大约 40gb 的数据库 db1 转储到 sql 文件中,并尝试在另一个系统 B 上恢复它。两者都有默认存储引擎 inno
我是一名优秀的程序员,十分优秀!