2024. 4. 14. 19:50ㆍ서버
야생의 버그가 나타났다.
오늘 코딩중 lock wait timeout exceeded try restarting transaction 이라는 에러를 마주쳤다.
문제의 sql 은 insert 작업이었고, 로그성 데이터를 남기는 sql 이었다.
해당에러를 구글에 검색하니 트랜잭션이 데이터베이스 리소스에 대한 락을 획득하려 시도하지만 어떤 트랜잭션이 해당 테이블을 잡고 놔주지 않아 발생한다고 나와있었다.
로컬에 서버를 띄워 개발하고있었고, sequelize logging 을 켜두고, 수상해보이는 코드마다 BP 를 찍어 확인하였다.
다행히 원인은 간단하였다. 바보같이 문제의 sql 을 실행하는 코드에 transaction 을 안 넣어 준 것이었다.
AS-IS
await this.loggingService.create({...logs})
TO-BE
await this.loggingService.create({...logs}, transaction)
만약 실서버 환경에서 버그 발생한다면
실서버에서 이런 버그가 발견한다면 저 트랜잭션이 물고있는 테이블들때문에 다른 요청들이 해당 테이블을 읽지거나 쓰지 못해 서비스가 멈출수도 있다.
매우 슬픈상황이니 예방 및 대처방법을 조사 해 보았다.
- 타임아웃 값 조정
- 읽기전용 데이터베이스 사용
- 모니터링 경고 설정
- 데드락이 걸린 쿼리 확인
타임아웃 값 조정
위처럼 트랜잭션이 데드락이 걸려 다른 작업들을 방해하고있다면 타임아웃값을 설정하여 해당 트랜잭션이 빠르게 종료되도록 하는것이 좋다.
Mysql 에선 기본값이 50초 이고, 다음 SQL 로 타임아웃을 설정할 수 있다.
SET GLOBAL innodb_lock_wait_timeout = 120; -- 초 단위로 시간 설정
PostgreSQL 에선 기본적으로 0 (무제한으로 기다림) 이고 다음과 같이 설정할 수 있다.
SET lock_timeout TO '30s'; -- 30초로 타임아웃 설정, 1분은 1min
읽기전용 데이터베이스 사용
만약 트랜잭션 데드락으로 인해 write 를 할 수 없는 상황이 오더라도 Read-only DB 를 사용하고있다면 서비스 전체가 먹통이 되진 않을것이다.
예시로 쇼핑몰에서 주문을 들어본다면.
1.상품정보 & 상품재고 조회 -> 2.주문생성 -> 3.결제 -> 4.상품 재고감소
로 이루어진 트랜잭션이 있다고 했을때 2, 3, 4 에서 데드락이 발생하면 유저들은 상품정보를 조회하는 행위조차 할 수 없을것이다.
하지만 읽기전용 데이터베이스를 사용한다면 write 과정에 데드락이 발생하더라도 서비스 전체로 영향이 퍼지지 않도록 예방할 수 있다.
모니터링 경고 설정
현재 우리회사에선 AWS RDS, Grafana 를 사용하고있으므로 AWS Cloud Watch, Grafana 이 두 환경에서 모니터링을 할 수 있는 방법을 조사했다.
cloud watch 에서 RDS 의 데드락을 직접적으로 모니터링할 순 없다. 따라서 RDS 의 데드락 에러 로그를 Cloud Watch 로 보내고, 해당 로그에 Cloud Watch 경보를 부착하면 된다.
이렇게하면 SNS 를 통해 이메일 알림을 받을 수 있고, 슬랙 웹훅으로 슬랙메시지도 보낼 수 있다.
2. Grafana 에서 알림 설정
일단 그라파나에 cloud watch 데이터소스를 추가 해 준다. (참고)
그 후 alert rule 으로 deadlock 을 감지해주면 된다.
데드락이 걸린 쿼리 확인
데드락이 걸리면 문제가 되는 코드를 찾아서 고쳐야하는데, 그러려면 어떤 쿼리에서 데드락이 걸렸는지 확인해야한다.
이부분은 직접 재현하기 너무 귀찮아 몇개의 레퍼런스를 남겨두어야 겠다. (위 상황은 회사코드에서 발생했으니...)
mysql 데드락 확인방법 show engine innodb status
후기
버그는 아무리 조심해도 결국 발생하게 되어있다고 생각한다.
특히 이번처럼 서비스 전체에 영향을 줄 수 있는 버그가 생길 수 도 있기에 평소 에러 로깅과 함께 예방 방안을 사전에 미리 마련 해 두어야 한다는것을 깨달았다.
'서버' 카테고리의 다른 글
Node.js 기반 백엔드 개발자의 Spring Boot 탐색 (2) | 2024.04.22 |
---|---|
서울 시위/행사 알리미 앱 고치기 - 타임아웃 (0) | 2023.10.19 |
Samba & Mega sync (1) | 2020.06.19 |