source

IN 절을 사용한 업데이트의 경우 잠금 대기 시간 초과가 발생합니다.

manycodes 2022. 12. 5. 21:31
반응형

IN 절을 사용한 업데이트의 경우 잠금 대기 시간 초과가 발생합니다.

LOCK WAIT TIMOUT 문제가 발생하고 있습니다.SELECT ... FOR UPDATE진술.

저는 이해할 수 없는 시나리오를 준비했습니다.왜 처음 세 블록은 즉시 실행되지만 마지막 블록은 대기하는지 알려 주시겠습니까?

감사해요.

-- I'm using MariaDb

-- T1 is the mysql terminal window 1
-- T2 is the mysql terminal window 2

CREATE TABLE `test` (
  `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `name` VARCHAR(255) NOT NULL
) COMMENT='' ENGINE='InnoDB' COLLATE 'utf8_bin';

INSERT INTO test SET name='foo';

T2: START TRANSACTION;
T1: START TRANSACTION;
T1: SELECT * FROM test WHERE id IN (1) FOR UPDATE;
T2: INSERT INTO test SET name='foo'; -- executed immediately

T2: START TRANSACTION;
T1: START TRANSACTION;
T1: SELECT * FROM test WHERE id IN (1,2) FOR UPDATE;
T2: INSERT INTO test SET name='foo'; -- executed immediately

T2: START TRANSACTION;
T1: START TRANSACTION;
T1: SELECT * FROM test WHERE id IN (1,2,3) FOR UPDATE;
T2: INSERT INTO test SET name='foo'; -- executed immediately

T2: START TRANSACTION;
T1: START TRANSACTION;
T1: SELECT * FROM test WHERE id IN (1,2,3,4) FOR UPDATE;
T2: INSERT INTO test SET name='foo'; -- waits for T1 to commit

T2: commit;
T1: commit;

InnoDB 행 레벨 잠금은 실제로는 인덱스 잠금입니다.문서화되어* 있지 않은 기능은 다음과 같습니다.잠금이 설정되어 있는 경우SELECT는 (사용자 정의) 인덱스를 사용하지 않습니다(또는 사용할 수 없습니다). 그러면 기본 클러스터된 인덱스만 사용할 수 있으며 테이블 전체가 잠깁니다.

옵티마이저는 인덱스가 "긴" 목록을 확인하는 데 유용하지 않다고 판단했을 가능성이 매우 높습니다.IN()파라미터(테이블의 대부분이 스캔이 필요하기 때문에 파라미터).이것은 당신이 감지한 예상치 못한 부작용으로 이어질 것입니다.

가설은 실행 계획을 확인함으로써 확인할 수 있다.

"select for update"는 UPDATE 행만 잠근다고 가정합니다.그러나 INSERT에는 원래 "선택" 아래에 있는 레코드를 삽입할 수 있기 때문에 잠금이 적용됩니다.문서에는 "행 및 관련 인덱스 항목을 잠급니다"라고 명시되어 있습니다.

http://dev.mysql.com/doc/refman/5.6/en/innodb-locking-reads.html

언급URL : https://stackoverflow.com/questions/27690681/for-update-with-in-clause-causes-lock-wait-timeout

반응형