我正在运行一个 Rails 3.2.3
应用程序,该应用程序使用 apache2/passenger 部署在具有 mysql 数据库服务器的虚拟主机上。在网站访问量很大后我收到了这个错误:
ActiveRecord::StatementInvalid (Mysql::Error: Can't create more than
max_prepared_stmt_count statements (current value: 16382)
我认为这与流量有关,但如果是这样,我必须找到解决方法。以前有人遇到过这个错误吗?我不知道如何阻止它。
这是我在 mysql 中看到的:
mysql> 显示全局状态,如 'com_stmt%';
| Com_stmt_关闭 | 1720319 | Com_stmt_执行 | 2094137 |
| com_stmt_fetch | 0 |
| Com_stmt_准备 | 1768924 |
| Com_stmt_reprepare | 0 |
| Com_stmt_重置 | 0 |
| Com_stmt_send_long_data | 0 |
+------------------------+--------+
我正在运行 resque gem。
最佳答案
很可能某些东西正在针对数据库打开准备好的语句而不是关闭它们。
要检查这一点,请尝试查询:
show global status like ‘com_stmt%’;
Com_stmt_prepare 和 Com_stmt_close 之间的非常大的差异表明某些事情使准备好的语句处于打开状态。 Com_stmt_close = 0 当然会特别有说服力。
有可能,由于两者之间的差异相对较小,您实际上确实同时需要那么多 open 语句,但我仍然认为您更有可能将它们泄漏到某个地方(错误/边缘情况处理,正在人们经常忘记关闭资源的经典示例)。
您可以增加允许的语句数量:
set global max_prepared_stmt_count=<some_larger number>;
这应该会让事情重新开始。小心设置过高的限制,因为这会使您容易受到 DoS 攻击。
之后,我会监控它,看看是否随着时间的推移积累了更多准备好的语句。
如果你:
set global general_log = 'ON';
通用日志将记录Prepare
语句。查找任何没有匹配的关闭,以帮助找到任何此类问题。
关于mysql - Rails 3.2.3 mysql 错误 "max_prepared_stmt_count",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13849027/