분류

트랜잭션·락·DB 운영 · 2쪽

락 대기, 격리 수준, @Transactional 함정, 스키마 변경과 VACUUM 처럼 운영 중인 DB 에서 터지는 문제를 모았어요.

21편 · 마지막 글 2026.08.12

DB 운영 글

21편 중 13–21

  1. 대량 DELETE 가 복제를 무너뜨린다

    오래된 로그를 정리하려고 천만 행을 한 번에 지웠더니, 복제 지연이 수십 분으로 뛰고 디스크는 오히려 늘었어요. 대량 삭제가 왜 사고가 되는지와 안전하게 나눠 지우는 법을 정리했어요.

    5분#DB
  2. 서머타임에 배치가 두 번 돌거나 건너뛴다

    한국은 서머타임이 없지만, 해외 결제사 리포트를 받는 순간 1년에 두 번 배치가 건너뛰거나 두 번 돌아요. 로컬 시각을 믿으면 생기는 정산 사고와 안전하게 스케줄 잡는 법을 정리했어요.

    5분#DB
  3. REPEATABLE READ, MySQL 과 PostgreSQL 은 다르다 — 격리 수준

    같은 REPEATABLE READ 인데 MySQL 과 PostgreSQL 에서 동작이 달라요. DB 를 옮기면 코드는 그대로인데 결과가 바뀌는 이유죠. 이름은 같고 보장은 다른 격리 수준을 DB 별로 비교했어요.

    5분#DB
  4. 운영 중 인덱스 추가 — CREATE INDEX CONCURRENTLY 로 쓰기 막지 않기

    운영 중에 인덱스 하나를 추가했더니 몇 분 동안 주문이 안 들어왔어요. 스테이징에선 1초 만에 끝났던 작업이에요. 쓰기를 막지 않고 인덱스를 만드는 방법과 그때 조심할 점을 다뤄요.

    5분#DB
  5. pgbouncer transaction 모드가 깨는 prepared statement·SET

    커넥션을 아끼려고 pgbouncer 설정 하나를 바꿨더니 앱이 가끔 이상해져요. 다시 보내면 성공해서 재현도 안 되고요. 세션에 걸어 둔 설정이 조용히 사라지는 이유와 피하는 법을 정리했어요.

    5분#DB
  6. PostgreSQL 이 쓰기를 거부할 때 — XID wraparound 막기

    어느 날 PostgreSQL 이 모든 쓰기를 거부해요. 디스크도 CPU 도 멀쩡한데 DB 가 스스로 문을 닫은 거예요. 이게 왜 일어나는지, 몇 주 전에 미리 알아채려면 무엇을 봐야 하는지 정리했어요.

    6분#DB#PostgreSQL#VACUUM
  7. ALTER TABLE 이 기다리면 뒤에 줄이 선다 — 락 큐와 lock_timeout

    1초면 끝나는 컬럼 추가 마이그레이션을 돌렸는데 서비스 전체가 몇 분간 멈췄어요. 마이그레이션은 시작도 못 했는데요. 락을 기다리는 줄이 평범한 조회까지 막는 구조를 풀어 드려요.

    5분#DB#DDL#마이그레이션
  8. MySQL SELECT FOR UPDATE, 인덱스가 없으면 스캔한 행이 전부 잠긴다

    재고를 잠그는 쿼리가 개발 DB 에선 멀쩡했는데, 프로모션 날 주문 API 가 통째로 멈춰요. 서로 다른 상품을 산 사람끼리 왜 서로를 기다리는지 풀어 드려요.

    5분#DB#인덱스#락
  9. MySQL 의 utf8 은 UTF-8 이 아니다

    닉네임에 이모지를 넣었더니 500 에러가 나요. 인코딩은 분명 utf8 로 맞췄는데도요. MySQL 의 utf8 이 이름과 달리 진짜 UTF-8 이 아닌 사연과 고치는 순서를 정리했어요.

    6분#DB#MySQL#인코딩