IT/DB 운영 26

Postgres 18 async I/O, io_uring 켜봤다가 반나절 날린 이야기

지난주에 우리 팀 리포팅 DB — Postgres 18로 올린 지 두 달째다 — 에 async I/O를 본격적으로 켜보자고 결심했다. Postgres 18에서 들어온 AIO가 sequential scan, bitmap heap scan, vacuum 같은 read-heavy 작업에서 최대 2~3배까지 빨라진다는 얘기가 릴리스 노트부터 pganalyze 벤치까지 여기저기 도배돼 있었고, 우리 리포팅 워크로드는 딱 그 형태였다. NVMe 붙은 i4i 계열, 대형 seq scan이 하루에도 수백 번 도는 그런 곳.결과부터 말하면 결국 io_method = worker로 되돌렸고, io_uring은 우리 환경에서 못 썼다. 왜 그렇게 됐는지 시간 순서대로 남겨둔다.첫 번째 삽질: `io_method=io_uri..

IT/DB 운영 2026.08.18

PgBouncer transaction pool에서 prepared statement 쓰기, 이젠 진짜 된다

Django, SQLAlchemy, node-postgres 같은 걸 쓰다가 PgBouncer 뒤에 붙이면 한 번쯤 만나는 에러가 있다. prepared statement "S_1" does not exist. 그 순간 대부분의 팀은 두 갈래로 갈라진다. 하나는 transaction pool을 포기하고 session pool로 내리는 쪽. 다른 하나는 앱단에서 prepared statement를 아예 끄는 쪽. 어느 쪽이든 성능을 반쯤 반납하는 거였다.PgBouncer 1.21에서 transaction pool에서도 protocol-level prepared statement를 쓸 수 있게 됐고, 최근 1.22가 나오면서 DISCARD ALL / DEALLOCATE ALL까지 다뤄져서 실무에서 쓰기가 훨..

IT/DB 운영 2026.08.18

PostgreSQL 논리 복제 슬롯, failover에서 살리는 법 (17 이후 실전 가이드)

논리 복제(logical replication)를 실제 운영에서 굴려본 사람이라면 한 번쯤 겪는다. HA 구성 잘 짜놨고, 프라이머리가 죽어도 스탠바이로 넘어가는 건 문제 없다. 근데 넘어가고 나서 CDC 파이프라인이 조용히 멈춰있다. Debezium 로그를 보면 "replication slot does not exist". 이유는 단순하다 — 복제 슬롯은 프라이머리에만 있었고, 스탠바이가 승격되는 순간 그 슬롯의 커밋 위치 정보가 통째로 증발한 거다.PostgreSQL 17에서 failover slots가 정식으로 들어왔고, 18에서 1년치 버그 패치가 얹혀서 이제 프로덕션에서 쓸만해졌다. 이번 글은 그 세팅을 처음부터 끝까지 밟아보는 실무 가이드다. RDS를 쓰는 팀에게도 해당되는 이야기가 있어서 뒤..

IT/DB 운영 2026.08.09

PgBouncer vs pgcat vs Supavisor, 2026년에 뭘 쓸까

Postgres 커넥션 풀러 얘기다. 15년 넘게 PgBouncer가 사실상 표준이었다. 근데 최근 몇 년 사이에 pgcat(Rust), Supavisor(Elixir) 같은 대안이 부쩍 눈에 띈다. 우리 팀에서도 지난 분기에 새 서비스용 풀러를 뭘로 갈지 논의가 있었고, 실제로 각각을 조금씩 다르게 굴려봤다. 이 글은 그 경험을 바탕으로 세 개를 나열해보는 글이다. "이거 써라"는 아니고, 어떤 상황에서 뭐가 맞더라 정도의 정리.세 개가 각자 어떤 물건인가PgBouncer는 여전히 단일 바이너리에 2MB짜리 프로세스로 커넥션 수천 개를 받아낸다. 트랜잭션 모드 풀링, 심플한 config, 문서화 잘 되어 있고, 튜닝 노하우가 인터넷에 널려있다. 단점은 단일 스레드라는 것. CPU 하나를 다 태우면 그게..

IT/DB 운영 2026.08.06

Redis vs Valkey, 지금 갈아탈 때인가

작년 여름부터 팀 회의 때마다 반복해서 나오는 주제가 있다. "우리도 Valkey로 옮겨야 하지 않을까요?" 처음에는 라이선스 이슈 정도로 가볍게 봤는데, 2026년이 되니 이야기가 좀 달라졌다. AWS ElastiCache 기본값이 Valkey로 바뀌고, Aiven이 15,000대 서버를 옮겼다는 얘기까지 들리니 무시하기 어려워졌다.우리 팀은 캐시 클러스터 40여 대, 세션 스토어 12대, 그리고 실시간 랭킹용 소규모 Redis 몇 개를 굴리고 있다. 각각의 워크로드가 조금씩 달라서 하나의 결론을 내기가 애매했다. 이 글은 그동안 실무자로서 두 진영을 비교하면서 정리한 내용이다. 결론부터 말하면 "무조건 갈아타야 한다"도 아니고 "굳이?"도 아니다.라이선스, 이게 진짜 이슈였다Redis 7.2까지는 B..

IT/DB 운영 2026.08.02

PgBouncer transaction pool로 갈아탄 다음 날 새벽에 벌어진 일

session pooling에서 transaction pooling으로 갈아탄 지 이틀째 되던 날 새벽 2시 반, 폰이 울렸다. 결제 API의 P99가 800ms를 넘겼다는 알람. 침대에서 노트북을 여는 순간 이미 뭐가 원인인지 짐작이 갔다. prepared statement 다.왜 갈아탔나우리 팀에서 PgBouncer는 오래전부터 session pool로 돌고 있었다. 백엔드가 Django였고, connection이 세션 내내 유지되는 게 편했다. 그런데 최근 서비스가 커지면서 DB 커넥션 수가 감당이 안 됐다. RDS 앞단 PgBouncer에 client는 3천이 넘게 붙는데 server 커넥션은 200~300 정도로 억제하고 싶었다. session pooling에서는 client 한 명이 붙어있는 ..

IT/DB 운영 2026.07.31

Redis Sentinel이 failover를 안 해준 새벽 이야기

지난달 새벽 2시 43분에 알람이 울렸다. Redis primary 노드가 죽었다는 알람이었는데, 문제는 Sentinel이 자동 failover를 안 해줬다는 거였다. 5분 정도 쳐다보다가 결국 손으로 promote 시켰다. 서비스는 그 사이 캐시 미스 폭탄으로 DB 커넥션 풀이 다 터졌고, 우리 팀 슬랙에는 "왜 자동 failover가 안 되냐"는 질문이 5개쯤 쌓였다.이 글은 그 원인을 찾아가는 과정과, 결국 뭐가 문제였는지에 대한 회고다.처음 봤을 때우리 구성은 이랬다. Redis 6.2에 primary 1대, replica 2대, Sentinel 3대. Sentinel은 Redis 노드와 같은 VM에 얹혀있었다 (사실 이게 나중에 원흉으로 밝혀진다). quorum은 2로 설정돼 있어서 이론상 Se..

IT/DB 운영 2026.07.20

Postgres autovacuum, 내부는 어떻게 도는가

autovacuum 이야기를 하면 대개 두 가지 반응이 나온다. 하나는 "그거 알아서 도는 거 아니냐"고, 다른 하나는 "우린 껐다"다. 둘 다 나름의 이유가 있는데, 결국 내부 동작을 잘 모르는 상태에서 기본값과 부딪히다 지친 사람들의 흔적이다. 사실 autovacuum은 상당히 정교한 스케줄러와 워커 조합이고, 각 파라미터가 어디에 걸려서 동작하는지 알면 튜닝이 아니라 그냥 논리적인 조합 문제가 된다.우리 팀에서는 최근 300GB 규모의 이벤트 로그 테이블에서 autovacuum이 "안 도는 것처럼" 보이는 문제를 파고들었다. 결론부터 말하면 안 돌던 게 아니라 계속 시작했다가 중간에 죽고 있었다. 이 이야기를 하려면 결국 내부 흐름부터 짚고 가야 한다.launcher와 worker의 관계Postgr..

IT/DB 운영 2026.07.19

idle_in_transaction_session_timeout, 이거 하나로 커넥션 풀이 살아난다

오늘 알게 된 건 아니고 예전부터 알고는 있었는데, 최근에 신규 서비스 튜닝 도우면서 "아 이거 진짜 모르는 팀 아직도 많구나" 싶어서 짧게 남긴다.PostgreSQL 파라미터 중에 idle_in_transaction_session_timeout 라는 게 있다. 이름 그대로 트랜잭션 시작해놓고 아무것도 안 하는 세션을 강제 종료해주는 값이다. 기본값은 0, 즉 비활성이다.왜 이게 문제가 되나전형적인 시나리오는 이렇다.앱에서 BEGIN 날려서 트랜잭션 열어놓고, 그 사이에 외부 API 호출한다. 근데 그 API가 30초쯤 걸린다. 그동안 이 커넥션은 어떤 상태냐면 idle in transaction. 살아는 있는데 아무 일도 안 하고, 그런데 락은 잡고 있을 수도 있다.이런 커넥션이 몇 개 쌓이면 pg_s..

IT/DB 운영 2026.07.16