我有一些游戏使用 MySQL 事件每隔几分钟更新一次用户的健康和其他属性。我遇到了一个问题,最终事件不再运行,事件中的 SQL 没有被执行。
我不确定如何修复它,所以我尝试重新启动 MySQL 并修复了一段时间。我将 MySQL 设置为每晚在 cron 中重新启动,但这不是一个很好的解决方案。有时 MySQL 无法重新启动并挂起。
编辑:我的数据库中使用事件的所有表都是 InnoDB。
可能是您的事件未完成并持有许多锁。最终,额外的工作将“堆积”起来,每个都试图获取锁但似乎没有做任何工作。如果您使用的是 MyISAM 表,则尤其如此,因为它们具有表级锁定,而不是行级锁定。
考虑配置 pt-stalk(Percona Toolkit 的一部分)来捕获“show processlist”和其他重要细节的常规快照。然后,您可以追踪事情何时“停止工作”并追溯问题开始的时间。
要防止作业“堆积”,请使用 GET_LOCK 函数:
SELECT GET_LOCK('THIS_IS_A_NAMED_LOCK', 0) INTO @got_lock;
IF @got_lock = 1 THEN
select 'do something here';
SELECT RELEASE_LOCK('THIS_IS_A_NAMED_LOCK') INTO @discard;
END IF;
如果您使用 InnoDB,请确保在事件中发出 START TRANSACTION 和 COMMIT 命令,以确保您不会创建长时间运行的事务。
最近由于这个问题,我最终将我的 iOS 游戏下线。我不知道如何实现贾斯汀斯旺哈特的答案。如果有人有兴趣,我可以提供我的 php/mysql 代码,看看你是否可以解决这个问题。让我知道。andy.triboletti@gmail.com