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

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

update some_table set some_column = some_value

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

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

Lock wait timeout exceeded; try restarting transaction

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



답변

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

SHOW PROCESSLIST;

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

KILL 115;

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


답변

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

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

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

KILL 1234;

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


답변

잠금에 대한 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) 


답변

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

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

이것을 실행하십시오 :

SET GLOBAL innodb_lock_wait_timeout = 5000; 

그리고 이것은 :

SET innodb_lock_wait_timeout = 5000; 


답변

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

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


답변

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

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

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

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

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

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


답변

mysql에서 Goto 프로세스.

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

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