개발 slecs

배포 초기화 SQL의 updatedAt DEFAULT 누락으로 INSERT

목차

배포 초기화 SQL 스크립트에서 updatedAt 컬럼에 DEFAULT 값이 빠져 있어 INSERT가 전부 터지던 이슈를 잡아냈다.

배경: 배포 스크립트가 왜 자꾸 이상해지는가

admin-db-init.sql 같은 초기화 스크립트는 보통 "한 번만 실행하면 되는 것"으로 취급되다 보니, 애플리케이션 코드 대비 리뷰 밀도가 낮아지는 경향이 있다. 스키마 변경이 생겼을 때 ORM 엔티티나 마이그레이션 파일은 꼼꼼히 챙기면서, 초기화용 SQL은 "그냥 붙여넣기"로 끝내는 케이스가 생각보다 많다.

이번 케이스도 그런 흐름에서 터진 거였다. updatedAt 컬럼이 NOT NULL로 선언되어 있는데 DEFAULT 구문이 없었다. 로컬이나 개발 환경에서 별문제 없이 돌아가던 이유는, 해당 환경에서는 INSERT 시 애플리케이션 레이어가 항상 updatedAt 값을 채워서 넘겼기 때문이다. 그러나 초기화 스크립트에서 직접 INSERT를 날리는 순간, updatedAt에 값을 명시하지 않은 구문은 전부 DB에서 거절당했다.

문제의 패턴

-- 문제가 된 형태 (simplified)
CREATE TABLE admin_user (
  id          BIGINT       NOT NULL AUTO_INCREMENT,
  name        VARCHAR(100) NOT NULL,
  updatedAt   DATETIME     NOT NULL,   -- DEFAULT 없음
  PRIMARY KEY (id)
);

-- 이 INSERT는 실패
INSERT INTO admin_user (id, name) VALUES (1, 'system');
-- 수정 후
CREATE TABLE admin_user (
  id          BIGINT       NOT NULL AUTO_INCREMENT,
  name        VARCHAR(100) NOT NULL,
  updatedAt   DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);

-- 이제 정상 동작
INSERT INTO admin_user (id, name) VALUES (1, 'system');

ON UPDATE CURRENT_TIMESTAMP까지 붙이면 레코드가 갱신될 때도 자동으로 현재 시각으로 업데이트되니, 대부분의 updatedAt 컬럼 용도에 맞다. 경우에 따라 DEFAULT CURRENT_TIMESTAMP만 두고 업데이트는 애플리케이션에서 직접 관리하는 방식을 선택하기도 하는데, 어느 쪽이든 NOT NULL이면 반드시 DEFAULT가 있어야 한다는 건 기본 중의 기본이다.

이 류의 버그가 위험한 이유

구분 내용
발견 시점 배포 직전 또는 배포 중 — 가장 타이밍이 나쁜 순간
영향 범위 초기화 스크립트 전체 실패 → 서비스 기동 불가
재현 난이도 로컬/개발 환경에서는 재현이 잘 안 됨
롤백 비용 스크립트 단순 수정이지만, 이미 올라간 배포 환경이 있으면 꽤 번거로움

가장 짜증스러운 부분은 로컬 재현이 잘 안 된다는 점이다. 로컬 개발 환경은 이미 DB가 세팅된 상태에서 앱이 올라가는 경우가 많고, 초기화 스크립트를 깨끗하게 처음부터 돌려보는 흐름을 갖춘 팀이 생각보다 드물다. 결국 실제 배포 환경, 혹은 CI의 DB 초기화 단계에서 처음으로 터지게 된다.

팀에 남기는 체크포인트

이번 픽스를 계기로 팀 내에서 배포 스크립트 리뷰할 때 몇 가지를 챙기기로 했다.

  • NOT NULL 컬럼에는 반드시 DEFAULT가 있는지 확인
  • createdAt / updatedAt 패턴은 DDL 표준 스니펫을 팀 위키에 고정해 두고 복붙하도록 가이드
  • 초기화 SQL은 CI에서 빈 DB 컨테이너에 실제로 돌려보는 스텝을 두는 것이 가장 확실한 방어선
  • 마이그레이션 파일과 초기화 스크립트가 둘 다 존재하는 프로젝트라면, 스키마 변경이 생겼을 때 양쪽을 동시에 업데이트하는 걸 PR 체크리스트에 명시

배포 스크립트는 자주 안 건드리니까 손이 덜 가는 게 당연한데, 그래서 오히려 한 번 놓치면 타격이 크다. 애플리케이션 코드보다 더 꼼꼼하게 봐야 하는 이유가 거기 있다.

끝.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.