MySQL은 '따닥'을 어떻게 방어할까

숑숑·2023년 1월 27일
48

DB

목록 보기
4/7
post-thumbnail

'따닥' 이 무엇인가

매우 빠르게 '따닥' 더블클릭하는 것을 말합니다.

이런 경우, 드물게 DB에 타임스탬프가 정말 똑같게 찍히는 요청이 있습니다.
그런데 동시 트랜잭션에 대한 처리가 안 되어있다면?

같은 요청을 두번 처리해서 문제가 될 수 있습니다.

저도 업무 중 비슷한 문제를 직면했는데,
DB insert를 실패하게 해서(중복 키 이슈로) 방어한다는 대안을 세웠습니다.

그런데, DB는 동시요청을 어떻게 막는걸까?

작은 의문이 들어 알아보았습니다.


ChatGPT에게 물어보았다

우선 DB도 동시요청에 에러나는 케이스가 있을지 궁금했습니다.

갑작스런 영어 어택 죄송합니다. (ChatGPT가 한국어 응답이 정말 느립니다..)
여기서 말하는 키는 Auto-incremented 옵션을 가진 Primary Key 라고 생각해주세요.

요약
질문
두개의 row를 정확히 동시에 insert 시도했을 때, 동일 키로 삽입 되는 것이 가능한가? 아니면 항상 duplicateKeyException 을 일으키는가?
대답
둘 중 하나의 트랜잭션은 해당 에러를 일으킨다.

이걸로 알 수 있는건 아무리 정확한 시간에 동시에 요청한다 하더라도,
primary 혹은 unique key가 있는 이상 동일 키 삽입은 불가능합니다.

그럼 DB는 요청 시간에 관계 없이 항상 구분해서 처리한다는건데,
정확히 어떻게 하고 있는걸까요?

요약
질문
MySQL은 내부적으로 동시 insert 요청을 어떻게 처리하는가?
대답
세가지 기술을 이용한다.
1. 트랜잭션 스케줄러
2. 스레드 분산
3. 낙관적 동시성 제어

이 중 첫번째, 트랜잭션 스케줄러에 대해 알아봅시다


트랜잭션 스케줄러

대기 중인 트랜잭션 간 우선순위를 매기는 스케줄러를 도입하고 있었네요.

공식 문서에 따르면, MySQL 8.0.20 이상은 CATS(Contention-Aware Transaction Scheduling) 알고리즘을 쓰고 있습니다.
이전엔 FIFO(First-In-First-Out) 알고리즘을 기본으로 두고, 경합이 강한 경우에만 CATS 알고리즘을 사용했다고 합니다.
그런데 CATS 알고리즘이 많이 개선되어 FIFO 알고리즘을 쓸 필요가 없다고 하네요.

그럼 CATS 알고리즘이 뭘까요?

The CATS algorithm is based on a simple intuition:
not all transactions are equal, and not all objects are equal.

모든 트랜잭션이 동일하지 않고, 모든 객체가 같지는 않다.
FIFO 알고리즘의 허점을 짚는 말입니다.

한 마디로 우선순위를 두자는 말입니다.
그럼 누구에게 더 높은 순위를 매긴다는 걸까요?

Here’s an analogy:
if a cab driver and a bus driver are waiting in a line for coffee, making coffee for the bus driver first (even if s/he arrived after the cab driver) will allow more people to arrive at their destination sooner (since there are more passengers on the bus than in the cab). While this might seem unfair for the cab driver, because of the complex inter-dependencies, this strategy would make the entire system so much faster that everyone (even the cab driver!) would benefit from a more efficient service.

버스 기사와 택시 기사가 커피를 사려고 줄을 서고 있다면, 누구에게 먼저 커피를 줘야 할까요?

버스 기사에게 먼저 주는 것이 더 효과적입니다.
버스 기사가 커피를 먼저 받아야 탑승객들도 더 빨리 이동할 수 있을테니까요.

그럼 택시 기사에겐 불이익 아닌가요?

그렇지만은 않습니다.
버스 기사, 탑승객, 택시 기사 모두 각각의 트랜잭션이라고 생각해봅시다.
다른 트랜잭션들이 빨리 잠금을 풀어줘야 시스템 성능에 도움이 되기 때문에
택시 기사 트랜잭션도 빠르게 이동할 수 있습니다.

the CATS algorithm does something smarter:
it counts the total number of transactions that are blocked by each transaction (directly or indirectly) and grants the lock to the one that is blocking more transactions.

FIFO는 먼저 요청된 트랜잭션이 있는지만 확인합니다.

CATS는 각 트랜잭션마다 몇개의 트랜잭션이 종속되어 있는지 카운트합니다.
그리고 가장 많은 트랜잭션을 가지고 있는 트랜잭션에게 lock을 줍니다.

아래 사진을 보고 어떤 트랜잭션이 먼저 lock을 획득할지 맞혀봅시다.

  • t1: 4개
  • t2: 3개

t1이 획득하게 됩니다. 1개 차이로 이겼네요.

참고로 shared lock의 경우, 가능한 많은 lock을 허용한다고 합니다.

성능이 FIFO와 얼마나 차이나는지 확인해봅시다.
아래는 MySQL 코어 개발자가 테스트한 결과입니다.


모든 면에서 우월합니다.
주목할 점은 경합이 없는 시나리오에서도 CATS가 이겼다는 건데요,
경합이 없다면 스케줄링을 아예 하지 않기 때문입니다.
FIFO 를 걷어낸 것이 성능적으로 옳았다는게 증명된 셈입니다.


Reference

profile
툴 만들기 좋아하는 삽질 전문(...) 주니어 백엔드 개발자입니다.

11개의 댓글

comment-user-thumbnail
2023년 1월 29일

첫번째 영어를 잘못 해석하셨습니다. 직렬가능 레벨에서도 unique 제약조건이 설정된 컬럼이 같은키를 넣는건 당연히 안됩니다. 저기에서 말하는 다르다는건 직렬가능레벨에서는 말 그대로 직렬적임을 보장하기 때문에 '동시'가 아니게 되게 된다는 말입니다.

1개의 답글
comment-user-thumbnail
2023년 2월 2일

오 진짜 좋은 내용 감사합니다
따당을 개발하면서
많이 경험했는데
디비는 이렇구나..

답글 달기
comment-user-thumbnail
2023년 2월 2일

Your writing is really informative, especially because it's so meaningful and updated. Thanks for sharing this wonderful post!

Your writing is really great. I’m so glad I read it. It kept me hooked the whole way through.

Thanks for this information. I really appreciate the information that you have provided.

https://www.tellthebell.fyi/ https://www.tellpizzahut.info/

답글 달기
comment-user-thumbnail
2023년 2월 4일

열심히 읽고 추가 자료 찾아보면서 공부했습니다! 큰 도움 됐어요 ㅎㅎ 출처 남기고 제 블로그에도 정리해봐도 괜찮을까요?

1개의 답글
comment-user-thumbnail
2023년 2월 5일

안녕하세요 아래 블로그에 글쓴이님 글 훔쳐가서 그대로 돈벌이 하고 있는 거 아시나요? 저도 도둑질 당했는데, 글쓴이님도 이거 당하셨길래 알려드려요. 감방에 넣어야 할 것 같습니다. 가장 아래 출처라고 작게 남기고 자기가 쓴 척 올리네요. 오늘 신고하려구요.

https://m.blog.naver.com/specialee8/222999660764

1개의 답글
comment-user-thumbnail
2023년 2월 6일

I have faced the same issue. Can anyone help me?

답글 달기
comment-user-thumbnail
2023년 2월 7일

I will try to figure it out for more.
https://www.myallsaversconnect.net/

답글 달기
comment-user-thumbnail
2023년 4월 4일

Want to take a break from reality and have a good laugh? https://kickthebuddy.co is the perfect game to help you unwind, offering hilarious and absurd ways to beat up a cartoon character.

답글 달기