MYSQL8. Transaction과 Lock

jys9962·2021년 12월 20일
0

MySQL8

목록 보기
3/8

트랜잭션 레벨 (isolation level)

READ_UNCOMMITTED

버퍼풀/디스크 그대로 읽음 dirty read

READ_COMMITTED

커밋된 내용만 읽는다.
동일 구문 두 번 실행할 때 다른 데이터를 보게 될 수 있다. (non-repeatable read)

REPETABLE_READ

aurora mysql에서 read 인스턴스에서 기본값

SERIALIZEABLE

읽기잠금을 건다
타임아웃, 잠금마찰이 많이 발생한다.


REPETABLE READ의 CRUD 과정

각 행에 트랜잭션의 아이디를 가지고 있어서
repetable read를 구현한다

select

현재 트랜잭션의 아이디보다 같거나 작은 버전의 레코드만 검색함
삭제버전이 없거나 현재 아이디보다 커야함

insert

현재 아이디를 새 레코드에 함께 기록함

delete

레코드 삭제 아이디를 현재 아이디로 만듬

update

현재 시스템 버전으로 새 사본을 작성하고
기존 레코드에 현재 아이디로 삭제 버전을 만든다


InnoDB의 Lock

레코드 락

유니크 인덱스에 의한 변경 작업에서 락으로 해당 ROW만 잠금

update table_A SET column_a = 10 WHERE pk = 10;
select * FROM table_A WHERE pk = 10 for update;

갭 락

레코드와 레코드 사이에 insert 되는 것을 막음
column_a between 10 AND 20 일때 원래 없던 값인 15를 insert 하더라도 막는다
repetable read 이상에서 활성화

넥스트 키 락

레코드락 + 갭락
column_a between 10 AND 20 일 때 10인 레코드 바로 앞에 6인 값이 있다면 7~9도 막는다.


performance_schema.data_locks

X,REC_NOT_GAP: 레코드락
X,GAP: 갭락
X: 넥스트키락
LOCK_MODE=X, LOCK_DATA=15,2 인 경우
15,2 행을 잠그고 15,2의 갭(15이전값~15)도 잠근다


B+Tree와 Lock

갭락은 Index Tree에서 삽입을 막기 때문에 삽입되는 위치가 중요하다
innodb에서 모든 인덱스는 마지막 컬럼으로 PK가 오기 때문에 PK가 AUTO_INCREMENT 설정되있다면
인덱스 컬럼이 같은 값일 경우 늦게 삽입된 row가 인덱스 tree의 오른쪽으로 간다

10~20 갭락이 걸려있을때 새로운 10 값을 넣는 경우
새로운 값이 pk가 더 크므로 기존의 10보다 오른쪽으로 가서 10~20 사이로 들어가기 때문에 갭락에 의해 insert 할수없다.
20의 경우 기존 20보다 오른쪽으로 들어가기 때문에 insert가 가능하다

0개의 댓글