“잠금 대기 시간 초과를 초과했습니다. '고착 된'MySQL 테이블에 대해 트랜잭션을 다시 시작 하시겠습니까?


131

스크립트에서 다음과 같은 쿼리를 로컬 데이터베이스에 보냈습니다.

update some_table set some_column = some_value

where 부분을 추가하는 것을 잊었으므로 동일한 열이 테이블의 모든 행에 대해 동일한 값으로 설정되었으며 수천 번 수행되었으며 열이 색인화되었으므로 해당 색인이 너무 많이 업데이트되었습니다. .

시간이 너무 오래 걸리기 때문에 스크립트가 잘못되었습니다. 그 이후로 컴퓨터를 재부팅했지만 간단한 쿼리를 실행하는 데 시간이 오래 걸리고 관련 인덱스를 삭제하려고하면이 메시지와 함께 실패하기 때문에 테이블에 문제가 발생했습니다.

Lock wait timeout exceeded; try restarting transaction

이것은 innodb 테이블이므로 트랜잭션이 내재되어있을 수 있습니다. 이 테이블을 수정하고 걸린 트랜잭션을 제거하려면 어떻게해야합니까?


3
출력은 SHOW FULL PROCESSLIST무엇입니까?
Wolph

SHOW FULL PROCESSLIST 명령 만 표시합니다. 로컬 개발 데이터베이스입니다. 아무것도 실행되고 있지 않습니다. 색인을 삭제하려고 할 때 명령 행에 'lock wait ..'오류 메시지가 표시됩니다.
Tom

이 경우 서로를 기다려야하는 다른 트랜잭션에서 2 개의 개별 연결을 작성하고있을 수 있습니다.
Wolph

나중에 거래를 만들지 않았습니다. 스크립트를 종료하고 컴퓨터를 재부팅 한 후 명령 줄에서 로그인하여 둘러 보았습니다. mysql 명령 행 클라이언트를 제외하고는 다른 데이터베이스를 사용하지 않았으므로 테이블에 무언가가 붙어 있어야합니다.
Tom

답변:


143

비슷한 문제가 있었고 실행중인 스레드를 확인하여 해결했습니다. 실행중인 스레드를 보려면 mysql 명령 행 인터페이스에서 다음 명령을 사용하십시오.

SHOW PROCESSLIST;

mysql 명령 행 인터페이스에 액세스 할 수없는 경우 phpMyAdmin에서 보낼 수도 있습니다.
그러면 해당 id와 실행 시간이있는 스레드 목록이 표시되므로 실행하는 데 너무 많은 스레드를 종료 할 수 있습니다. phpMyAdmin에는 KILL을 사용하여 스레드를 중지하는 버튼이 있습니다. 명령 행 인터페이스를 사용하는 경우 다음 예제와 같이 KILL 명령과 스레드 ID를 사용하십시오.

KILL 115;

해당 스레드에 대한 연결이 종료됩니다.


36
필기 해! 이것은이 문제와 관련하여 많은 SO 스레드 중 하나에서 언급되었습니다. 때로는 테이블을 잠근 프로세스가 프로세스 목록에서 잠자기 상태로 표시됩니다! 문제의 데이터베이스에서 열린 모든 스레드를 자거나 죽일 때까지 머리카락을 찢어 버렸습니다. 결국 테이블의 잠금이 해제되고 업데이트 쿼리가 실행되었습니다. 논평자는 "때때로 MySQL 스레드가 테이블을 잠근 다음 MySQL과 관련이없는 것을 기다릴 때 휴면 상태"라고 언급했다.
Eric L.

(나는 관련된 질문에, 여기에 그 생각 조각을 육체로 내 자신의 대답을 추가했습니다 )
Eric L.

이것은 나를 도왔다. PHPStorm 데이터베이스 관리 / 쿼리 기능으로 생성 된 몇 개의 휴면 스레드가있었습니다.
Ejaz

큰! 나는 5 시간 이래로 숨겨져있는 프로세스를 식별하고 죽일 수있었습니다.
Aldo Paradiso

2
이것은 감염된 상처를 도청하는 덕트 이상의 해결책이 아닙니다. 근본적인 근본 문제를 해결하지 않습니다.
user2914191

55

당신은 현재 실행중인 거래를 확인할 수 있습니다

SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`

거래는 목록에서 가장 오래된 거래이므로 첫 번째 거래 중 하나 여야합니다. 이제 값을 가져 trx_mysql_thread_id와서 다음 KILL명령을 보내십시오 .

KILL 1234;

어떤 거래인지 확실하지 않은 경우 첫 번째 쿼리를 자주 반복하고 어떤 거래가 지속되는지 확인하십시오.


당신은 SQL 실제로 액세스하는 테이블에서 다른 차단하는 트랜잭션을 볼 수 있음을 실행하려면 루트 계정을 사용해야 할 수도 있습니다
tom10271

40

잠금에 대한 InnoDB 상태 확인

SHOW ENGINE InnoDB STATUS;

MySQL 오픈 테이블 확인

SHOW OPEN TABLES WHERE In_use > 0;

보류중인 InnoDB 트랜잭션 확인

SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`; 

잠금 종속성 확인-무엇을 차단

SELECT * FROM `information_schema`.`innodb_locks`;

위의 결과를 조사한 후 무엇을 잠그고 있는지 확인할 수 있습니다.

문제의 근본 원인이 코드에있을 수도 있습니다. Hibernate와 같은 JPA를 사용하는 경우 특히 주석에 대한 관련 함수를 확인하십시오.

예를 들어 here 에 설명 된대로 다음 주석을 잘못 사용하면 데이터베이스가 잠길 수 있습니다.

@Transactional(propagation = Propagation.REQUIRES_NEW) 

4
정말 고맙습니다! 실행 SELECT * FROM information_schema.innodb_trx t JOIN information_schema.processlist p ON t.trx_mysql_thread_id = p.id중인 범인을 밝히기 : 잠금 스레드가 내 IP 주소에서 나왔습니다. 트랜잭션 도중에 남겨둔 디버그 콘솔을 닫는 것을 잊었습니다 ...
Elias Strehle

40

데이터베이스 크기가 커지고 많은 트랜잭션을 수행 할 때 이런 일이 시작되었습니다.

진실은 아마도 쿼리 또는 DB를 최적화 할 수있는 방법이 있지만 해결을 위해이 두 쿼리를 시도하십시오.

이것을 실행하십시오 :

SET GLOBAL innodb_lock_wait_timeout = 5000; 

그리고 이것은 :

SET innodb_lock_wait_timeout = 5000; 

2
참조 링크 : innodb_lock_wait_timeout
culix

1
매우 바쁜 11GB 데이터베이스를 실행 중입니다. 이것은 나를 위해 일한 유일한 것입니다, 감사합니다!
dongemus

영원히 보관하지 않으려면 값을 이전 값으로 변경하십시오.
Ricardo Martins

이것은 내 사용자 중 일부의 경험이 더 느리다는 것을 의미합니까?
Arnold Roa

9

트랜잭션에 대한 연결을 설정하면 트랜잭션을 수행하기 전에 잠금을 얻습니다. 자물쇠를 얻을 수 없다면 언젠가 시도하십시오. 여전히 잠금을 얻을 수 없으면 잠금 대기 시간 초과 오류가 발생합니다. 잠금을 획득 할 수없는 이유는 연결을 닫지 않았기 때문입니다. 따라서 두 번째 잠금을 얻으려고 할 때 이전 연결이 여전히 닫혀 있고 잠금을 유지하므로 잠금을 획득 할 수 없습니다.

해결 방법 : 연결을 닫거나setAutoCommit(true) (디자인에 따라) 잠금을 해제하십시오.


7

MySQL을 다시 시작하면 제대로 작동합니다.

그러나 이러한 쿼리가 중단되면 어딘가에 문제가 있음을 명심하십시오.

  • 귀하의 질문에 (잘못 배치 된 문자, 직교 곱, ...)
  • 편집 할 매우 많은 레코드
  • 복잡한 조인 또는 테스트 (MD5, 하위 문자열 LIKE %...%등)
  • 데이터 구조 문제
  • 외래 키 모델 (체인 / 루프 잠금)
  • 잘못 색인 된 데이터

@syedrakib가 말했듯이 작동하지만 이것은 생산을위한 오래 살지 않는 솔루션입니다.

주의 : 다시 시작하면 일관성이없는 데이터에 영향을 줄 수 있습니다.

또한 EXPLAIN 키워드를 사용하여 MySQL이 쿼리를 처리하는 방법을 확인하고 쿼리 속도를 높일 수있는 것이 있는지 확인할 수 있습니다 (인덱스, 복잡한 테스트 등).


감사합니다. 당신은 내 문제를 직접 해결하지 못했지만 테이블 잠금으로 고통 받고 너무 나빴습니다. 그것은 인터넷 전체의 유일한 게시물이므로 외래 키를 확인하는 아이디어로 이어집니다. 그래서 나는 기본 키의 키가 11이고 외래 키가 10이라는 것을 알았습니다. 나는 그것이 어떻게 일어날 수 있고 왜 모든 것이 이전에 작동했는지 알 수 없습니다.
EscapeNetscape

@EscapeNetscape 천만에요,이 작은 답변이 도움이 되었기 때문에 :)
Benj

3

mysql에서 Goto 프로세스.

작업이 아직 진행중인 것을 볼 수 있습니다.

특정 프로세스를 종료하거나 프로세스가 완료 될 때까지 기다리십시오.


7
문제를 해결합니다. 그러나 이것은 라이브 프로덕션 서버에 대한 해결책이 될 수 없습니다 ... 어떻게 교착 상태 처리를 출력 할 수 있습니까? 아니면 어떻게 교착 상태가 발생하지 않도록 할 수 있습니까?
Rakib

1
글쎄, 개발자가 작성하지 않았지만 프레임 워크의 활성 레코드 인터페이스에 의해 완벽하게 구성되고 완벽하게 mysql 쿼리를 이스케이프 처리하더라도 잠금 대기 시간 초과 문제는 여전히 발생할 수 있습니다. 그래서 나는 적절한 mysql 쿼리를 작성하지 않습니다.
Rakib

1

"update"문에서 같은 문제가 발생했습니다. 내 솔루션은 단순히 테이블에 대해 phpMyAdmin에서 사용 가능한 작업을 실행하는 것입니다. 테이블을 최적화하고 플러시하고 조각 모음을 수행했습니다 (순서가 아님). 테이블을 삭제하고 백업에서 복원 할 필요가 없습니다. :)


1
문제를 해결할 수 있습니다. 그러나 이러한 오류가 발생할 때마다이 작업을 수행해야하는 것은 라이브 프로덕션 서버에 대한 해결책이 될 수 없습니다.이 교착 상태 처리를 어떻게 출력 할 수 있습니까? 아니면 어떻게 교착 상태가 발생하지 않도록 할 수 있습니까?
Rakib

1

나는 같은 문제가 있었다. SQL의 교착 상태 문제라고 생각합니다. 작업 관리자에서 SQL 프로세스를 강제로 닫을 수 있습니다. 그래도 문제가 해결되지 않으면 컴퓨터를 다시 시작하십시오. 테이블을 삭제하고 데이터를 다시로드 할 필요가 없습니다.


문제를 해결합니다. 그러나 이것은 라이브 프로덕션 서버에 대한 해결책이 될 수 없습니다 ... 어떻게 교착 상태 처리를 출력 할 수 있습니까? 아니면 어떻게 교착 상태가 발생하지 않도록 할 수 있습니까?
Rakib

Apache와 해당 서비스 (또는 적어도 MySQL)를 다시 시작합니다. 재부팅 할 필요가 없습니다
Amjo

1

웹 서버에서 MySQL에 대한 ODBC 연결로 MS Access 2007을 사용하여 특정 레코드 그룹을 삭제하려고 할 때이 문제가 발생했습니다. 일반적으로 MySQL에서 특정 레코드를 삭제 한 다음 업데이트 된 레코드로 바꿉니다 (여러 관련 레코드를 캐스케이드 삭제하면 단일 레코드 삭제에 대한 모든 관련 레코드 삭제가 간소화됩니다).

테이블에 대해 phpMyAdmin에서 사용할 수있는 작업 (최적화, 플러시 등)을 실행하려고했지만 플러시하려고 할 때 RELOAD 오류가 필요합니다. 데이터베이스가 웹 서버에 있으므로 데이터베이스를 다시 시작할 수 없습니다. 백업에서 복원하는 것은 옵션이 아닙니다.

웹의 cPanel mySQL 액세스 에서이 레코드 그룹에 대해 삭제 쿼리를 실행하려고했습니다. 같은 오류 메시지가 나타납니다.

내 솔루션 : Sun (Oracle의) 무료 MySQL Query Browser (이전에 컴퓨터에 설치)를 사용하여 삭제 쿼리를 실행했습니다. 문제가 해결되었습니다. 그런 다음 ODBC Access to MySQL 연결을 사용하여 Access 스크립트를 사용하여 기능을 다시 한 번 수행 할 수있었습니다.


-2

고쳤다.

쿼리에서 일치하지 않는 데이터 형식 삽입이 없는지 확인하십시오. "사용자 브라우저 에이전트 데이터"를 시도 VARCHAR(255)하고이 잠금에 문제가있는 문제가 있었지만이를 변경했을 때 문제가 해결되었습니다 TEXT(255).

따라서 데이터 유형이 일치하지 않을 가능성이 높습니다.


-151

테이블을 삭제하고 백업에서 복원하여 문제를 해결했습니다.


20
또한이 답변은 SO의 최저 점수 "허용 된"답변 이라는 영광을 얻습니다! 🏆
ashleedawg 오전

1
이것은 또한 일반적으로 가장 낮은 점수의 답변입니다
Bob Kerman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.