2016-05-17 113 views
4

在我的軌道項目中,我使用sidekiq處理耗時的任務,但在sidekiq記錄一個錯誤:的ActiveRecord :: StatementInvalid:Mysql2 ::錯誤:鎖等待超時超標

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 

enter image description here sidekiq.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] 

的database.yml

production: 
    adapter: mysql2 
    encoding: utf8mb4 
    collation: utf8mb4_bin 
    reconnect: false 
    database: database_name 
    pool: 48 
    username: password 
    password: password 
    host: locahost 
+2

很可能多個工作人員嘗試更新相同的數據庫行,並在等待訪問時出現一些超時。根據你的信息,我們不能說更多。您應該重新檢查您的代碼是否存在競爭條件並查看死鎖的來源... – averell

+1

您可能會發現http://stackoverflow.com/questions/6000336/how-to-debug-lock-wait-timeout-exceeded有幫助 –

回答

0

當不同的工作人員嘗試修改相同的資源時(基本上是數據庫死鎖),由於事務超時而發生此錯誤。

它發生或者如果您使用的交易明確地像SomeModel.transaction { SomeModel.task_that_takes_too_much_time }或使用正常的ActiveRecord的方法是修改記錄,因爲一切都被包裹成一個事務。

唯一的建議我可以給你的是探索的替代品使用https://github.com/mhenrixon/sidekiq-unique-jobs,使您的工作使用.perform_in讓你的員工獨特,等等。

+0

我會同時處理很多任務, – scottxu

0

這發生在數據庫大小和成長,你明確地做了很多交易,可能是一些其他線程持有記錄鎖定的一些記錄得太久,你的線程被超時。我用

一個解決方案,就是延長等待超時。

登錄到MySQL通過終端並運行此。

SET GLOBAL innodb_lock_wait_timeout = 28800; 

你可以做的另一件事是在MySQL鎖定表FORCE UNLOCK:

這樣的破鎖常常會導致原子在數據庫中不導致鎖定的SQL語句執行。

這是一個黑客攻擊。正確的解決方案是修復導致鎖定的應用程序。

FORCE UNLOCK for locked tables in MySQL:

0

這意味着在工作記錄已被其他慢SQL鎖定,並且已經等待了很久。

也許這就是在你的代碼中的許多長事務。

檢查你的代碼,優化SQL速度慢,分裂長事務。

我希望這可以對你有所幫助。

+0

是的,但我不知道如何解決它。 – scottxu