2012-12-12 69 views
4

我正在運行一個Rails 3.2.3應用程序,該應用程序在帶有mysql數據庫服務器的虛擬主機上與apache2/passenger部署在一起。我很多的流量被擊中的部位後得到這個錯誤:Rails 3.2.3 mysql錯誤「max_prepared_stmt_count」

ActiveRecord::StatementInvalid (Mysql::Error: Can't create more than 
max_prepared_stmt_count statements (current value: 16382) 

我想它是與業務量,但如果讓我必須找到解決的辦法。任何人有過這個錯誤?我無法弄清楚如何阻止它。

這裏就是我在mysql中看到:

的mysql>顯示像'com_stmt%的全球地位;

| Com_stmt_close | 1720319 | Com_stmt_execute | 2094137 |

| Com_stmt_fetch | 0 |

| Com_stmt_prepare | 1768924 |

| Com_stmt_reprepare | 0 |

| Com_stmt_reset | 0 |

| Com_stmt_send_long_data | 0 |

+ ------------------------- + --------- +

我正在resque寶石。

回答

2

好的,我暫時在這裏回答了一個答案。我使用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 

我認爲這表明我不再使用準備語句?會愛任何想法 - 我想我將不得不繼續監測,看看事情如何...

+0

只要它不會對你的性能產生不利影響,我看不出有什麼理由不能解決問題。特別是考慮到你發佈的這個地位,它似乎已經完成了這項工作。 – femtoRgon

1

這很可能是打開對數據庫的準備語句,而不是關閉它們。

要檢查這個問題,嘗試查詢:

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>; 

。小心限制太高,因爲這會使您容易受到DoS攻擊。

之後,我會監控它,看看是否有更多準備好的陳述隨時間積累。

如果您:

set global general_log = 'ON'; 

一般的日誌會記錄Prepare語句。查找沒有匹配的關閉,以幫助找到任何此類問題。

+0

請參閱上面的mysql當我運行該命令....想法? –

+0

謝謝,不是兩者之間的差異必然會導致我懷疑的問題。我已經更新了一些更多的想法。 – femtoRgon

+0

我在設置global_log = ON時收到mysql錯誤;我不認爲它與問題有關,我只需要知道如何讓全局日誌打開! mysql> set global_log = ON; 錯誤1193(HY000):未知系統變量'global_log' –