복붙노트

[SQL] 잠금 대기 제한 시간 초과 "얻기; 내가 트랜잭션을 사용하지 않는 경우에도 "트랜잭션을 다시 시작합니다

SQL

잠금 대기 제한 시간 초과 "얻기; 내가 트랜잭션을 사용하지 않는 경우에도 "트랜잭션을 다시 시작합니다

나는 다음과 같은 MySQL의 UPDATE 문을 실행 해요 :

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

내가 트랜잭션을 사용하지 않는, 그래서 내가 왜이 오류가 될 것인가? 난 내 MySQL 서버를 다시 시작 시도하고 도움이되지 않았다.

표는 406,733 행이 있습니다.

해결법

  1. ==============================

    1.당신은 트랜잭션을 사용하는; 자동 커밋은 단지 그들을 자동으로 문장의 마지막에 커밋하게하지 비활성화 거래를한다.

    당신은 트랜잭션을 사용하는; 자동 커밋은 단지 그들을 자동으로 문장의 마지막에 커밋하게하지 비활성화 거래를한다.

    어떤 일이 일어나고 것은 다른 스레드가 너무 오래 (! 당신이 테이블의 모든 레코드를 업데이트하는) 일부 기록에 기록 잠금을 보유하고 스레드 시간이 초과되고있다.

    당신은을 실행하여 이벤트의 자세한 내용을 볼 수 있습니다

    SHOW ENGINE INNODB STATUS
    

    (SQL 편집기에서) 사건 이후. 이상적으로 조용한 테스트 기계에이 작업을 수행.

  2. ==============================

    2.HOW TO FORCE UNLOCK MySQL은 고정 테이블 :

    HOW TO FORCE UNLOCK 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>;
    
  3. ==============================

    3.

    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 상태 \ G를 발행하고 당신을 잠그고 다른 어떤 거래 볼 수 백초 시간을 가지고있다.

  4. ==============================

    4.데이터베이스가 미세 조정되는 경우에 살펴 보자. 특히 트랜잭션 격리. innodb_lock_wait_timeout 변수를 증가시키는 좋은 생각이 아니다.

    데이터베이스가 미세 조정되는 경우에 살펴 보자. 특히 트랜잭션 격리. 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 대신 REPEATABLE READ를 저지른 것처럼 (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를 사용하려고합니다.

  5. ==============================

    5.제안 된 솔루션을 아무도 나를 위해 일한하지만이했다.

    제안 된 솔루션을 아무도 나를 위해 일한하지만이했다.

    뭔가 쿼리의 실행을 차단하고 있습니다. 대부분의 경우 다른 쿼리의 업데이트는, 삽입 또는 쿼리의 테이블 중 하나에서 삭제. 당신은 그게 뭔지 알아 내야 :

    SHOW PROCESSLIST;
    

    당신이 차단 과정을 찾으면, 해당 ID 및 실행을 찾을 수 있습니다 :

    KILL {id};
    

    초기 쿼리을 다시 실행합니다.

  6. ==============================

    6.MarkR 말한 100 %. 자동 커밋은 각 문장 한 문장 트랜잭션 수 있습니다.

    MarkR 말한 100 %. 자동 커밋은 각 문장 한 문장 트랜잭션 수 있습니다.

    SHOW ENGINE INNODB 상태는 교착 상태의 원인에 관해서는 몇 가지 단서를 제공한다. 너무 테이블을 쿼리되는 다른 무엇을보고 전체 tablescan을하고있어 아무것도 제거하려고하는 속도가 느린 쿼리 로그에서 좋은 모습을 가지고있다. 행 수준 잠금이 잘 작동하지만 당신은 모든 행을 잠그려고하지 않을 때!

  7. ==============================

    7.이 테이블에서 다른 레코드를 업데이트하거나,이 표는 많이 사용? 내가 생각하고하는 것은 잠금을 획득하려고 시도하는 동안이 레코드 집합이 초과되었습니다했다 제한 시간을 업데이트 할 필요가 있다는 점이다. 당신은 도움이 될 수 있습니다 시간을 향상시킬 수 있습니다.

    이 테이블에서 다른 레코드를 업데이트하거나,이 표는 많이 사용? 내가 생각하고하는 것은 잠금을 획득하려고 시도하는 동안이 레코드 집합이 초과되었습니다했다 제한 시간을 업데이트 할 필요가 있다는 점이다. 당신은 도움이 될 수 있습니다 시간을 향상시킬 수 있습니다.

  8. ==============================

    8.행의 수는 큰 아니지만 ... account_import_id 경우는 없습니다 기본 키에 인덱스를 만듭니다.

    행의 수는 큰 아니지만 ... account_import_id 경우는 없습니다 기본 키에 인덱스를 만듭니다.

    CREATE INDEX idx_customer_account_import_id ON customer (account_import_id);
    
  9. ==============================

    9.당신은 단지 하나의 큰 쿼리를 살해 한 경우, 롤백 할 시간이 소요됩니다. 살해 쿼리가 다시 롤링 완료되기 전에 다른 쿼리를 실행하면, 당신은 잠금 시간 초과 오류를 얻을 수 있습니다. 그게 나에게 무슨 일이 있었는지입니다. 이 솔루션은 조금 기다려야 만했다.

    당신은 단지 하나의 큰 쿼리를 살해 한 경우, 롤백 할 시간이 소요됩니다. 살해 쿼리가 다시 롤링 완료되기 전에 다른 쿼리를 실행하면, 당신은 잠금 시간 초과 오류를 얻을 수 있습니다. 그게 나에게 무슨 일이 있었는지입니다. 이 솔루션은 조금 기다려야 만했다.

    세부:

    나는 1 백만에 대한 행 90 만 밖으로에 대한 제거하는 DELETE 쿼리를 발행했다.

    나는 (행의 10 %를 제거) 실수로이 실행 : 테이블에서 삭제 WHERE MOD (번호 10) = 0

    대신이의 (행의 90 %를 제거) 테이블 MOD (ID, 10)! = 0에서 삭제

    나는 행의 90 %가 아닌 10 %를 제거하고 싶었다. 나는 그것이 다시 지금까지 삭제했던 모든 행을 출시 할 것을 알고, MySQL의 명령 줄에서 프로세스를 살해 그래서.

    그리고 나는 즉시 올바른 명령을 실행하고, 직후 잠금 제한 시간 초과 오류가 발생했습니다. 나는 자물쇠가 실제로 백그라운드에서 계속 일어나는 사망 쿼리의 롤백 될 수 있음을 깨달았다. 나는 몇 초를 기다리고 그래서 쿼리를 다시 실행.

  10. ==============================

    10.확인 데이터베이스 테이블이 InnoDB 스토리지 엔진과 READ-COMMITTED 트랜잭션 격리 수준을 사용하고 있는지 확인.

    확인 데이터베이스 테이블이 InnoDB 스토리지 엔진과 READ-COMMITTED 트랜잭션 격리 수준을 사용하고 있는지 확인.

    당신은 SELECT @@ GLOBAL.tx_isolation하여 확인할 수 있습니다 @@ tx_isolation; MySQL의 콘솔.

    이 READ-COMMITTED되도록 설정되어 있지 않은 경우 당신은 그것을 설정해야합니다. 당신이 MySQL의에서 SUPER 권한이 있는지를 설정하기 전에해야합니다.

    당신은 http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html의 도움을 걸릴 수 있습니다.

    이 설정하여 나는 당신의 문제가 해결 얻을 것이다 생각합니다.

    당신은 또한 당신이 한 번에 두 가지 과정이 업데이트를 시도하지 않는 확인 할 수 있습니다. 사용자 (@tala)이 맥락에서 유사한 오류 메시지, 어쩌면 두 번 검사를 발생했습니다 ...

  11. ==============================

    11.나는 구글에서 와서 그냥 나를 위해 일한 솔루션을 추가하고 싶었다. 내 문제는 내가 영업과 같은 오류가 발생했습니다 있도록 캐스케이드에서 FK를 많이했다 거대한 테이블의 삭제 기록하려고 하였다.

    나는 구글에서 와서 그냥 나를 위해 일한 솔루션을 추가하고 싶었다. 내 문제는 내가 영업과 같은 오류가 발생했습니다 있도록 캐스케이드에서 FK를 많이했다 거대한 테이블의 삭제 기록하려고 하였다.

    나는 자동 커밋을 비활성화 한 후 바로 SQL 문장의 끝에 COMMIT 추가했다. 지금까지 내가이 릴리스를하는 대신에 명령의 끝에서 기다리고의 비트에 의해 버퍼 비트를 이해한다.

    영업 이익의 예제를 유지하기 위해,이 일을해야 :

    MySQL의> 집합 자동 커밋 = 0;

    MySQL의> 갱신 고객 설정 account_import_id = 1; 범하다;

    당신이 이전과 MySQL의 설정를 마칠 경우 다시 자동 커밋을 활성화하는 것을 잊지 마십시오.

    MySQL의> 집합 자동 커밋 = 1;

  12. ==============================

    12.하지 않도록 적절한 말씨 - 늦은 (평소처럼) 파티에 그러나 내 문제는 내가 나쁜 SQL (초보자 인) 여러 프로세스가 레코드 (들)에 대한 잠금을했습니다를 <썼다는 사실이었다. 난 그냥에 가지고 결국 : KILL을 사용하여 ID를 죽일 후 SHOW PROCESSLIST와

    하지 않도록 적절한 말씨 - 늦은 (평소처럼) 파티에 그러나 내 문제는 내가 나쁜 SQL (초보자 인) 여러 프로세스가 레코드 (들)에 대한 잠금을했습니다를 <썼다는 사실이었다. 난 그냥에 가지고 결국 : KILL을 사용하여 ID를 죽일 후 SHOW PROCESSLIST와

  13. ==============================

    13.내가 PHP를 사용했을 때 이런 일이 나에게 일어 언어 구조 출구; 거래의 중간이다. 그런 다음이 거래 "중지는"당신은 MySQL의 프로세스를 죽일 필요 (PROCESSLIST 전술을)

    내가 PHP를 사용했을 때 이런 일이 나에게 일어 언어 구조 출구; 거래의 중간이다. 그런 다음이 거래 "중지는"당신은 MySQL의 프로세스를 죽일 필요 (PROCESSLIST 전술을)

  14. ==============================

    14.내 경우에, 나는 수정 데이터에 비정상적인 쿼리를 실행했다. 당신이 당신의 쿼리에서 테이블을 잠글 경우에, 당신은 잠금 제한 시간을 처리 할 필요가 없습니다 :

    내 경우에, 나는 수정 데이터에 비정상적인 쿼리를 실행했다. 당신이 당신의 쿼리에서 테이블을 잠글 경우에, 당신은 잠금 제한 시간을 처리 할 필요가 없습니다 :

    LOCK TABLES `customer` WRITE;
    update customer set account_import_id = 1;
    UNLOCK TABLES;
    

    이것은 아마도 정상적인 사용에 대한 좋은 생각이 아니다.

    MySQL의 8.0 참조 설명서 : 자세한 정보 참조

  15. ==============================

    15.나는이 두 교리 DBAL 연결, (중요 로그) 비 트랜잭션으로 그 중 하나를 필요로 실행, 그들은 서로에 따라하지 평행하게 실행하기위한 것입니다.

    나는이 두 교리 DBAL 연결, (중요 로그) 비 트랜잭션으로 그 중 하나를 필요로 실행, 그들은 서로에 따라하지 평행하게 실행하기위한 것입니다.

    CodeExecution(
        TransactionConnectionQuery()
        TransactionlessConnectionQuery()
    )
    

    데이터가 매우 테스트 후 롤백에 대한 내 통합 테스트는 거래에 싸여 있었다.

    beginTransaction()
    CodeExecution(
        TransactionConnectionQuery()
        TransactionlessConnectionQuery() // CONFLICT
    )
    rollBack()
    

    내 솔루션은 이러한 테스트에서 포장 트랜잭션을 사용하지 않고 다른 방법으로 DB 데이터를 재설정하는 것이 었습니다.

  16. ==============================

    16.나는 단지 하나 개의 항목으로 하나 개의 테이블을 갱신했지만, MySQL의를 다시 시작한 후, 문제가 해결되었다하더라도,이 같은 오류가 발생했다.

    나는 단지 하나 개의 항목으로 하나 개의 테이블을 갱신했지만, MySQL의를 다시 시작한 후, 문제가 해결되었다하더라도,이 같은 오류가 발생했다.

  17. from https://stackoverflow.com/questions/5836623/getting-lock-wait-timeout-exceeded-try-restarting-transaction-even-though-im by cc-by-sa and MIT license