데이터베이스 스키마는 실제로 어디에 사는가
이 글의 내용
이 서비스가 하는 모든 것은 버전 관리 안에 있습니다. 적어도 코드는 그렇습니다. 그것이 도는 데이터베이스는 표 32개이고, 그 가운데 15개는 저장소 어디에도 정의가 없습니다 — CREATE TABLE도, 스키마 파일도, 아무것도 없습니다. 덤프는 32개를 구조까지 온전히 되돌립니다. 저장소가 담고 있지 않은 것은 그 구조의 두 번째 독립된 사본입니다.
그 수치는 살아 있는 데이터베이스를 저장소의 파일 736개, 5,671,710자와 견주어 나왔습니다. 어림이 아닙니다.
스키마 절반이 어떻게 사라지는가
부주의가 아니고, 바로 그 점이 적어 둘 값어치를 만듭니다. 낱낱의 단계는 저마다 합당했습니다.
지금 코드가 있기 전에 만들어진 표는 결코 적히지 않았습니다. 그때는 그냥 거기 있었으니까요. 그 뒤에 온 표는 마이그레이션 스크립트로 왔고, 그 스크립트들은 저장소에 있습니다 — 정의 17개가 거기서 옵니다. 나중에 더한 칸은 프롬프트에 친 한 줄짜리 ALTER TABLE로 더했습니다. 1초 걸리는 변경에 스크립트를 쓰기보다 치는 편이 빨랐기 때문입니다.
인덱스가 최악입니다. 인덱스는 무언가 느릴 때, 느린 바로 그 순간에 더해지고, 문제를 곧바로 해결합니다. 남는 산물이 없고, 검토할 것도 없고, 잊었을 때 실패하는 것도 없습니다. 여기 보조 인덱스 서른둘 가운데 열하나가 바로 그 까닭으로 존재하고 어디에도 기록되어 있지 않습니다.
카운터 자체를 담은 표는, 166,438줄짜리인데, 저장소에 정의가 없는 열다섯 가운데 하나입니다.
실제로 무엇이 망가지는가
많지 않습니다. 딱 한 순간까지는 그렇습니다. 데이터베이스를 덤프에서 되돌릴 때입니다.
덤프는 구조를 지니고 있으므로 곧바로 되돌리는 것은 괜찮습니다. 위험은 표를 되돌리는 대신 다시 만드는 모든 길에 있습니다 — 다른 기계로 옮기기, 고른 표만 가져오기, 스크립트로 하나를 다시 만들기. 데이터는 돌아오고 인덱스는 조용히 돌아오지 않습니다. 실패하는 것은 없습니다. 조회는 옳은 답을 돌려줍니다. 다만 더 오래 걸리고, 원인은 보이지 않습니다. 그 인덱스가 무엇이었는지의 유일한 기록이 이제 그것을 갖고 있지 않은 기계이기 때문입니다.
이름을 붙여 둘 값어치가 있는 실패 방식이 그것입니다. 빠진 인덱스는 오류를 내지 않고, 느린 정답을 냅니다. 그에 대한 시험은 없습니다. 시험이 통과하기 때문입니다.
그동안 우리가 하는 일
스키마는 오늘 저장소에 없고, 그것이 상태에 대한 정확한 설명입니다. 갖춘 것은 완전한 해결보다 좁고, 실제로 값을 치르게 하는 경우를 덮습니다:
파괴적인 무엇을 하기 전의 덤프, 웹 디렉터리 밖에 보관합니다. 가정이 아니라 적어도 한 번 실제로 수행해 본 되돌리기. 그리고 되돌릴 때마다 확인하는 짧은 목록, 곧 돌아가는 데이터베이스에만 있는 것으로 알려진 인덱스 목록입니다 — 기계에 어떤 인덱스가 있는지 물을 수 있고, 그 답을 지난번에 물었을 때와 견줄 수 있기 때문입니다.
일반적인 판본은 데이터베이스보다 넓게 적용됩니다. 시스템의 일부가 돌아가는 시스템에만 존재한다면, 그것의 두 번째 사본은 없습니다. 어떤 기반 시설에 대해서든 물어볼 값어치가 있는 물음은 백업이 되어 있느냐가 아니라, 기계가 사라지면 저장소에서 다시 지을 수 없는 것이 무엇이냐입니다. 여기서 답은 표 열다섯과 인덱스 열하나이고, 확인하는 데 오후 한나절이 들었으며, 미지수가 아니라 목록입니다.
덧붙임: 2026년 9월
이 글이 올라간 지 닷새 뒤에 작업 디렉터리를 커밋했습니다. 파일 26개와 4,058줄이고, 그 가운데 8월 28일부터 9월 1일 사이에 쓰였으며 그때까지 돌아가는 기계에만 있던 마이그레이션 스크립트 열하나가 있습니다. 그것이 쉬운 절반이었습니다 — 쓰였으나 기록되지 않았던 코드 말입니다.
2026년 9월 1일에 같은 방식으로 측정을 되풀이했습니다. 살아 있는 데이터베이스를 git이 추적하는 모든 것과 견주었습니다.
| 표 | 46 | 저장소에 CREATE TABLE가 있는 것 30개, 없는 것 16개 |
| 보조 인덱스 | 43 | 저장소의 코드가 만드는 것 32개, 돌아가는 데이터베이스에만 있는 것 11개 |
| 마이그레이션 스크립트 | 109 | 버전 관리 안에 |
중요한 숫자는 움직이지 않았습니다. 8월 27일에 보조 인덱스 열하나가 돌아가는 데이터베이스 말고는 어디에도 없었습니다. 9월 1일에도 여전히 열하나입니다. 그사이에 인덱스 열하나가 더해졌고, 그 하나하나가 마이그레이션 스크립트와 함께 왔습니다. 습관은 바뀌었고, 빚은 그대로입니다.
그 열하나는 표 다섯에 놓여 있습니다 — 카운터, 언어, 참조, 제외 목록, 이벤트 로그입니다. 다섯 모두 지금 코드보다 앞서고, 바로 그래서 그것들에 대해서는 아무것도 적히지 않았습니다. 지금 파일을 쓴다는 것은 몇 해 전에 프롬프트에 친 것을 돌아가는 서버에서 되짚어 복원한다는 뜻입니다.
그러니 8월의 입장은 그대로입니다. 스키마는 여전히 저장소에 없고, 표를 되돌리는 대신 다시 만드는 되돌리기는 여전히 아무 말 없이 인덱스 열하나를 떨어뜨릴 것입니다. 바뀐 것은 더 좁습니다. 그 뒤로 더해진 모든 것은 파일을 남겼습니다.