Jun Kang 👋

  • AI와 빅데이터로 건설업계의 디지털 혁신을 이끄는 (주)산군의 Jun Kang입니다. 대규모 데이터 처리, DB 최적화, 확장 가능한 시스템 구축에 관심이 많으며, 개발팀의 건강하고 지속 가능한 성장 문화를 문화를 만들어가고 있습니다.
  • 주요 관심사: Backend Development, Cloud Computing, DevOps, Database, AI, 개발 문화 형성

[PostgreSQL] 데드락은 어떻게 생기고 어떻게 읽나

지난 편이 한 줄로 늘어선 대기였다면, 이번 편은 대기가 원을 그리는 경우다. 서로를 기다리면 끝나지 않는다 트랜잭션 A가 행 1을 잠그고 행 2를 기다린다. 트랜잭션 B는 행 2를 잠그고 행 1을 기다린다. 둘 다 상대가 끝나야 진행할 수 있고, 상대는 내가 끝나야 진행할 수 있다. A: UPDATE accounts SET ... WHERE id = 1; -- 행 1 잠금 B: UPDATE accounts SET ... WHERE id = 2; -- 행 2 잠금 A: UPDATE accounts SET ... WHERE id = 2; -- B가 끝나길 대기 B: UPDATE accounts SET ... WHERE id = 1; -- A가 끝나길 대기 → 데드락 PostgreSQL은 이걸 막지 않는다. 대신 감지한다. 잠금 대기가 deadlock_timeout(기본 1초)을 넘으면 대기 그래프를 검사하고, 순환이 있으면 그중 하나를 끊는다. ...

9월 17, 2026 · Jun Kang

[PostgreSQL] ALTER TABLE 하나가 서비스를 멈추는 구조

컬럼 하나 추가하는 ALTER TABLE을 돌렸는데 서비스가 멈췄다는 이야기는 흔하다. 원인은 대개 ALTER 자체가 아니다. ALTER가 잠금을 기다리는 동안 그 뒤로 줄이 생기는 구조 때문이다. 잠금은 줄을 선다 PostgreSQL의 테이블 잠금은 여덟 단계가 있고, 서로 충돌하는 조합이 정해져 있다. 실무에서 기억할 건 두 가지면 된다. SELECT는 ACCESS SHARE를 잡는다. 거의 아무것과도 충돌하지 않는다. 대부분의 ALTER TABLE은 ACCESS EXCLUSIVE를 잡는다. 모든 것과 충돌한다. SELECT와도. 문제는 잠금 요청이 도착 순서대로 처리된다는 점이다. 앞의 요청이 못 받고 있으면 뒤의 요청도 기다린다. 뒤의 요청이 앞의 것과 충돌하는 종류라면 그렇다. ...

9월 16, 2026 · Jun Kang

[PostgreSQL] HOT update와 fillfactor — 죽은 튜플을 덜 만드는 쪽

앞선 세 편은 이미 생긴 죽은 튜플을 어떻게 치울 것인가에 대한 이야기였다. 이번 편은 반대쪽이다. 애초에 덜 만드는 방법. UPDATE가 인덱스까지 건드리는 문제 PostgreSQL에서 UPDATE는 새 버전을 쓰는 일이라고 1편에서 정리했다. 그런데 여기 딸려오는 비용이 하나 더 있다. 새 버전이 생기면 그 위치를 가리키도록 인덱스도 갱신해야 한다. 인덱스가 다섯 개인 테이블에서 한 행을 UPDATE하면, 힙에 새 버전 하나가 생기고 인덱스 다섯 곳에 엔트리가 추가된다. 그래서 갱신이 잦은 테이블은 힙보다 인덱스가 먼저 부푸는 경우가 많다. 그리고 인덱스 팽창은 조회 성능에 직접 영향을 준다. ...

9월 12, 2026 · Jun Kang

[PostgreSQL] VACUUM은 도는데 죽은 튜플이 안 줄어들 때

앞선 두 편에서 VACUUM이 공간을 반환하지 않는다는 것과 autovacuum 발동 조건을 다뤘다. 이번 편은 성격이 다르다. 설정을 아무리 만져도 해결되지 않는 경우가 있다. autovacuum은 정상적으로 돌고, 실행 기록도 계속 갱신되는데, 죽은 튜플만 계속 늘어난다. 이건 VACUUM이 게을러서가 아니라 지울 권한이 없어서다. 정리 기준선 VACUUM은 아무 죽은 튜플이나 지우지 않는다. 지워도 되는지 판단하는 기준선이 있다. 기준은 단순하다. 지금 실행 중이거나 앞으로 시작할 어떤 트랜잭션도 이 튜플을 볼 수 없는가. 하나라도 볼 가능성이 있으면 못 지운다. 지웠다가는 그 트랜잭션이 읽어야 할 데이터가 사라진다. ...

9월 11, 2026 · Jun Kang

[PostgreSQL] autovacuum이 큰 테이블에서 안 도는 이유

지난 편에서 죽은 튜플 비율이 계속 올라가고 있다면 설정을 봐야 한다고 썼다. 그 설정 이야기다. 결론부터 말하면, autovacuum의 기본값은 작은 테이블에 맞춰져 있다. 테이블이 커질수록 늦게 돌고, 늦게 도는 만큼 한 번에 할 일이 많아진다. 발동 조건 공식 autovacuum은 테이블마다 임계값을 계산해서, 죽은 튜플 수가 그 값을 넘으면 대상으로 잡는다. 발동 임계값 = autovacuum_vacuum_threshold + autovacuum_vacuum_scale_factor × 테이블 행 수 기본값은 이렇다. 파라미터 기본값 autovacuum_vacuum_threshold 50 autovacuum_vacuum_scale_factor 0.2 (20%) 지배적인 건 뒤쪽 항이다. 행 수에 곱해지기 때문이다. ...

9월 10, 2026 · Jun Kang