MySQL Innodb의 간격 잠금을 잘 알고 있습니다.

MySQL의 록


잠금은 거래의 병행도를 높이는 병행 스케줄링 방법 중의 하나이다


사무를 지원하는 데이터베이스에서 사무의 병행수를 높이는 것은 성능을 향상시키는 방법이다.
다른 업무에 업데이트를 원하지 않는 데이터만 잠그고, 잠긴 데이터를 제외한 업데이트를 병행합니다.

Innodb는 행 잠금입니까?


Innodb는 업데이트 객체의 행만 잠급니다.이렇게 생각하면 의외의 함정에 빠질 수 있다.
그중의 하나가 바로 반차 록이다.

실제로 반전 록을 틀어보려고 해요.


견본표


그냥 id와str가 있는 간단한 책상이에요.id는 PK로 1~5 순서로 10,20줄로 날아갑니다.

일반 행 잠금


트랜잭션 1


select for 업데이트에서 id=2 줄을 명확하게 잠그기

트랜잭션 2


id=1,3,id=2를 업데이트할 수 있는 업데이트는 기다려야 한다(그림이 식별하기 어렵지만 잠겨 기다리기 때문에 답장이 없다).

이것은 정상적인 은행 잠금으로 거래 1에서 접촉한 은행만 잠긴다.

클리어런스 잠금


트랜잭션 1


select for update에서 id가 날아다니는 범위의 5~10을 만들어 보세요.
줄이 잠긴 느낌으로 볼 때, 나는 select의 id=5와 10의 줄이 잠길 것이라고 생각한다

트랜잭션 2


새 insert에서 id=7로 시도하면 답장이 없습니다.

원래 id=5와 10이 존재했는데 이 두 줄이 잠길 줄 알았는데 insert가 존재하지 않는 id=7에 도착했을 때 거기도 잠겼다.이것이 바로 반전 록이다.

select 공회전에도 간극 잠금


트랜잭션 1


id=6~9 범위 내에서 select for 업데이트.한 줄 한 줄이 실제로 부딪힌 적이 없다는 얘기다.

트랜잭션 2


이 경우에도 id=7은 insert를 진행할 수 없습니다.

한 줄 한 줄이 select를 잠그지 않아도 공전할 때 틈이 생길 수 있습니다.

범위 검색이 아니더라도 공백이 생기면 반차 잠금


트랜잭션 1



트랜잭션 2



범위나 id 지정을 막론하고 자물쇠가 비어 있습니다

범위에서 검색하지 않아도 틈이 나면 잠깁니다


트랜잭션 1


id>9에서 select for 업데이트

트랜잭션 2


id=7 밖에 있지만 간극 잠금 때문에 잠금

한마디로 간극 잠금이란


색인과 색인 사이의 잠금.
색인 단위의 록이라면 이해하기 쉬운 구조를 고려한 것 같다.
잠긴 대상의 범위를 최소화하고 거래에 이상이 생기지 않는다면 그렇다.
MySQL의 경우 5와 10 사이에 6, 7, 8, 9 같은 생각은 고려하지 않을 것이다.
그나저나 주 열쇠가 없는 책상에서 같은 일을 하면 책상에 잠긴다.이 역시 색인 단위로 잠금 범위를 좁힌다는 점을 고려하면 당연히 이런 생각이 든다.
어쨌든 어느 범위로 업데이트하는 것이 불편할지 전혀 모르기 때문에 책상 전체를 잠가야 한다.

실제 발생한 사고


예를 들어 100명의 사용자가 있는 서비스의 사용자 테이블에서 id=200에 대한 자물쇠를 잘못 잠근 경우 이 경우 id>100의 차이가 있기 때문에 이 시기에 새로 가입한 사용자는 자물쇠를 기다려야 한다.잠금을 해제하지 않으면 시간 초과 등 회원 가입이 불가능한 오류까지 발생할 수 있다.

좋은 웹페이지 즐겨찾기