我们从 Microsoft ADO.NET 连接器访问 MySQL。
有时我们会在 innodb 状态中看到以下死锁,并且无法确定问题的原因。看起来事务(2)正在等待并持有相同的锁?
------------------------
LATEST DETECTED DEADLOCK
------------------------
110606 5:35:09
*** (1) TRANSACTION:
TRANSACTION 0 45321452, ACTIVE 0 sec, OS thread id 3804 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 368, 1 row lock(s)
MySQL thread id 84, query id 3265713 localhost 127.0.0.1 famdev Updating
UPDATE people SET company_id = 1610, name = '<name>', password = '<hash>', temp_password = NULL, reset_password_hash = NULL, email = …
Run Code Online (Sandbox Code Playgroud) 我们在 Windows Server 2008 R2 上运行 MySQL 5.1。
我们最近一直在对我们的数据库进行一些诊断,并发现了一些我们无法解释的令人不安的伪影。当我们有需要很长时间(> 2000 毫秒)的查询时,我们添加了一些代码来记录。结果令人惊讶(并且可能是对我们僵局的解释)。
有时,通常只需要很少时间(<10 毫秒)的查询需要 4 到 13 秒。需要明确的是,这些是持续运行(每秒数次)并且不会受到这些查询时间峰值影响的查询。
我们已经检查了我们的索引,寻找任何明显的错误,但运气不佳。
更新
人表:
| people | CREATE TABLE `people` (
`people_id` bigint(20) NOT NULL AUTO_INCREMENT,
`company_id` bigint(20) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
`temp_password` varchar(10) DEFAULT NULL,
`reset_password_hash` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`phone` varchar(32) DEFAULT NULL,
`mobile` varchar(32) DEFAULT NULL,
`iphone_device_id` varchar(160) DEFAULT NULL,
`iphone_device_time` datetime DEFAULT NULL,
`last_checkin` datetime DEFAULT NULL, …
Run Code Online (Sandbox Code Playgroud) 这几乎可以肯定是我的另一个问题的原因,但我认为值得将两者分开,因为我有一个基于以下日志的假设,我很乐意伪造或验证该假设。
我的假设是另一个死锁实际上是以下查询的结果,根据我的理解隐藏了原始查询,innodb 状态仅显示最近的事务(这是正确的吗?)。
根据日志,我检查了我们的代码,发现依次执行了以下两个查询:
db.Execute("UPDATE people SET iphone_device_id=NULL WHERE iphone_device_id=@0 AND people_id<>@1", DeviceID, m_User.people_id);
// I have hard coded this query in this snippet to simplify things
db.Execute("UPDATE people SET company_id = 444, name = 'Dad', password = '<pass>', temp_password = NULL, reset_password_hash = NULL, email = '<redacted>@gmail.com', phone = NULL, mobile = NULL, iphone_device_id = 'iphone:<device_id_blah>', iphone_device_time = '2011-06-06 19:12:29', last_checkin = '2011-06-07 02:49:47', location_lat = <lat>, location_long = <lng>, gps_strength = 66, picture_blob_id = …
Run Code Online (Sandbox Code Playgroud) 我是数据库管理的新手。我试图找出死锁异常的原因,但我无法理解日志。
日志显示“事务 1 已回滚”。为什么会这样?赌注表与帐户表有外键关系,但它(运行插入的反式)无法获得 S 锁并因此因死锁而死亡是否“正常”?我的意思是,考虑到它只是验证参照完整性的读取,这似乎很糟糕。
第二笔交易也在写入赌注表,但没有更新。那么是用于创建 auto-inc 键的“机制”还是索引机制或两者都导致死锁?为什么它们不会以连续的方式发生?或者可能是他们,但某种等待时间太短了。
任何帮助,指针,进一步阅读如何使用下面的日志来解决死锁问题表示赞赏。
111031 17:39:26
*** (1) TRANSACTION:
TRANSACTION 0 984899905, ACTIVE 180 sec, process no 10882, OS thread id 1104619856 inserting
mysql tables in use 1, locked 1
LOCK WAIT 13 lock struct(s), heap size 3024, undo log entries 86
MySQL thread id 122, query id 28932942 localhost 127.0.0.1 bt update
INSERT INTO wager (amount_won, confirmation, created_by_partner, creation_date, description, fantasy_league,
first_game_start, image_thumb, image_wide, kind, last_game_start, last_update_version, locked, name,
num_future, num_past, num_present, partner, …
Run Code Online (Sandbox Code Playgroud) 在 InnoDB 上运行 Mysql 5.1.57,并且存在数据库锁定问题。
我有两个单独的会话连接到单个数据库 MySQL。在第一个会话中,我在表 A 上运行了一个很长的 SELECT 查询(技术上是一个慢速查询)。然后在另一个连接上,我在表 B 上运行了一个小的 UPDATE 查询。
编辑:如本主题底部所述,当表/查询完全位于不同的数据库中时也会出现此问题,并且不限于表/查询位于同一数据库中。
由于某种原因,在长选择查询完成之前,表 B 上的更新不会完成,就好像它们在同一个连接上一样。此外,“PROCESS LIST”将第二个查询显示为“正在释放项目”,同时它正在等待执行。
是否有任何设置或配置问题会导致这些查询按顺序运行而不是同时运行?
在此先感谢您的帮助。
表A
CREATE TABLE `history` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`log` text NOT NULL,
`created_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id_idx` (`user_id`),
CONSTRAINT `history_user_id_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=364398 DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
表B
CREATE TABLE `client` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`root_id` int(11) DEFAULT …
Run Code Online (Sandbox Code Playgroud) mysql ×5
innodb ×4
deadlock ×3
ado.net ×2
amazon-rds ×1
insert ×1
locking ×1
monitoring ×1
performance ×1