Windows 서버에서 MariaDB를 운영하다 보면 어느 날 갑자기 응답이 느려지거나, 애플리케이션에서 Lock wait timeout exceeded, Deadlock found 같은 메시지가 터지면서 장애로 이어지는 경우가 있습니다. 이 글은 “지금 서비스가 돌아가는 중”이라는 전제에서, 영향 최소화(online) 관점으로 원인 진단 → 즉시 완화 → 백업/복구 → 재발 방지 점검 순서로 정리한 실전 절차입니다.
핵심은 “잠금을 없애는 것”이 아니라, 어떤 트랜잭션이 어떤 잠금을 오래 쥐고 있는지를 빠르게 찾고, 안전한 범위에서 풀어주는 것입니다.
1) 증상 분류: 지금 겪는 게 lock인지부터 확인
락 이슈는 대체로 아래 형태로 나타납니다. 먼저 증상을 분류하면 불필요한 조치를 줄일 수 있습니다.
- 특정 API/배치만 느림: 특정 테이블/쿼리에서 row lock 경합 가능성이 큽니다.
- 전체가 느려짐: 커넥션이 대기 상태로 쌓이면서 “연쇄 대기”가 발생했을 수 있습니다.
- 에러가 명확: 애플리케이션 로그에 lock wait timeout / deadlock 문구가 직접 찍힙니다.
- CPU는 낮은데 처리량이 급감: 실행이 아니라 “대기”가 병목인 전형적인 패턴입니다.
온라인 환경에서는 원인 파악 전에 성급히 재시작부터 하면, 같은 트랜잭션 패턴이 다시 들어와 재발하거나 복구 시간이 더 길어질 수 있습니다.
2) 영향 최소화 진단: 대기 중인 트랜잭션과 ‘범인’ 세션 찾기
가장 먼저 보고 싶은 건 “누가 잡고 있고(holding), 누가 기다리는지(waiting)”입니다. Windows에서도 MariaDB 클라이언트(mysql)로 접속해 확인합니다.
1) 현재 프로세스/대기 확인
가능하면 전체를 보되, 운영 중에는 긴 쿼리/대기만 빠르게 훑는 게 좋습니다.
- SHOW FULL PROCESSLIST로 Sleep이 아닌 쿼리, 오래 도는 쿼리, Locked/Waiting 관련 상태를 확인
- 애플리케이션 커넥션 풀에서 같은 계정으로 수백 개가 대기 중이면, DB 원인 + 앱 재시도 폭주가 겹쳤을 가능성
2) InnoDB 잠금 내부 상태 확인
InnoDB의 잠금은 프로세스리스트만으로는 원인이 흐릿할 때가 있어, 내부 상태를 함께 봅니다.
- SHOW ENGINE INNODB STATUS 결과에서 LATEST DETECTED DEADLOCK, TRANSACTIONS, LOCKS 섹션 확인
- 특정 테이블/인덱스가 반복적으로 등장하면 해당 경로가 병목
3) “긴 트랜잭션”이 있는지 확인
잠금 문제의 80%는 결국 “오래 열린 트랜잭션”에서 시작합니다. 특히 Windows 환경에서 스케줄러 작업(배치)이나 서비스 프로세스가 트랜잭션을 열어둔 채 예외 처리로 빠져버리면 쉽게 재현됩니다.
- 오래 지속되는 트랜잭션(분 단위 이상)이 있는지
- 같은 세션이 계속 갱신/삭제를 붙잡고 있는지
- 대량 작업이 커밋 없이 한 번에 진행되는지
3) 즉시 완화(online): 재시작보다 먼저 할 수 있는 안전한 조치
서비스 영향 최소화 관점에서, 아래 순서로 “작게” 개입하는 편이 안전합니다.
- 1순위: 범인 세션만 정리
- 대기열을 만든 원인이 명확한 경우, 해당 세션(커넥션)만 종료하는 것이 재시작보다 충격이 작습니다.
- 종료 전, 그 세션이 어떤 앱/호스트에서 왔는지(Host, User) 확인해 재발 경로를 같이 잡습니다.
- 2순위: 대량 작업을 “작게 쪼개기”로 전환
- 배치/정리 작업이 원인이라면, LIMIT로 나누거나(예: 1,000~10,000 단위) 커밋 주기를 짧게 해서 잠금 보유 시간을 줄입니다.
- 가능하면 운영 피크 시간대에는 쓰기 작업(UPDATE/DELETE/ALTER)을 피합니다.
- 3순위: 애플리케이션 재시도(리트라이) 폭주 완화
- DB에서 lock wait가 나면 앱이 즉시 재시도하며 더 큰 경합을 만드는 경우가 있습니다.
- 일시적으로 재시도 간격(백오프)이나 동시 실행 수를 낮추면 DB가 회복할 시간을 벌 수 있습니다.
가능하면 “DB 재시작”은 마지막 카드로 남겨두세요. 재시작은 확실히 잠금을 끊어주지만, 원인이 쿼리/트랜잭션 설계에 있으면 동일 증상이 곧바로 재발합니다.
4) 백업/복구 절차: lock 이슈 직후 안전하게 상태 보존하고 복구하기
잠금으로 장애가 난 직후에는 “우선 풀고 끝”이 아니라, 원인 분석을 위한 상태 보존과 데이터 안전을 같이 챙기는 게 중요합니다. 아래는 운영 중 영향 최소화를 우선한 흐름입니다.
A. 장애 직후(온라인) 상태 보존
- DB 상태 캡처: SHOW FULL PROCESSLIST, SHOW ENGINE INNODB STATUS 결과를 파일로 저장(시간 포함)
- 에러 로그 보존: MariaDB error log와 애플리케이션 로그의 동일 시간대 구간을 함께 보관
- 대상 테이블/쿼리 식별: 반복 등장하는 테이블과 쿼리 패턴을 기록
B. 온라인 백업(가능하면)으로 ‘사후 복구 옵션’ 확보
- 서비스가 간신히라도 동작 중이면, 논리 백업(mysqldump)은 락/부하를 유발할 수 있어 신중합니다.
- 가능한 선택지는 “부하가 낮은 시간대에” 백업을 돌리거나, 백업 범위를 문제 테이블 중심으로 최소화하는 것입니다.
- 백업 도중 대기/락이 다시 악화되면 즉시 중단하고, 먼저 원인을 완화한 뒤 재시도합니다.
C. 복구(재시작/롤백/재처리) 판단 기준
- 단일 세션 종료로 회복: 가장 선호. 앱 오류 영향도도 상대적으로 작습니다.
- 트랜잭션 꼬임/대량 대기 고착: 세션 정리로도 회복이 안 되면, 계획된 재시작을 고려하되 재발 방지 조치를 함께 진행
- 데이터 정합성 우려: 장애 시점에 비정상 종료가 있었다면, 재기동 후 테이블 체크/애플리케이션 재처리(리컨실리에이션) 계획 필요
중요한 건 복구 자체보다, 복구 후에 동일한 락 경합이 다시 올라오지 않도록 쿼리/인덱스/트랜잭션 경계를 손보는 것입니다.
5) 재발 방지 튜닝 포인트: “잠금 보유 시간”을 줄이는 쪽으로
온라인 영향 최소화 관점에서 가장 효과가 큰 건 “한 번에 처리량을 늘리기”보다 잠금을 쥐는 시간을 짧게 만드는 것입니다.
- 트랜잭션 범위 최소화: 여러 작업을 한 트랜잭션에 묶지 말고, 실패 가능성이 있는 외부 호출/파일 I/O를 트랜잭션 밖으로 분리
- 배치 작업 분할: UPDATE/DELETE를 작은 단위로 반복 처리(커밋 주기 짧게)
- 인덱스 점검: 조건절에 맞는 인덱스가 없으면 불필요한 범위 스캔이 늘어나 잠금 범위도 커질 수 있음
- 일관된 접근 순서: 같은 여러 테이블을 갱신한다면, 모든 코드 경로에서 테이블 접근 순서를 통일해 deadlock 가능성을 낮춤
- 격리 수준/락 대기 정책: 기본값을 무작정 바꾸기보다, 특정 작업의 락 대기 시간이 과도한지부터 확인
deadlock은 “나쁜 것”이라기보다 동시성 시스템에서 자연스럽게 생길 수 있는 현상입니다. 다만 deadlock이 잦아졌다면 대개 트랜잭션이 길거나, 같은 자원을 서로 다른 순서로 잡고 있거나, 인덱스가 부실한 쪽을 먼저 의심하는 게 맞습니다.
6) 운영 점검 리스트(현장용): 지금 바로 확인할 것들
- 증상 확인
- 에러 로그/앱 로그에 lock wait timeout 또는 deadlock이 있는가
- 특정 테이블/기능에만 집중되는가
- 원인 세션/쿼리
- SHOW FULL PROCESSLIST에서 오래 실행/대기 중인 세션이 무엇인가
- SHOW ENGINE INNODB STATUS에 반복 등장하는 테이블/인덱스가 있는가
- 긴 트랜잭션(커밋이 늦는 흐름)이 있는가
- 즉시 완화
- 범인 세션만 종료할 수 있는가(재시작 대신)
- 배치/정리 작업의 동시 실행 수, 작업 단위를 줄일 수 있는가
- 앱 재시도 폭주를 일시 완화(백오프/동시성 제한)할 수 있는가
- 백업/복구
- 장애 시점의 프로세스/innodb status/로그를 저장했는가
- 온라인 백업을 돌릴 때 부하/락을 더 악화시키지 않는 계획이 있는가
- 재시작이 필요하다면, 재발 조건(배치 재가동/트래픽 유입)을 통제할 수 있는가
- 재발 방지
- 문제 쿼리에 맞는 인덱스가 있는가(특히 WHERE/JOIN 조건)
- 트랜잭션 범위가 과도하게 넓지 않은가
- 여러 테이블 업데이트 시 접근 순서가 일관적인가
마무리
Windows에서 MariaDB 잠금 이슈가 생겼을 때는 “재시작으로 일단 살린다”보다, 대기/보유 트랜잭션을 빠르게 특정하고 작은 조치로 풀어주는 것이 운영 중 영향 최소화에 더 유리합니다.
한 번이라도 lock wait timeout이나 deadlock이 장애로 번졌다면, 그 순간의 상태(SHOW ENGINE INNODB STATUS/로그/프로세스)를 남겨두는 것만으로도 다음 대응 속도가 크게 빨라집니다.