분류

개발 · 4쪽

DB·백엔드에서 실제로 터지는 문제와 USB·CD 굽기 교과서를 모았다. 느린 쿼리, 락과 트랜잭션, 장애와 확장, 배포와 관측은 태그로 나눠 찾는다.

96편 · 글 80 · 강 16 · 마지막 글 2026.09.28

교과서굽기 16강

개발 글

96편 중 37–48

  1. 쓰기 스큐, 각자는 옳은데 합치면 틀리다

    당직은 최소 한 명이 남아야 하는데, 두 사람이 동시에 해제를 눌렀더니 0명이 됐다. 검사도 있었고 트랜잭션도 걸려 있었다. 어디가 틀렸을까?

  2. 두 번 적립했는데 포인트가 한 번만 들어갔다

    포인트 적립 요청이 두 번 다 성공했는데 잔액에는 한 번만 들어가 있다. 에러가 하나도 없어서, 정산 때가 돼서야 알게 되는 종류의 사고다.

  3. 결제사가 느려졌을 뿐인데 우리 서비스가 멈췄다

    결제사가 조금 느려졌을 뿐인데 결제와 상관없는 화면까지 우리 서비스가 통째로 멈췄다. 원인은 트랜잭션 안에서 부른 외부 API 였다.

  4. JSON 컬럼은 스키마를 미루는 빚이다

    요구사항이 자주 바뀌어 JSON 컬럼에 속성을 몰아넣었더니, 1년 뒤엔 어떤 키가 들어 있는지 아무도 모른다. 조회도 느려졌다. 빨리 가려던 선택에 이자가 붙었다.

  5. 대량 적재 뒤에만 느려지는 쿼리, 범인은 낡은 통계

    데이터를 왕창 넣은 직후부터 쿼리가 느려졌다가 시간이 지나면 저절로 낫는다. 그래서 원인을 못 찾고, 다음 적재 때 똑같이 또 느려진다.

  6. 인덱스가 분명히 있는데 순차 스캔이 뜬다

    인덱스를 만들었는데 쿼리는 그대로 느리다. 개발 DB 에선 잘 타던 인덱스를 운영에서만 안 탄다. 그런데 옵티마이저가 인덱스를 안 쓰는 게 옳은 판단일 때가 생각보다 많다.

  7. 천만 행 DELETE 한 번에 복제가 수십 분 밀렸다

    오래된 로그를 치우려고 천만 행을 한 번에 지웠더니, 복제 지연이 수십 분으로 뛰고 디스크는 오히려 늘었다. 지우는 일도 결국 기록을 쓰는 일이었다.

  8. deleted_at 만 채웠더니 2년 뒤 테이블이 느려졌다

    지운 데이터를 실제로 지우지 않고 표시만 해 뒀더니, 2년 뒤 테이블의 70%가 삭제된 행이 됐다. 조회는 점점 느려지고, 탈퇴한 이메일로는 재가입도 막힌다.

  9. 서머타임 전환일에 크론 배치가 두 번 돈 이유

    한국은 서머타임이 없지만, 해외 결제사 리포트를 받는 순간 1년에 두 번 배치가 건너뛰거나 두 번 돈다. 상대가 자르는 하루가 그날만 23시간이거나 25시간이다.

  10. 같은 REPEATABLE READ 인데 DB 를 옮기니 결과가 달라졌다

    같은 REPEATABLE READ 인데 MySQL 과 PostgreSQL 에서 동작이 다르다. DB 를 옮기면 코드는 그대로인데 결과가 바뀐다. 이름은 표준이 정했지만 구현은 DB 마다 제각각이다.

  11. 안 쓰는 인덱스, 지워도 되는지 어떻게 알까

    느릴 때마다 인덱스를 하나씩 더하다 보니 테이블 하나에 열두 개가 됐다. 조회는 그대로인데 쓰기만 느려졌다. 그렇다고 사용 횟수 0 이라는 숫자를 그대로 믿으면 곤란하다.

  12. CREATE INDEX 하나에 주문이 몇 분 멈췄다

    운영 중에 인덱스 하나를 추가했더니 몇 분 동안 주문이 안 들어왔다. 스테이징에선 1초 만에 끝난 작업이다. 락은 그때도 똑같이 걸렸다. 아무도 못 느꼈을 뿐이다.