본문으로 건너뛰기

14.5 운영 실수

DBA가 좋은 의도로 실행한 명령이 그대로 사고가 되는 경우가 있습니다. 운영 중에는 절대 하면 안 되는 명령이 따로 있습니다.

1. fsync = off

# 절대 금지
fsync = off

성능은 빠르지만 power loss가 나면 일관성 없는 페이지가 디스크에 남아 클러스터가 깨지기 쉽습니다. 검증 환경도 결국 운영처럼 다루게 되므로 처음부터 끄지 않는 편이 안전합니다.

2. autovacuum = off

# 절대 금지
autovacuum = off

dead tuple이 누적 → BLOAT 폭증 → XID wraparound 위험합니다. 일시 정지가 필요하면 테이블 단위:

ALTER TABLE big_table SET (autovacuum_enabled = false);
-- 변경 후 정기 점검에 vacuum 명시 호출

그래도 위험 — 임시 + 즉시 복원 권장합니다.

3. full_page_writes = off

# 절대 금지
full_page_writes = off

torn page 위험이 있습니다. 디스크의 부분 write가 페이지를 깨뜨릴 수 있습니다. CPU를 조금 아끼자고 데이터 손상을 감수할 가치는 없습니다.

4. pg_xlog/pg_wal 수동 삭제

# 절대 금지
sudo rm /var/lib/pgsql/17/data/pg_wal/000000010000000000000003A

디스크 풀로 긴급 정리를 하려다 낸 사고가 가장 흔합니다. WAL 파일 하나만 지워도 클러스터가 부팅되지 않습니다.

대응: archive·replication slot 점검 → 원인 해결합니다.

SELECT * FROM pg_replication_slots WHERE NOT active;
-- inactive 슬롯 drop으로 WAL 잘림

SELECT * FROM pg_stat_archiver;
-- archive_command 실패면 그것부터

5. base 디렉토리의 파일 수동 편집

# 절대 금지
sudo nano /var/lib/pgsql/17/data/base/16384/16389

데이터 파일을 OS 레벨에서 수정 = 페이지 손상 = corruption.

6. PGDATA tar로 백업

# 안티패턴 — 실행 중인 클러스터에서
tar cf - /var/lib/pgsql/17/data | gzip > backup.tar.gz

PostgreSQL이 읽기·쓰기 중인 파일을 tar로 묶으면 일관성 깨진 백업. 복원 시 부팅 안 됩니다.

대응:

  • 클러스터 정지 후 tar (cold backup)
  • 또는 pg_basebackup·pgBackRest

7. ROLE을 슈퍼유저로 만들기

-- 안티패턴
ALTER ROLE app_user SUPERUSER;

application이 슈퍼유저로 접속하면 사고 범위가 무한해집니다. SQL injection 한 줄로 클러스터 전체가 손상될 수 있습니다.

대응: 최소 권한 원칙. pg_monitor 같은 미리 정의된 역할 활용(9.1).

8. template1을 직접 수정

-- 안티패턴
\c template1
CREATE TABLE shared_data ...;

template1이 잘못되면 새 DB 생성 모두 실패. 명시적 의도가 아니면 절대 건드리지 말기.

대응: 정말 모든 DB에 객체가 필요하면 의도적으로 + 백업 확인합니다.

9. 같은 시간에 큰 vacuum + 큰 백업 + 큰 인덱스 빌드

점검 시간에 무거운 작업을 한꺼번에 몰아 실행하는 경우입니다. xmin horizon이 잡혀 vacuum이 무용지물이 되고 I/O도 폭증합니다.

대응: 시점을 분리합니다. 백업 도중에는 큰 ALTER를 하지 않습니다.

10. 트래픽 받는 primary에서 VACUUM FULL

-- 안티패턴
VACUUM FULL big_table;

ACCESS EXCLUSIVE를 잡아 모든 SELECT까지 차단합니다. 대용량 테이블은 수 시간 동안 멈춥니다.

대응: pg_repack(8.3)으로 운영 중 무중단 재구성합니다.

11. REINDEX 운영 중 (CONCURRENTLY 없이)

-- 안티패턴
REINDEX TABLE orders;

ACCESS EXCLUSIVE. 운영에서는 항상 CONCURRENTLY.

REINDEX INDEX CONCURRENTLY idx_orders_user_id;   -- PG 12+

12. ALTER TABLE의 함정

-- 안티패턴
ALTER TABLE big_table ALTER COLUMN col TYPE bigint;
-- 전체 테이블 rewrite — ACCESS EXCLUSIVE로 수십 분

다음은 rewrite 발생:

  • ALTER COLUMN ... TYPE (호환 안 됨)
  • ADD COLUMN ... DEFAULT volatile_func()
  • SET LOGGED/UNLOGGED

대응:

  • PG 11+의 ADD COLUMN ... DEFAULT constant는 rewrite 안 함 (메타데이터만)
  • 큰 타입 변경은 새 컬럼 추가 → 점진 마이그레이션 → 옛 컬럼 drop 패턴

13. unique constraint 추가가 운영 중

-- 안티패턴
ALTER TABLE orders ADD CONSTRAINT unique_order_no UNIQUE(order_no);
-- 큰 테이블에서 ACCESS EXCLUSIVE 오래

대응: CONCURRENTLY 인덱스 + ADD CONSTRAINT USING INDEX 패턴(8.3).

14. truncated pg_dump 사용

# 안티패턴 — 디스크 풀 시점에 dump 일부 잘림
pg_dump big_db | gzip > dump.sql.gz
# dump 도중 디스크 풀 — 잘린 파일이지만 에러 처리 안 됨

pipe로 출력하면 부분 dump가 만들어질 수 있습니다. 검증 없이 복원하면 row 누락.

대응:

  • pg_dump -Fc -f dump.dump (단일 파일 + 압축, 검증 가능)
  • pg_restore -l dump.dump | head 로 toc 확인

15. 백업 검증 없음

“백업이 있다"가 작동한다는 뜻이 아님(11.7). 운영자가 한번도 복원 시도 안 한 백업은 거의 무용.

대응: 분기 PITR 시뮬레이션.

16. 빠른 패치 적용

# 안티패턴 — 점검 없이 운영에 바로
sudo dnf update postgresql17-server
sudo systemctl restart postgresql-17

마이너 패치에도 드물게 regression이 있습니다.

대응: staging 먼저 → 운영. 백업 확인 후 적용합니다.

17. 모르는 SQL 실행

-- 인터넷에서 본 SQL을 production에서 실행
UPDATE pg_class SET ... ;

system catalog를 직접 수정하면 즉시 사고입니다. 옵티마이저·VACUUM·replication이 한꺼번에 망가집니다.

대응: 시스템 카탈로그는 읽기만. 변경은 공식 명령(ALTER 등)으로.

18. DROP USER만 하고 객체 정리 안 함

DROP ROLE alice;
-- ERROR: role "alice" cannot be dropped because some objects depend on it

대응:

REASSIGN OWNED BY alice TO svc_app;
DROP OWNED BY alice;     -- alice가 가진 객체 + 권한 제거
DROP ROLE alice;

19. unlogged table을 영구 데이터로

-- 안티패턴
CREATE UNLOGGED TABLE important_data (...);

unlogged = WAL 미작성. crash 시 truncate됨. 중요 데이터는 영구 손실.

대응: 임시 캐시·세션 데이터에만 사용합니다.

20. 비밀번호 평문 SQL 로그에

ALTER ROLE alice PASSWORD 'plain_text_secret';

log_statement = all이면 로그에 평문 비밀번호.

대응: \password alice (psql)이 challenge로 hash만 보냄.

사고 방지 체크리스트

사항권장
autovacuum항상 on
fsync항상 on
full_page_writes항상 on
pg_wal 수동 삭제절대 금지
데이터 파일 직접 편집절대 금지
VACUUM FULL on production금지 (pg_repack 사용)
application 슈퍼유저금지
점검 없이 운영 변경금지
백업 검증 안 함정기 시뮬레이션
운영 변경은 항상 되돌릴 수 있는 형태로. ALTER 전 백업 확인, 큰 작업 전 staging 검증, 의심스러우면 점검 시간에 한 번 더.

정리

fsync·autovacuum·full_page_writes는 절대 off로 두지 않고, pg_wal 수동 삭제나 데이터 파일 직접 편집도 하지 않습니다. VACUUM FULL·REINDEX·DROP은 운영 중 위험하므로 CONCURRENTLY나 pg_repack으로 대신합니다.

  • ALTER TABLE은 rewrite 여부 확인
  • 백업 검증·점진적 패치·최소 권한이 운영 표준

여기까지가 Part XIV 안티패턴입니다.