在我的Rails项目中,我使用sidekiq处理耗时的任务,但是在sidekiq日志中出现一个错误:
ActiveRecord::StatementInvalid: Mysql2::Error: Lock wait timeout exceeded; try restarting transaction: UPDATE `marker_layers` SET `show_fields` = 'title,desc', `sort_col` = 'title,desc', `updated_at` = '2016-05-17 07:36:02' WHERE `marker_layers`.`id` = 16021210
Processor: iZ23edse84Z:29310
侧边对齐.yml
# Options here can still be overridden by cmd line args.
# setsid sidekiq -d -C config/sidekiq.yml -e production
---
:concurrency: 5
:pidfile: tmp/pids/sidekiq.pid
:logfile: log/sidekiq.log
staging:
:concurrency: 10
production:
:concurrency: 40
:queues:
- ['critical', 3]
- ['default', 2]
- ['low', 1]
数据库.yml
production:
adapter: mysql2
encoding: utf8mb4
collation: utf8mb4_bin
reconnect: false
database: database_name
pool: 48
username: password
password: password
host: locahost
3条答案
按热度按时间gcuhipw91#
发生此错误的原因是,当不同的工作线程尝试修改同一资源时出现事务超时(基本上是数据库死锁)。
如果显式使用事务(如
SomeModel.transaction { SomeModel.task_that_takes_too_much_time }
),或者使用修改记录的普通ActiveRecord方法(因为所有内容都被 Package 到事务中),就会发生这种情况。我能给予你的唯一建议是探索替代方案,让你的工人 * 独特 *,比如使用https://github.com/mhenrixon/sidekiq-unique-jobs,让你的工作使用
.perform_in
。swvgeqrz2#
这意味着正在操作的记录已被另一个慢速SQL锁定,并等待了很长时间。
也许你的代码中有很多长事务。
检查您的代码,优化缓慢的SQL并拆分长事务。
我希望这对你有帮助。
tktrz96b3#
当数据库大小增长并且您显式地执行大量事务时,可能会发生这种情况,可能是其他某个线程在某个记录上持有记录锁的时间太长,并且您的线程正在超时。
我使用的一个解决方案是延长等待超时。
通过终端登录MySQL并运行此命令。
您可以做的另一件事是强制解锁MySQL中的锁定表:
像这样打破锁通常会导致数据库中的原子性不能在导致锁的SQL语句上实施。
这是一个黑客攻击。正确的解决方案是修复导致锁的应用程序。
强制解锁MySQL中的锁定表: