mysql Lock을 조심하자!

sunn_ni·2024년 6월 13일
0

트러블슈팅

목록 보기
5/5

Mysql에서 주의해야할 것 중 하나가 transaction이다.
회사 서버중에서 대량의 정기적인 작업을 할 때 큐를 만들어 큐를 순차적으로 돌리는 작업만 하는 서버가 따로 있다.

이때 이 큐에서 일을 하나씩 빼와서 순차적으로 한번에 작업을 돌리는데,
하나하나가 매우 중요한 작업이다보니 한 작업마다 transaction을 걸고 select lock을 걸어놓았다.
그렇게 나름 주의에 주의를 했건만..

.

어느날 갑자기 한 작업당 소요되는 시간이 1초면 걸리던게 최대 2분까지 랜덤하게 걸리는것이다..

결제쪽 관련 작업들에서만 관련 이슈가 발생해서 처음에는..
아 바뀐 PG사의 api의 처리가 좀 느린가? 했다.

*맞다.. 실제로도 느렸다. *

.
해당 PG사에도 문의를 했었는데 실제로 평균 소요시간이 그렇게 걸린다는 답변을 받았고, 한번에 몇개까지 처리 가능한지에 대한 답변이 왔었다.

그래서 결제관련해서 한번에 처리개수도 조절하고, DB의 connection time또한 조절을 해서 대응을 해봤다. 그럼에도 조절 전보다는 시간이 줄었지만 근본적인 해결방안은 아니라는 생각이 들었다.

근본적인 문제를 알기 위해 아래와 같이 조치를 취했다.

1. 로그남기기

대체 무엇이 문제인지 알 수가 없었고, 해당 이슈를 재현해보려 했지만 재현을 할 수가 없어서,
실 서버에 단계단계마다 로그를 빼곡하게 남게 수정을 해봤다.

그러다보니 어느 한 특정 구간에서만 시간 딜레이가 발견이 되었다.

2. 좀 더 빼곡하게 로그남기기

발견한 특정 구간에 db작업을 하는 코드 한줄한줄 아주 빼곡하게 분기마다 로그를 남게 설정을 해놨다.

3. 문제점 발견

문제점이 발견되었다. 특정 한 쿼리 부분에서 지나치게 db를 오래 잡고 있는것이었다.
아니 복잡한 쿼리문도 아니고 select문 한줄밖에 안되는 부분이였고 key도 잡혀있었는데 대체 뭐가 문제일까
코드를 유심히 살펴보다 깨달았다.

우리는 view테이블을 만들어 해당 view테이블에서 select하고 금전적인 부분이니 select lock을 걸었었는데..

그 view테이블이 다른 유저들도 공통적으로 참조하는 테이블 이 JOIN되어 형성되었던 것이다. 그래서 공통적으로 참조하는 테이블 또한 같이 LOCK이 걸려버렸다....

그렇다보니 모두가 대량의 정기적인 데이터가 해당 작업을위해 같은 테이블을 참조하는데, 한 작업당 lock을 걸어두었으니 거기서 db가 기다리고 기다리고 그러다가 처리속도가 늘어난 것이었다.

그나마 PG사에서 속도가 느리다는 답변을 받고 처리되는 속도를 늘렸기에 테이블 점유도 그나마(?) 순차적으로 진행되었어서 조절 후에 처리속도가 조금 빨라진 것이었다.

4. 문제점 해결

SELECT락을 걸때 특정 테이블만 LOCK을 걸 수 있게끔 쿼리문을 수정하였다.

for update of {테이블 이름};

이렇게 하면 JOIN되어있는 view테이블이건, 일반 조인 테이블이건 원하는 테이블만 Lock이 걸린다.

.
.
lock을 걸때 조심하도록하자..

profile
방황중인 서버개발자

0개의 댓글