Rails 3.2.3 mysql错误“;最大“准备”计数;
我正在运行一个Rails 3.2.3 mysql错误“;最大“准备”计数;,mysql,ruby-on-rails-3.2,Mysql,Ruby On Rails 3.2,我正在运行一个rails3.2.3应用程序,该应用程序是在一个带有mysql数据库服务器的虚拟主机上与apache2/passenger一起部署的。在大量流量访问该站点后,我出现了此错误: ActiveRecord::StatementInvalid (Mysql::Error: Can't create more than max_prepared_stmt_count statements (current value: 16382) 我认为这与交通量有关,但如果是这样的话,我必须找到解
rails3.2.3
应用程序,该应用程序是在一个带有mysql数据库服务器的虚拟主机上与apache2/passenger一起部署的。在大量流量访问该站点后,我出现了此错误:
ActiveRecord::StatementInvalid (Mysql::Error: Can't create more than
max_prepared_stmt_count statements (current value: 16382)
我认为这与交通量有关,但如果是这样的话,我必须找到解决办法。以前有人犯过这个错误吗?我想不出怎么阻止它
以下是我在mysql中看到的内容:
mysql>显示全局状态,如“com_stmt%”
|Com|U stmt|U close|1720319
|Com|u stmt|u execute|2094137|
|Com_stmt|u fetch | 0|
|公司准备| 1768924|
|Com|u stmt|u reprepare | 0|
|Com_stmt|u重置| 0|
|Com_stmt_发送_long_数据| 0|
+-------------------------+---------+
我正在运行resque gem。很可能有什么东西正在打开针对数据库的准备好的语句,而不是关闭它们 要检查此问题,请尝试查询:
show global status like ‘com_stmt%’;
Com_stmt_prepare和Com_stmt_close之间的差异非常大,这表明准备好的语句处于打开状态。当然,Com_stmt_close=0会特别说明问题
有可能,这两者之间的相对较小的差异,实际上你确实需要一次多个开放的语句,尽管我仍然认为你更可能泄漏到某个地方(错误/边缘情况处理,是人们经常忘记关闭资源的典型例子)。 您可以通过以下方式增加允许的语句数:
set global max_prepared_stmt_count=<some_larger number>;
常规日志将记录
准备语句。寻找任何没有匹配结尾的问题,以帮助找到任何此类问题。好的,我暂时在这里权衡答案。我用femtoRgon的提示来检查状态。然后我将这两行添加到我的database.yml文件中
pool: 30
prepared_statements: false
我重新启动了mysql。现在,在应用程序运行一段时间后,我看到:
mysql> show global status like 'com_stmt%';
| Com_stmt_close | 189017 |
| Com_stmt_execute | 189017 |
| Com_stmt_fetch | 0 |
| Com_stmt_prepare | 189017 |
| Com_stmt_reprepare | 0 |
| Com_stmt_reset | 0 |
| Com_stmt_send_long_data | 0 |
Ecard Load (0.1ms) SELECT `ecards`.* FROM `ecards` WHERE `ecards`.`id` = ? LIMIT 1 [["id", "34"]]
Ecard Load (0.4ms) SELECT `ecards`.* FROM `ecards` WHERE `ecards`.`id` = 34 LIMIT 1
任何地方都没有差异。。。加上我以前看到的:
mysql> show global status like 'com_stmt%';
| Com_stmt_close | 189017 |
| Com_stmt_execute | 189017 |
| Com_stmt_fetch | 0 |
| Com_stmt_prepare | 189017 |
| Com_stmt_reprepare | 0 |
| Com_stmt_reset | 0 |
| Com_stmt_send_long_data | 0 |
Ecard Load (0.1ms) SELECT `ecards`.* FROM `ecards` WHERE `ecards`.`id` = ? LIMIT 1 [["id", "34"]]
Ecard Load (0.4ms) SELECT `ecards`.* FROM `ecards` WHERE `ecards`.`id` = 34 LIMIT 1
我现在看到:
mysql> show global status like 'com_stmt%';
| Com_stmt_close | 189017 |
| Com_stmt_execute | 189017 |
| Com_stmt_fetch | 0 |
| Com_stmt_prepare | 189017 |
| Com_stmt_reprepare | 0 |
| Com_stmt_reset | 0 |
| Com_stmt_send_long_data | 0 |
Ecard Load (0.1ms) SELECT `ecards`.* FROM `ecards` WHERE `ecards`.`id` = ? LIMIT 1 [["id", "34"]]
Ecard Load (0.4ms) SELECT `ecards`.* FROM `ecards` WHERE `ecards`.`id` = 34 LIMIT 1
我认为这表明我不再使用prepare语句了?我想我会喜欢任何想法的——我想我必须不断地观察事态的发展……谢谢,这两者之间并没有太大的差异,所以我必须总结出我所怀疑的问题。我更新了一些想法。我在设置全局_log=ON时遇到了一个mysql错误;我不认为这与问题有关,我只需要知道如何打开全局日志!mysql>设置全局_log=ON;错误1193(HY000):未知系统变量'global_log'对不起,请尝试:set global general_log='ON'代码>编辑我的答案以反映你对我上面的答案有何看法?你认为这能解决问题吗?我将如何测试?只要它不会对您的性能产生负面影响,我看没有理由这不能解决问题。特别是考虑到你发布的状态,它看起来确实完成了任务。