2010-04-15 4 views
9

나는 매일 수백만 건의 호출을 처리하는 알고리즘을 실행하는 웹 서비스를 실행 중이며 일부 백그라운드 처리도 실행합니다. "MySQL 상자에 연결 시도가 너무 많습니다."라는 오류 메시지가 몇 초 동안 표시되지만, 이는 트래픽이 많거나 무엇이든 넣을 수있는 것이 아닙니다.MySQL/PHP에서 "너무 많은 연결"오류의 근본 원인을 찾는 방법

특정 시간에 서버가 CPU와 메모리 측면에서 너무로드되지 않고 2-3 개의 연결 (스레드)이 열려 있고 모든 것이 원활하게 작동한다는 것 이외에는 병목 현상이 발생합니다. (나는 Zabbix를 사용합니다.

) 모니터링을 추적하는 방법?

+1

프로덕션 이외의 컴퓨터에서 문제를 재현 할 수 있습니까? 적합한 하드웨어 상자와 생산로드를 시뮬레이션 할 수있는 드라이버 시스템을 갖춘 스트레스 테스트 환경을 갖추고 있습니까? 그렇지 않은 경우 가능한 한 빨리 하나를 얻으십시오. 그렇지 않으면 프로덕션 환경에서 디버깅을 시도해야합니다. 일반 쿼리 로그를 켜는 것과 같이 위험이 높은 작업을 수행해야합니다. – MarkR

+0

업데이트 - 너무 많은 연결 문제가 발생하는 동안 SHOW PROCESSLIST를 성공적으로 실행했습니다. 내가 얻는 것은 총 151 개의 쿼리 목록 (내 num 연결은 150로 설정 됨). 그 중 2 명은 내 PC (쇼 프로세스 목록) 나머지는 374-395의 시간 값을 가진 쿼리 명령입니다. 상태가 FULLTEXT 인 사람 이외에는 LOCKED입니다. 3 개의 쿼리가 모두 UPDATE이고 나머지는 SELECT입니다. 이 잠김 현상의 원인을 어떻게 알 수 있습니까? – Nir

+0

문제의 원인을 밝히기는 어렵지만, 시스템을 호깅하는 쿼리라고 확신합니다. 그들 가운데 어느 것이 가장 오랫동안 사형을 받았는지 그리고 많은 것을 반복하는 것처럼 보이는 것을보십시오. 그 후에 올바른 인덱스를 만들고 쿼리를 최적화하는 것만으로도 여기에 아무도 스키마와 쿼리를 보지 않고 무엇을 해야할지 정확히 말할 수 없습니다. – matei

답변

3

MyISAM 또는 InnoDB (또는 다른 하나)? MyISAM은 테이블 수준 잠금을 사용하므로 사용자가 무거운 선택을 실행 한 다음 동일한 테이블과 수많은 선택 쿼리에 대한 업데이트를 수행 한 다음 마지막 선택 쿼리는 업데이트가 완료 될 때까지 기다려야합니다 (tu rn은 first - heavy - select가 끝날 때까지 기다려야한다).

InnoDB의 경우 innotop과 같은 도구가 교착 상태의 원인을 찾는 데 유용 할 수 있습니다 (http://www.xaprb.com/blog/2006/07/31/how-to-analyze-innodb-mysql-locks/ 참조).

BTW 잠금을 발생시키는 쿼리는 잠긴 상태가 아닌 쿼리 중 하나 여야합니다.

+0

MyISAM의 내 테이블과 몇 개의 메모리 테이블. – Nir

+0

SHOW PROCESSLIST는 잠금 상태의 쿼리와 FULLTEXT 초기화 상태의 쿼리를 많이 제공합니다. 후자는 가장 낮은 프로세스 ID를가집니다. 이 프로세스와 관련된 쿼리가 특정 프로세스를 잠그는 것이 확실합니까? – Nir

+0

LOCKED 상태에있는 사람들은 다른 쿼리가 끝나기를 기다리고 있습니다. – wimvds

6

시도에 어떤 창의적인 아이디어는 이런 일이 발생하면 오픈 MySQL의 콘솔을 가지고 무엇을 볼 수있는

SHOW PROCESSLIST;
을 실행하려면 쿼리가 실행 중입니다. 에서 [mysqld를] 섹션에

log-slow-queries=/var/log/mysql-log-slow-queries.log

느린 고려해야 할 쿼리를 위해 수행해야하는 최소 시간은 무엇을 정의하는

set-variable=long_query_time=1
를 사용 가 또는 느린 쿼리를 로깅 가능 수 (my.cnf 파일에이 줄을 삽입합니다. (변경 사항을 적용하려면 mysql을 다시 시작해야 함)

2

SHOW OPEN TABLES 명령은 MySQL의 모든 테이블의 잠금 상태를 표시합니다. 하나 이상의 쿼리가 연결 백락을 일으키는 경우 SHOW PROCESSLIST과 열린 테이블을 결합하여 정확히 어떤 쿼리가 작업을 보류하는지 확인해야합니다.

+0

오류가 발생하는 동안 SHOW OPEN TABLES를 완료했습니다. 내가 가지고있어 table_name 나는이 테이블이 잠긴다라고 생각하는 것이 맞을 까? 이 테이블에 대한 쿼리에서 모든 연결이 차단 되었습니까? – Nir

+0

'148'은 148 개의 잠금이 활성화되어 있거나 해당 테이블에서 보류 중임을 의미합니다. InnoDB라면 엔진이 로우 레벨 잠금을 할 수 있기 때문에 큰 문제는 아니지만 MyISAM이라면 테이블 레벨 잠금 만 할 수 있기 때문에 큰 문제입니다. InnoDB의 경우,'SHOW INNODB STATUS'를 통해 활성 쿼리/잠금이 무엇인지 볼 수 있습니다. 출력의 일부는 쿼리 및 오류/잠금 목록입니다. –

0

구현을 많이하고 PHP를 일반적으로 알지 못해도 DB 연결이 오래 가지 않아도 아무런 문제가 없다고 확신합니까? 예 : 요청이 처리 된 후에도 연결 상태가 유지됩니까?

PHP에서는 스크립트가 종료되거나 mysql_close($conn);을 호출 할 때 대개 자동으로 연결이 닫히지 만 모든 종류의 자체 연결 풀링을 사용하면 문제가 발생할 수 있습니다.

1

가 전체 텍스트 검색 MySQL의에서이 버그에 관련이있을 수 있습니다 :이 경우 http://bugs.mysql.com/bug.php?id=37067

, 전체 텍스트 초기화 실제로 MySQL은 중단됩니다. 불행히도 해결책이없는 것 같습니다.

1

이전 주제. 그러나 나는 방금이 문제가 있었고 mysqldump 스크립트를 하루에 3 번 예약했기 때문에 발생했다. 이 시점에서 웹 애플리케이션의 사용량이 꽤 많아지면 mysqldump가 데이터베이스의 모든 테이블을 잠그는 동안 모든 웹 애플리케이션 쿼리가 서로를 위로 대기하게됩니다.가장 좋은 방법은 별도의 컴퓨터에 복제 슬레이브를 설치하고 프로덕션 서버가 아닌 슬레이브에서 백업을 가져 오는 것입니다.

관련 문제