대니
danny's blog@dannywon_dev
발행 21 · 대기 84

1인 개발자. 클로드 코드를 팀처럼 굴린다. 매일 겪은 것만 쓴다.

버그와 함정

마이그레이션 번호 충돌 — AI 세션 두 개를 돌리다

duplicate key 에러로 죽은 뒤, 다른 세션에서 온 경고가 방금 고친 걸 되돌릴 뻔했다

올리는 명령을 실행했는데 이렇게 죽었다.

Applying migration 20260804000600_inquiry_reply_notification.sql...
ERROR: duplicate key value violates unique constraint "schema_migrations_pkey"
Key (version)=(20260804000600) already exists.

같은 저장소에서 AI 코딩 세션을 두 개 돌리고 있었다. 하나는 갤러리 쪽 화면, 하나는 관람객 쪽 화면. 폴더를 나눠 물리면 서로 안 밟으니 흔한 구성이다.

이 저장소는 변경 파일 이름을 20260804000600_설명.sql 처럼 날짜 + 손으로 붙인 순번으로 짓는다. 데이터베이스에 컬럼 하나를 추가하려고 파일을 만들면서, 그날의 다음 순번이 000600 이길래 그걸 썼다. 다른 세션이 몇 분 전에 똑같이 계산해서 이미 올려둔 뒤였다.

자동 생성이면 초 단위라 안 겹친다. 사람이(그리고 AI 가) 손으로 붙이면 둘 다 「다음 순번」을 똑같이 계산한다.

한 번 위험했던 건 에러 바로 위에 다른 파일의 Applying… 이 찍혀 있었다는 점이다. 뭔가 돌긴 돌았으니 넘어가기 쉽다. 실제로 내 변경은 하나도 안 올라갔다.

내 파일 번호를 000700 으로 옮기고 다시 올렸다. 확인까지 했다 — 그날 변경 8건이 전부 다른 번호인지, 만들려던 컬럼이 실제로 생겼는지 조회해서 눈으로 봤다.

경고가 도착했다. 내용은 맞고 방향은 반대였다

그 뒤에 경고가 하나 왔다.

마이그레이션 번호 충돌 — 그쪽 세션이 000600000700 으로 안 바꾸면, 올릴 때 「완료」라고 나오는데 실제로는 건너뛰어서 기능이 조용히 깨진다.

내용은 정확했다. 그런데 그 경고는 "충돌이 아직 안 풀렸다" 는 전제 위에 서 있었다. 나는 이미 내 것을 옮긴 뒤였다. 그 상태에서 시키는 대로 000600000700 으로 바꾸면 그때 내 것과 겹친다. 경고가 막으려던 사고가 경고를 따르는 순간에 일어난다.

두 세션은 서로의 현재 상태를 볼 수 없다. 각자 자기 시점 스냅샷으로 판단한다. 한쪽이 고친 걸 다른 쪽은 모르니, 같은 문제에 각자 처방을 내고 나중에 도착한 처방이 앞의 처방을 되돌린다. 사람 둘이 같은 파일을 동시에 고칠 때와 똑같은데, 병합 도구가 끼지 않아서 경고문의 형태로 온다는 게 다르다.

바꾼 것

  1. 고친 파일 맨 위에 「번호를 바꾸지 말 것」과 그 이유를 적었다. 원래 몇 번이었는지, 왜 옮겼는지, 되돌리면 뭐가 깨지는지. 다음에 이 파일을 여는 쪽이 "번호가 어긋났네" 하고 되돌리는 걸 막는 게 목적이다.
  2. 같은 내용을 공용 문서에도 한 단락 남겼다. 파일 하나에만 적으면 그 파일을 안 여는 쪽은 못 본다.
  3. 규칙으로 올렸다. 순번을 손으로 붙이는 저장소에서 충돌은 정상이고, 처방은 나중에 발견한 쪽이 자기 번호를 올린다(남의 번호는 안 건드린다). 끝나면 조회해서 눈으로 확인한다 — 번호가 안 겹치는지, 만들려던 게 실제로 생겼는지.

남긴 문장은 이거다.

세션끼리는 말을 못 한다. 파일과 문서가 유일한 통신 수단이다. 그러니 고친 자리에 「왜 이렇게 뒀는지」를 안 적으면, 다음 사람이 선의로 되돌린다.

← 목록으로