[TIL 2021.08.10] 잠금 타임아웃Lock timeout과 교착 상태Deadlock

Kyu·2021년 8월 10일
0

TIL

목록 보기
212/322

데이터베이스 첫걸음

잠금 타임아웃(Lock timeout)과 교착 상태(Deadlock)

MySQL(InnoDB) 기준으로 set innodb_lock_wait_timeout = 초단위;
명령어로 lock wait timeout 시스템변수를 설정 할수있다.

이때 만약에
트랜잭션A가 갱신을 했고, 트랜잭션B가 트랜잭션A가 갱신을 한 레코드에 갱신을 하려고 하면 wait가 발생하고 지정한 시간이 지나면 Lock timeout이 발생하고 다음과 같은 에러가 뜬다.
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
이것이 잠금 타임아웃(Lock timeout)이다.

  • 타임아웃 시스템변수는 1초 이상부터 설정가능
  • 타임아웃이 발생하는 경우 DBMS로부터 롤백되는 단위가 다를 때가있는데 트랜잭션 전체를 롤백하고 싶으면 명시적으로 rollback;을 해주던가 innodb_rollback_on_timeout을 설정해줘야한다.

만약에
테이블 a와 테이블 b가 있을때
트랜잭션 A는 a에, 트랜잭션 B는 b에 갱신을 한 상태일때
트랜잭션 A가 b에 갱신을 하려하고, 이상태로
트랜잭션 B가 a에 갱신을 하려고하면 교착 상태(Deadlock) 가 발생하면서 다음과 같은 에러가 뜬다.
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

교착상태가 발생하면 타임아웃과 다르게 상황이 진전될 기미가 보이지 않기 때문에, DBMS에서는 교착 상태를 독자적으로 검출해 교착 상태를 보고한다. MySQL 같은 경우에도 교착 상태가 일어나면 즉시 시스템에 영향이 작은 쪽의 트랜잭션을 트랜잭션 개시 시점까지 롤백한다. (p217)

이런 교착상태를 줄이려면 여러가지 대책이 필요하다. 요약하자면 다음과 같다

  1. 트랜잭션을 작은 단위로 교착상태가 적도로 자주 커밋한다.
  2. 정해진 순서로 테이블에 액세스하게 한다.
  3. 레코드 단위가 아니라 테이블 단위로 잠금을 획득해서 갱신을 하도록한다. 대신에 동시성은 떨어지지만 교착상태는 회피할 수있다.
  4. (MySQL InnoDB의 대책) 테이블에 적절한 인텍스를 추가해 쿼리가 이를 이용하게 한다. 인덱스가 사용되지 않는경우에는 필요한 행의 잠금이 아닌 스캔한 행 전체에 대해 잠금이 걸리게 된다. (p217)

클라/서버형 DBMS에는 타임아웃, 교착상태, 커넥션네트워크 오류, 일시오류 등 여러 트러블에 대한 대비책이 있어야한다.

해선 안될 트랜잭션 처리

  1. 오토커밋
  2. 긴트랜잭션

잡담

  • 80페이지만 더 보면 끝난다!!! 얏호!
  • 회사에서 타사 서비스와 연동하는 업무가 있는데 그 중 조그마한 부분을 맡아서 개인적인 목적으로 깃을 넣어서 함께 작업을 했다! 깃안쓰다가 쓰니까 너무너무너무 좋다 ㅠㅠ 마음에 안정을 주는 갓깃..
profile
TIL 남기는 공간입니다

0개의 댓글