[Database] MySQL InnoDB의 Read-Only Transaction 최적화

종미(미아)·2024년 5월 13일
2
post-thumbnail

들어가며

database와 storage engine에 따라 Read-Only Transaction을 최적화하는 방식이 다르다. 나는 Mysql을 많이 사용해왔기에 Mysql의 default storage engine인 InnoDB의 방식을 간단히 알아보고자 한다.

최적화가 필요한 이유

InnoDB engine의 모든 statement들은 명시해 놓지 않으면 자동으로 transaction이 된다. transaction을 명시하지 않으면 auto commit이 활성화된다. 그만큼 모든 statement마다 locking과 snapshot이 사용된다. RDB에서 일관성 보장을 지키면서 성능을 챙기는 것은 중요하다.

어떻게 최적화가 동작하는가

Mysql의 transaction id는 각 row에 관련된 필드로, INSERT, UPDATE, DELETE 작업이 일어나면 row를 locking한 tranction을 기록한다. 즉 traction id는 변경 관련 작업 혹은 SELECT ... FOR UPDATE와 같은 locking read에서만 필요하다.

InnoDb는 Read Only transaction을 사용하여 transaction id를 세팅하는 오버헤드를 줄인다. 그리고 불필요한 transaction id를 제거하면 뷰(read view)를 구성할 때 참조하는 데이터 크기가 줄어든다.

Read-Only Transaction을 감지하는 상황

1. statement 사용시

START TRANSACTION READ ONLY statement를 사용하면 감지한다.

2. single statement & non-locking select

auto commit이 활성화되어 모든 statement가 single statement임이 보장될 때 non-locking select statement는 read-only transaction이다. 이 때 non-locking select statement란 FOR UPDATE 혹은 LOCK IN SHARED MODE 절이 없는 select statement**이다.

3. 명시적 lock이 필요할 때까지

READ ONLY 옵션 없이 transaction을 시작했지만 테이블에 변경 사항이 없어 명시적으로 locking이 되지 않았을 때 감지한다.


[번외] locking select statement란?

(2024.05.19 에 추가)

쿼리를 날리고(조회) 해당 데이터를 수정 혹은 삽입하는 동작이 한 transaction 안에서 이루어질 경우 일반적인 select statment가 안전하지 않을 수 있다. 예를 들어, 사이트에 방문한 사용자가 방문자 수를 조회하고(select) 방문자 수를 1 증가시킨다(update)고 할 때 간발의 차로 다른 사용자가 방문한다고 해보자. 아래 사진과 같은 race condition이 발생한다. InnoDB는 두 가지 locking select statement를 지원하여 더 안전한 쿼리를 사용하도록 한다.

SELECT ... FOR SHARE

읽고 있는 row에 대해 shared mode lock을 건다. 즉, 다른 세션들이 해당 row를 읽을 수 있지만 (commit 될 때까지) 변경할 수는 없다.

SELECT ... FOR UPDATE

update statement를 locking하는 것과 동일하게 row와 row와 연관된 index들을 모두 잠근다. row 변경과 특정 트랜잭션 격리 수준에서 row를 읽는 것 모두 차단된다.

소감

스프링에서 @Transactional(readOnly = true)를 사용하다가 정확한 이해도가 낮은 것 같아 우선 가장 낮은 레벨부터 공부해보기로 했다. 다음 포스팅은 Spring의 @Transactional에 대해 다룰 것이다.

출처

[1]

[MySQL docs] Optimizing InnoDB Read-Only Transactions

[2]

https://www.baeldung.com/spring-transactions-read-only

[3]

[MySQL docs] Innodb locking reads

profile
BE 개발자 지망생 🪐

0개의 댓글