2011-01-24 58 views
3

Rails的版本:2.3.8ActiveRecord的「mysql的::錯誤:超過了鎖定等待超時」,沒有明顯的鎖

很多時候,不論白天,我的申請將看似隨機返回一個500錯誤與在對應的條目生產日誌:

ActiveRecord::StatementInvalid (Mysql::Error: Lock wait timeout exceeded; try restarting transaction: INSERT INTO `forum_posts` (`forum_topic_id`, `created_at`, `body`, `ancestry`, `updated_at`, `quote_limit`, `user_id`, `ancestry_depth`, `quote_root`) VALUES(1224783, '2011-01-24 19:18:38', 'Post body', '1285704', '2011-01-24 19:18:38', 1, 57931, 1, 1)) 

檢查MySQL的慢查詢日誌顯示了這個條目:

# Time: 110124 11:19:29 
# [email protected]: db_user[db_user] @ localhost [] 
# Query_time: 51 Lock_time: 0 Rows_sent: 0 Rows_examined: 0 
SET insert_id=0; 
INSERT INTO `forum_posts` (`forum_topic_id`, `created_at`, `body`, `ancestry`, `updated_at`, `quote_limit`, `user_id`, `ancestry_depth`, `quote_root`) VALUES(1224783, '2011-01-24 19:18:38', 'Post body', '1285704', '2011-01-24 19:18:38', 1, 57931, 1, 1); 

根據Rails的日誌,ActiveRecord的返回,因爲一個錯誤鎖定等待超時。這個簡單查詢的長期性質似乎也是如此。事情是,無處可查的慢查詢日誌可以找到需要很長時間處理的實際查詢 - 它們都與上面的示例類似。另外,在此相同的日誌,沒有一個項目有大於0

Lock_time值是否有人在這裏有一個想法,以什麼可能會造成這個明顯的鎖,以及如何將其隔離?目前我正在使用的工具似乎沒有什麼幫助。

在此先感謝。

+0

任何通過`show innodb status`顯示的長期交易?那些可能會創建隱藏的鎖,這些鎖並沒有出現在別處。 – 2011-01-24 21:41:23

回答

4

也許這會有所幫助: http://www.mysqlperformanceblog.com/2007/02/25/pitfalls-of-converting-to-innodb/

我們經常推薦給我們的客戶他們當前數據庫從MyISAM錶轉換爲InnoDB的。 在大多數情況下,傳輸本身幾乎很簡單,但應用程序可能因新的意外錯誤而中斷 1205(ER_LOCK_WAIT_TIMEOUT) 鎖定等待超時已過期。事務被回滾。 1235(ER_LOCK_DEADLOCK) 事務死鎖。您應該重新運行交易。

這不難處理這些錯誤,但你應該知道。 這是一些事情我們在PHP應用程序一樣:

class mysqlx extends mysqli { 

... 

    function deadlock_query($query) { 
      $MAX_ATTEMPS = 100; 
      $current = 0; 
      while ($current++ < $MAX_ATTEMPS) { 

        $res = $this->query($query); 

        if(!$res && ($this->errno== '1205' || $this->errno == '1213' )) 
            continue; 
        else 
          break; 
      } 
} 
... 
} 

您可能要處理ER_LOCK_WAIT_TIMEOUT以不同的方式,尤其是對於網絡應用中漫長的等待是不好的,你的想法。

相關問題