【发布时间】:2010-12-09 19:49:44
【问题描述】:
我已经尝试了明显的“SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED”,但是当更新正在进行时(当与某些复杂的更新事务同时运行时,我的简单存储过程仍然会被阻塞)在 PRIMARY KEY 上执行我不想修改)——最终会遇到死锁和锁定超时。
当然,必须有一种方法来保证非阻塞读取......我认为这就是 READ-UNCOMMITTED 的目的。但我错了……这是一个 MySQL 错误吗?有解决办法吗?
我知道 READ-UNCOMMITTED 的所有危险和学术上不健全的属性,但这没关系,对于我的特定应用程序,这里偶尔会出现幻影或缺失行,实际上没什么大不了的,但延迟或错误由读锁引起的问题要严重得多。
数据库中的所有表都是 InnoDB。 服务器版本为 5.0.67。平台是 Linux 32 位。
更新这是一个简化的“hello world”版本的问题描述(我的实际查询过于复杂和丑陋,无法发布):
控制台 1:
mysql> create table t1(a int primary key) engine=innodb; 查询正常,0 行受影响(0.20 秒) mysql> 插入 t1 值 (1),(2),(3); 查询正常,3 行受影响(0.03 秒) 记录:3 重复:0 警告:0 mysql>开始事务; 查询正常,0 行受影响(0.00 秒) mysql> 插入 t1 值 (4); 查询正常,1 行受影响(0.01 秒) mysql> 更新 t1 设置 a=5 其中 a=4; 查询正常,1 行受影响(0.00 秒) 匹配行:1 更改:1 警告:0CONSOLE 2(在单独的窗口中,不要关闭 CONSOLE 1)
mysql> select max(a) from t1; +--------+ |最大(一)| +--------+ | 3 | +--------+ 一组中的 1 行(0.00 秒) mysql> set @test = (select max(a) from t1); ERROR 1205 (HY000): 超过锁定等待超时;尝试重启事务
【问题讨论】:
-
您有索引来“覆盖”您的查询工作负载吗?
-
Mitch:作为我调查重点的简单查询的索引足以涵盖 WHERE 条件,但不能涵盖所有返回的列。
-
您的读取在这里是非阻塞的,它是阻塞的插入和更新。如果没有主从设置或类似设置,或者按照 James 的建议修改长期运行的 UPDATE,则无法解决此问题。
-
本:你的假设不正确。我已经通过“显示引擎 innodb 状态”深入了解了这一点,而且绝对是这样,我的读取不是非阻塞的(即读取实际上是被阻塞的)。我们所读到的关于 InnoDB 的所有内容都是错误的 :(