2012-12-12 16 views
4

mysql 데이터베이스 서버가있는 가상 호스트에 apache2/passenger와 함께 배포 된 Rails 3.2.3 응용 프로그램을 실행 중입니다.레일 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) 

내가 생각하고이 트래픽의 양을 함께 할 수있는 뭔가가 있지만, 그래서이 주위에 방법을 찾을 수있는 경우 : I 트래픽이 많은 사이트를 타격 한 후이 오류가 발생했습니다. 누구든지 전에이 오류가 있었습니까? 나는 그것을 멈출 수있는 방법을 알아낼 수 없다. 여기

내가 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.4ms) SELECT `ecards`.* FROM `ecards` WHERE `ecards`.`id` = 34 LIMIT 1 
:

Ecard Load (0.1ms) SELECT `ecards`.* FROM `ecards` WHERE `ecards`.`id` = ? LIMIT 1 [["id", "34"]] 

지금이 참조

나는 더 이상 prepare 문을 사용하지 않는다고 생각합니다. 어떤 생각을 사랑할 것입니다 - 나는 물건이 어떻게 가는지보기 위해 계속 모니터링해야 할 것 같아요.

+0

성능에 나쁜 영향을 미치지 않는 한 문제가 해결되지 않을 이유가 없습니다. 특히 귀하가 게시 한 지위를 고려할 때 확실히 그 일을 수행 한 것으로 보입니다. – femtoRgon

1

데이터베이스에 대해 준비된 문을 열고 닫지 않을 가능성이 높습니다.

것은이를 확인하려면 쿼리 시도 :

show global status like ‘com_stmt%’; 

Com_stmt_prepare와 Com_stmt_close 사이에 매우 큰 차이가 열려 준비된 문을 떠나는 것을 나타냅니다. Com_stmt_close = 0은 물론, 특히 말할 것입니다.


그것은 내가 아직도 당신이 어딘가에 누수된다는 사실을 가능성이 생각 하는데요하지만 실제로, 한 번에 많은 열려있는 문을 필요 않는 것이, 둘 사이의 상대적으로 작은 차이와, 가능 (오류/EDGE 사례 처리, 사람들이 종종 자원을 폐쇄하는 것을 잊어 버리는 고전적인 사례).

set global max_prepared_stmt_count=<some_larger number>; 

일이 다시 굴러 가야 :

당신은으로 허용 문장의 수를 증가시킬 수있다. 한계가 너무 높아서 DoS에 취약해질 수 있습니다.

그 후, 나는 그것을 모니터하고, 준비된 진술이 시간이 지남에 따라 축적되는지 확인합니다.

당신이 경우

set global general_log = 'ON'; 

일반 로그 Prepare 문을 기록합니다. 그러한 문제를 찾을 수 있도록 일치하는 닫기가없는 항목을 찾으십시오.

+0

위의 명령을 실행할 때 위의 MySQL에 대한 내용 참조 .... 생각? –

+0

감사합니다. 필자가 의심했던 문제를 반드시 결론 짓기 위해 둘 사이의 불일치가별로 없습니다. 나는 더 많은 생각들을 가지고 갱신했다. – femtoRgon

+0

설정을 수행 할 때 mysql 오류가 발생했습니다. global_log = ON; 나는 그것이 문제와 관련이 있다고 생각하지 않는다, 나는 단지 글로벌 로그를 켜는 방법을 알 필요가있다. mysql> set global_log = ON; ERROR 1193 (HY000) : 알 수없는 시스템 변수 'global_log' –

관련 문제