책 <Real MySQL 8.0>을 읽고 정리한 내용입니다.
레코드 기반 잠금 제공, 높은 동시성 처리가 가능하고 안정적이며 성능이 뛰어남.
레코드에 잠금을 걸지 않고도 트랜잭션 격리 수준에 따라 일관된 읽기를 할 수 있다.
<- undo log를 이용하여 이 기능을 구현한다.
트랜잭션 격리 수준에 따라 조회되는 데이터가 다름.
(READ_UNCOMMITTED
, READ_COMMITTED
, REPEATABLE_READ
, SERIALIZABLE
)
데이터가 변경될 때?
InnoDB 버퍼풀 : 변경된 데이터를 디스크에 반영하기 전까지 잠시 버퍼링 하는 곳, 즉시 새로운 데이터로 변경됨. (COMMIT
명령이 실행되면 변경된 데이터를 디스크에 반영)
Undo log : INSERT, UPDATE, DELTE 같은 문장으로 데이터를 변경할 때 변경되기 이전 데이터를 백업 해두는 공간, 트랜잭션 롤백할 때 언두 로그를 사용하여 이전 버전의 데이터로 복구, 트랜잭션 격리 수준에 맞게 언두 로그에 백업해둔 데이터를 읽어 반환.
MVCC기술을 이용하여 잠금을 걸지 않고 일관된 읽기 작업이 가능하다.
레코드 단위로 잠금을 걸기 때문에 동시 처리 성능이 좋다.
사실 레코드 자체를 잠그는 것이 아닌, 인덱스를 잠금.
가정
테이블의 총 레코드 개수 : 5000개
성씨 컬럼이 '박'인 레코드 : 300개
성씨 컬럼이 '박'이고 이름 컬럼이 '병욱'인 레코드 : 1개
성씨 컬럼에는 idx_성씨 index가 생성되어 있음.
이 상태에서 성씨가 '박'이고 이름이 '병욱'인 user의 취미를 '축구'
로 바꾸는 update 쿼리를 실행하게되면?
이 테이블은 성씨 컬럼에 대해 index가 존재하므로 성이 '박'인 레코드 300개가 모두 lock이 걸리게 된다.
가정
테이블의 총 레코드 개수 : 5000개
성씨 컬럼이 '박'인 레코드 : 300개
성씨 컬럼이 '박'이고 이름 컬럼이 '병욱'인 레코드 : 1개
index 존재 X (자동으로 생성된 PK 인덱스만 존재)
이 상태에서 성씨가 '박'이고 이름이 '병욱'인 user의 취미를 '축구'
로 바꾸는 update 쿼리를 실행하게되면?
이 테이블은 성씨 컬럼에 대한 index가 존재하지 않고 대신에 자동으로 생성된 PK 인덱스만 존재하므로 테이블 full scan을 하게된다. 따라서 검색에 사용된 모든 PK 인덱스가 lock이 걸리게 됨. 즉 5000개 레코드 모두 lock이 걸린다.
가정
테이블의 총 레코드 개수 : 5000개
성씨 컬럼이 '박'인 레코드 : 300개
성씨 컬럼이 '박'이고 이름 컬럼이 '병욱'인 레코드 : 1개
성씨 컬럼과 이름 컬럼에 대한 복합 index 존재
이 상태에서 성씨가 '박'이고 이름이 '병욱'인 user의 취미를 '축구'
로 바꾸는 update 쿼리를 실행하게되면?
이 테이블은 성씨 컬럼과 이름 컬럼에 대해 복합 index가 존재하므로 성이 '박'이고 이름이 '병욱'인 레코드 1개만 lock이 걸리게 된다.