한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

게임 렉 백서 › L12 데이터베이스

오래 열린 트랜잭션 Long-running transaction / MVCC purge lag

원인 ID db-long-tx · 주 담당 게임개발팀·서버 개발 · 함께 인프라팀·DB 인프라

그림과 실험이 있는 원본 카드로 열기 →

트랜잭션 하나가 오래 열려 있으면 잠금을 계속 잡고 있고 DB가 옛 버전 데이터를 정리(purge)하지 못해 전체가 점점 느려집니다.

왜 트랜잭션을 연 채 다른 서버 응답을 기다리거나, 운영 중 주 DB에서 긴 집계 쿼리 실행 → 그러면 잡은 잠금이 풀리지 않고 정리해야 할 옛 버전 데이터가 계속 쌓임 → 화면에서는 그 행을 쓰는 기능 타임아웃, 몇 시간에 걸쳐 저장·조회가 전반적으로 느려짐

증상
입력 지연, 씹힘·롤백
요인
지연, 정체
누가 겪나
특정 기능만, 서버 전체
언제
오래 켜 둘수록, 가끔 무작위로
담당
주 담당 게임개발팀·서버 개발 · 함께 인프라팀·DB 인프라
게임개발팀 할 일
트랜잭션 안에서 네트워크 호출·사용자 입력 기다리지 않기, 집계 쿼리는 복제본에서.
인프라팀 할 일
오래 열린 트랜잭션 경보와 강제 종료, 집계용 복제본 제공, 언두 로그·죽은 행 증가 감시.
그래프에서는
서서히 오름 · 언두 로그 길이(History list length), 죽은 행 수
확인할 곳
MySQL은 INFORMATION_SCHEMA.INNODB_TRX의 trx_started로 가장 오래된 트랜잭션을 찾고, SHOW ENGINE INNODB STATUS의 TRANSACTIONS 섹션에 나오는 History list length(아직 정리하지 못한 언두 로그 양)를 봄. PostgreSQL은 pg_stat_activity의 xact_start와 state가 idle in transaction인 세션, pg_stat_user_tables의 n_dead_tup을 봄
이러면 맞음
몇 분~몇 시간 된 트랜잭션이 있고 그동안 History list length나 n_dead_tup이 계속 오르다 그 트랜잭션을 끝낸 뒤 정리(purge·VACUUM)가 돌면서 줄어듦
이러면 아님
오래된 트랜잭션이 없는데 전반적으로 느리면 체크포인트(db-checkpoint)나 디스크 쪽
확인 수단
인프라 도구로 확인(게임 코드 불필요)
더 알아보기
DB는 읽는 쪽이 고치기 전 모습을 볼 수 있도록 옛 버전을 남겨 둡니다(MVCC). 가장 오래된 트랜잭션이 끝나야 이 기록을 지울 수 있습니다. 트랜잭션 하나가 몇 시간 열려 있으면 MySQL은 언두 로그가, PostgreSQL은 VACUUM이 정리하지 못한 죽은 행(dead tuple)이 쌓입니다. SQL Server는 트랜잭션 로그가 줄지 않아 디스크를 채우기도 합니다.

출처

  1. InnoDB Multi-Versioning MySQL
    옛 버전을 볼 수 있는 트랜잭션이 남아 있으면 update 언두 로그를 버리지 못해 롤백 세그먼트가 커짐, 읽기만 하는 트랜잭션도 자주 커밋 권고
  2. Routine Vacuuming (PostgreSQL Documentation) PostgreSQL
    옛 행 버전은 다른 트랜잭션이 볼 수 있는 동안 지울 수 없고 오래 열린 트랜잭션은 끝내거나 세션을 종료해야 함
  3. Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
    idle_in_transaction_session_timeout: 트랜잭션을 연 채 쉬는 세션을 끊어 잠금을 오래 잡고 있지 못하게 함
  4. Troubleshoot a full transaction log (SQL Server Error 9002) Microsoft SQL Server
    오래 실행 중인 활성 트랜잭션이 트랜잭션 로그 정리를 막음
  5. The INFORMATION_SCHEMA INNODB_TRX Table MySQL
    TRX_STARTED: 트랜잭션 시작 시각
  6. Purge Configuration MySQL
    커밋된 트랜잭션의 언두 로그 목록(history list)을 purge가 정리, 밀린 양은 SHOW ENGINE INNODB STATUS의 TRANSACTIONS 섹션 History list length로 표시
  7. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    pg_stat_activity의 xact_start(트랜잭션 시작 시각)와 state(idle in transaction), pg_stat_user_tables의 n_dead_tup(죽은 행 추정치)

함께 보면 좋은 원인

같은 층: L12 데이터베이스

같은 증상(입력 지연)의 다른 층 원인

그림과 실험이 있는 원본 카드 보기