[mysql] “잠금 대기 시간 초과를 초과했습니다. 트랜잭션을 사용하지 않더라도 트랜잭션을 다시 시작하십시오”

다음 MySQL UPDATE문을 실행 중입니다 .

mysql> update customer set account_import_id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

거래를 사용하지 않고 있는데 왜이 오류가 발생합니까? 심지어 MySQL 서버를 다시 시작하려고 시도했지만 도움이되지 않았습니다.

테이블에는 406,733 개의 행이 있습니다.



답변

거래를 사용하고 있습니다. autocommit은 트랜잭션을 비활성화하지 않고 명령문 끝에서 자동으로 커밋합니다.

일어나고있는 일이 있습니다. 다른 스레드가 일부 레코드에 대해 레코드 잠금을 유지하고 있습니다 (테이블의 모든 레코드를 업데이트 중입니다!). 스레드가 시간 초과되었습니다.

당신은 이벤트를 발행하여 이벤트에 대한 자세한 내용을 볼 수 있습니다

SHOW ENGINE INNODB STATUS

이벤트 후 ( sql편집기에서). 이상적으로는 조용한 테스트 시스템에서이 작업을 수행하십시오.


답변

MySQL에서 잠긴 테이블의 잠금을 해제하는 방법 :

이와 같은 잠금을 해제 하면 데이터베이스의 원 자성 이 잠금 을 유발 한 SQL 문에 적용되지 않을 수 있습니다.

이것은 hackish이며 올바른 해결책은 잠금을 유발 한 응용 프로그램을 수정하는 것입니다. 그러나, 달러가 온라인에있을 때, 빠른 킥은 물건을 다시 움직일 것입니다.

1) MySQL 입력

mysql -u your_user -p

2) 잠긴 테이블 목록을 보자

mysql> show open tables where in_use>0;

3) 현재 프로세스 목록을 보자. 그 중 하나는 테이블을 잠그고 있습니다.

mysql> show processlist;

4)이 프로세스 중 하나를 종료

mysql> kill <put_process_id_here>;


답변

mysql> set innodb_lock_wait_timeout=100

Query OK, 0 rows affected (0.02 sec)

mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 100   |
+--------------------------+-------+

이제 잠금을 다시 트리거하십시오. SHOW ENGINE INNODB STATUS\G데이터베이스에 a를 발행하는 데 100 초의 시간이 있으며 어떤 트랜잭션이 귀하를 잠그는 지 확인하십시오.


답변

데이터베이스가 잘 조정되어 있는지 살펴보십시오. 특히 트랜잭션 격리. innodb_lock_wait_timeout 변수를 늘리는 것은 좋지 않습니다.

mysql cli에서 데이터베이스 트랜잭션 격리 레벨을 확인하십시오.

mysql> SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation, @@session.transaction_isolation;
+-----------------------+-----------------+------------------------+
| @@GLOBAL.tx_isolation | @@tx_isolation  | @@session.tx_isolation |
+-----------------------+-----------------+------------------------+
| REPEATABLE-READ       | REPEATABLE-READ | REPEATABLE-READ        |
+-----------------------+-----------------+------------------------+
1 row in set (0.00 sec)

분리 레벨을 변경하여 개선을 얻을 수 있습니다. READ COMMITTED와 같은 오라클을 대신 반복 읽기 (InnoDB 기본값)로 사용하십시오.

mysql> SET tx_isolation = 'READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL tx_isolation = 'READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> 

필요한 경우에만 SELECT FOR UPDATE를 사용하십시오.


답변

제안 된 해결책 중 어느 것도 나를 위해 일하지 않았지만 이것은 효과가있었습니다.

쿼리 실행을 방해하는 것이 있습니다. 쿼리의 테이블 중 하나에서 다른 쿼리를 업데이트, 삽입 또는 삭제하는 경우가 많습니다. 그게 무엇인지 찾아야합니다.

SHOW PROCESSLIST;

차단 프로세스를 찾으면 해당 프로세스를 찾아서 id실행하십시오.

KILL {id};

초기 쿼리를 다시 실행하십시오.


답변

MarkR의 말과 100 %. autocommit은 각 명령문을 하나의 명령문 트랜잭션으로 만듭니다.

SHOW ENGINE INNODB STATUS교착 상태에 대한 단서를 제공해야합니다. 느린 쿼리 로그도 잘 살펴보고 테이블을 쿼리하는 다른 항목을 확인하고 전체 테이블 스캔을 수행하는 모든 것을 제거하십시오. 행 수준 잠금은 잘 작동하지만 모든 행을 잠그려고 할 때는 작동하지 않습니다!


답변

이 테이블 내의 다른 레코드를 업데이트 할 수 있습니까? 아니면이 테이블이 많이 사용됩니까? 내가 생각하고있는 것은 잠금을 얻으려고 시도하는 동안 설정된 시간 초과 가이 레코드를 업데이트해야한다는 것입니다. 도움이 될 수있는 시간을 늘릴 수 있습니다.