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'编辑我的答案以反映你对我上面的答案有何看法?你认为这能解决问题吗?我将如何测试?只要它不会对您的性能产生负面影响,我看没有理由这不能解决问题。特别是考虑到你发布的状态,它看起来确实完成了任务。