[CS] 다중 스레드 데드락과 DB 데드락

Arthur·2023년 4월 14일
0
post-thumbnail

1. 락(Lock)이란❓


컴퓨터 과학에서 락(lock) 또는 뮤텍스(mutex, 상호 배제에서)는 여러 스레드를 실행하는 환경에서 자원에 대한 접근에 제한을 강제하기 위한 동기화 매커니즘이다.
락은 상호 배제 동시성 제어 정책을 강제하기 위해 설계된다.
-위키피디아(Wikipedia)-

위키피디아에는 위와 같이 다중 스레드 혹은 프로세스 환경에서 발생하는 락에 대해 설명하고 있다.

그런데 '한권으로 읽는 컴퓨터 구조와 프로그래밍' 책에서는
우리(개발자)가 실제로 처리해야 할 문제는 공유 자원이 아닌, 실제로 처리해야 할 문제는 여러 작은 연산으로 이뤄진 작업을 어떻게 원자적(Atomic) 으로 만들 수 있을까 하는 문제를 다뤄야 한다고 한다.

저자는 컴퓨터에 '은행 잔고를 조정하라' 와 같은 명령어가 있다면 위와 같은 문제를 논할 필요도 없을 것이라고 한다.

명령어를 만들고 처리하기 위해 우리는 코드에 중요한 부분을 상호 배제(mutual exculusion) 메커니즘을 통해 원자적으로 처리하게 만든다.

이런 목표의 프로그램을 만들면서 충돌을 피하기 위해 어드바이저리 락(advisory lock)을 만든다.

결국 우리는 요구사항들에 필요한 추상화된 원자 단위의 명령어로 만든다.
이 때 데이터의 무결성을 유지하고, 충돌을 방지하기 위해 락(Lock)을 사용하게 된다.


2. 데드락이란❓


데드락(Deadlock)

데드락(Deadlock, 교착 상태)는 여러 프로세스 간에 리소스를 공유할 때 발생할 수 있는 문제로 아무도 자원을 할당 받지 못하고, 무한히 대기하는 상태를 말한다.

위 사진은 데드락의 예시이다.

  • 스레드1이 스레드2가 사용하고 있는 리소스1를 사용하기 위해 기다리고 있다.
  • 스레드2는 스레드1가 사용하고 있는 리소스2를 사용하기 위해 기다리고 있다.

일반적으로 다중 프로세스, 스레드에 대해 얘기하지만 사용자, 트랜잭션, 분산 시스템에서도 데드락이 발생 할 수 있다.

교착 상태의 원인

  1. 상호 배제(mutual exclusion) : 공유 자원을 함께 쓸 수 없어서 어느 한 프로세스가 독점적으로 사용해야만 한다.
  2. 점유 대기(hold and wait) : 프로세스들은 어느 자원을 점유한 상태에서 다른 자원을 요청한다.
  3. 비선점(no preemption) : 프로세스가 할당받은 자원을 강제로 빼앗을 수 없다.
  4. 순환 대기(circular wait) : 각 프로세스가 서로 순환적으로 다른 프로세스가 갖고 있는 자원을 요구한다.

교착 상태 방지 방법

  1. 자원을 상호 배제하지 않고 언제든지 공유할 수 있는 자원으로 만든다.
  2. 어느 자원을 점유한 다음에 다른 자원을 요구하지 않고 한꺼번에 자원을 요구한다.
  3. 선점형으로 바꾼다.
  4. 자원마다 우선순위를 부여해서 모든 프로세스가 다 서로 정해진 순서대로만 자원을 요구한다.

3. DB 데드락


데드락

트랜잭션 데드락이라고도 한다.
트랜잭션 A가 Accounts 테이블을 잡고 있다.
트랜잭션 B는 Orders 테이블을 잡고 있다.
둘 다 작업을 끝내기 위해서는 각 트랜잭션이 잡고 있는 테이블이 필요한 상황이다.
위와 같은 상황이 DB 데드락의 예시이다.


4. 데드락과 DB 데드락의 차이


위 내용을 봤을 때 다중 스레드 데드락과 DB 데드락의 차이는 크게 보이지 않는다.

MySQL의 InnoDB 엔진을 예시로 들었을 때
InnoDB 스토리지 엔진은 내부적으로 잠금이 교착 상태에 빠지지 않았는지 체크하기 위해 잠금 대기 목록을 그래프(Wait-for-List 형태로 관리한다.

데드락 감지 스레드

InnoDB는 데드락 감지 스레드를 가지고 있어서 주기적으로 잠금 대기 그래프를 검사해 교착 상태에 빠진 트랜잭션들을 찾아서 그 중 하나를 강제 종료한다.

강제 종료를 판단하는 기준

트랜잭션의 언두 로그 양이며, 언두 로그 레코드를 더 적게 가진 트랜잭션이 일반적으로 롤백의 대상이 된다.

  • 언두 레코드를 적게 가졌다는 이야기는 롤백을 해도 언두 처리를 해야 할 내용이 적다는 것
    (MySQL 서버의 부하도 덜 발생한다.)

동시 처리 스레드가 데드락 감지 스레드와 성능에 미치는 영향

동시 처리 스레드가 매우 많아지거나 각 트랜잭션이 가진 잠금의 개수가 많아지면 데드락 감지 스레드가 느려진다.결국 서비스 쿼리를 처리 중인 스레드는 작업을 진행하지 못하고 대기하면서 서비스에 악영향을 미친다.
(동시 처리 스레드가 매우 많은 경우 데드락 감지 스레드는 더 많은 CPU 소모)

데드락 감지 설정을 off 할 수 있다?

MySQL 서버는 innodb_deadlock_detect 시스템 변수를 off로 설정하면 데드락 감지 스레드가 작동하지 않는다고 한다.
데드락 감지 설정을 off 하면 데드락 상황에서 무한정 대기가 발생하게 되기 때문에 신중히 설정해야 한다.


5. 라이브 락(Live Lock)이라는게 있다❗


라이브 락
나 : 엄마 저..
엄마 : 아빠한테 물어봐
나 : 아빠 저..
아빠 : 엄마한테 물어봐
...

라이브 락은 위와 같이 행동은 일어나지만 block된 것처럼 보이는 현상을 말한다.

한 길을 지나가는데 마주보는 사람이 서로 같은 방향으로 계속 비켜줘서 지나가지 못하는 상황도 하나의 예시다.

라이브 락 외에도 스핀 락, 공유 락, 베타 락, 업데이트 락 등등 상당히 많다.
이것을 전부 다루기는 어려울 것 같아서 예시가 재미있는 라이브 락만 다뤄봤다.

🤔느낀 점


데드락이라는 키워드를 알게 되어 공부 할 때, 단순히 암기의 대상이 되고 싶지는 않았다.
그래서 이렇게 다양한 자료를 찾아보면서 공부를 하게 되었다.
그리고 위와 같은 인사이트를 얻게 된 것은 직접 찾아본 것도 있지만,
F-lab 멘토님이 키워드와 논의 내용을 주신 덕분에 조금 더 깊게 공부하게 되었다.


참고자료


  • DEVOPEDIA - Deadlock => 링크
  • 토르비욘 - 교착 상태 (deadlock) => 링크
  • 책 <한권으로 읽는 컴퓨터 구조와 프로그래밍> - 락(470페이지) => 링크
  • 위키피디아 - Lock (computer science) => 링크
  • 큰돌의 터전 - 데이터베이스의 데드락과 해결방법 | deadlock => 링크
  • RealMySQL 8.0 1권 - 4.2.5 자동 데드락 감지(104페이지) => 링크
profile
기술에 대한 고민과 배운 것을 회고하는 게임 서버 개발자의 블로그입니다.

0개의 댓글