← 전체 글로 돌아가기

웹 개발

배포 전에 데이터베이스 제약을 꼭 확인하자

unique 제약이나 foreign key 때문에 배포 후 데이터 입력이 실패할 수 있다. 배포 전 마이그레이션을 검토해야 한다.

데이터베이스에 새로운 제약을 추가하고 배포했는데, 갑자기 에러가 난다고 하면 보통 기존 데이터가 그 제약을 만족하지 않아서다.

어떤 제약이 추가될 예정인지 확인하기

먼저 마이그레이션 파일을 본다.

# 대기 중인 마이그레이션 확인
pg_dump -s mydb | grep CONSTRAINT

# 또는 마이그레이션 파일 직접 확인
cat migrations/20240630_add_unique_email.sql

마이그레이션 파일에 ADD CONSTRAINT 또는 ADD UNIQUE 같은 명령이 있다면, 기존 데이터와 충돌할 수 있다.

기존 데이터가 제약을 만족하는지 확인하기

# unique 제약을 추가하려는데, 중복된 값이 몇 개나 있는가?
SELECT email, COUNT(*) as cnt FROM users GROUP BY email HAVING COUNT(*) > 1;

# NOT NULL 제약을 추가하는데, NULL 값이 있는가?
SELECT COUNT(*) FROM users WHERE age IS NULL;

# foreign key 제약을 추가하는데, 존재하지 않는 참조가 있는가?
SELECT user_id FROM orders WHERE user_id NOT IN (SELECT id FROM users);

만약 중복 이메일이 있다면, ADD CONSTRAINT UNIQUE (email) 명령은 실패한다.

마이그레이션을 두 단계로 나누기

한 번의 마이그레이션으로 제약을 추가하면, 기존 데이터 때문에 롤백될 수 있다. 대신 두 단계로 나눈다:

Step 1: 데이터 정리 (배포 전)

-- 중복된 이메일은 유지하고 나머지는 삭제
DELETE FROM users
WHERE id NOT IN (
  SELECT MIN(id) FROM users GROUP BY email
);

Step 2: 제약 추가 (배포)

ALTER TABLE users ADD CONSTRAINT unique_email UNIQUE(email);

이렇게 하면 기존 데이터도 보존하면서 제약을 추가할 수 있다.

테스트 환경에서 먼저 시뮬레이션하기

# 프로덕션 데이터를 테스트 환경에 복사
pg_dump production_db | psql test_db

# 마이그레이션 실행
python manage.py migrate

# 에러가 나는가?

에러가 난다면 원인을 파악해서 마이그레이션을 수정한다. 프로덕션에 배포하기 전에 test 환경에서 검증하는 게 중요하다.

롤백 계획 세우기

만에 하나 마이그레이션이 실패하면 어떻게 할지 미리 정한다.

# 데이터베이스 백업
pg_dump mydb > backup_20240630.sql

# 마이그레이션 실패 시 복구
psql mydb < backup_20240630.sql

또는 롤백 마이그레이션을 준비한다.

-- down 마이그레이션
ALTER TABLE users DROP CONSTRAINT unique_email;

배포 후 확인

# 제약이 실제로 추가됐는가?
SELECT constraint_name FROM information_schema.table_constraints
WHERE table_name = 'users';

# 새 데이터 입력이 제약을 지키는가?
INSERT INTO users (name, email) VALUES ('Test', '[email protected]');
INSERT INTO users (name, email) VALUES ('Test2', '[email protected]');
-- Unique violation 에러가 나야 정상

제약이 제대로 작동하는지 확인해야 나중에 버그를 줄일 수 있다.

앞으로의 마이그레이션 습관

제약을 추가할 때는:

  1. 기존 데이터가 제약을 만족하는지 먼저 확인
  2. 필요하면 데이터를 정리하는 마이그레이션을 먼저 실행
  3. 테스트 환경에서 검증
  4. 롤백 계획을 준비
  5. 배포 후 제약이 제대로 작동하는지 확인

이 단계들을 거치면 예상치 못한 배포 오류를 줄일 수 있다.