2011-01-24 53 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以不同的方式,尤其是对于网络应用中漫长的等待是不好的,你的想法。

相关问题