【发布时间】:2011-01-20 22:12:05
【问题描述】:
我有一个记录在线用户的 innoDB 表。它会在用户每次刷新页面时更新,以跟踪他们所在的页面以及他们最后一次访问网站的日期。然后我有一个每 15 分钟运行一次的 cron 来删除旧记录。
我在尝试获取锁定时发现“死锁”;昨晚尝试重新启动事务大约 5 分钟,这似乎是在向该表中运行 INSERT 时。有人可以建议如何避免此错误吗?
=== 编辑 ===
以下是正在运行的查询:
首次访问网站:
INSERT INTO onlineusers SET
ip = 123.456.789.123,
datetime = now(),
userid = 321,
page = '/thispage',
area = 'thisarea',
type = 3
在每次页面刷新时:
UPDATE onlineusers SET
ips = 123.456.789.123,
datetime = now(),
userid = 321,
page = '/thispage',
area = 'thisarea',
type = 3
WHERE id = 888
Cron 每 15 分钟一次:
DELETE FROM onlineusers WHERE datetime <= now() - INTERVAL 900 SECOND
然后它会进行一些计数以记录一些统计信息(即:在线成员、在线访问者)。
【问题讨论】:
-
你能提供更多关于表结构的细节吗?是否有任何聚集或非聚集索引?
-
dev.mysql.com/doc/refman/5.1/en/innodb-deadlocks.html - 运行“show engine innodb status”将提供有用的诊断。
-
插入单行如何导致该插入的死锁?我期待在事务中,您需要尝试获取至少两个锁才能死锁。插入一行只持有一个锁。我认为您在第一个查询中缺少一些插入或选择。