
들어가며
백엔드 서비스 개발을 하다보면, 테이블 스키마를 변경해야 하는 일이 발생합니다. Column 을 추가하거나, PK 를 바꾸거나, 인덱스를 추가하는 등이요. 그냥 ALTER TABLE … ADD COLUMN 으로 추가하면 될까요? 데이터베이스 수업 시간에 스키마 변경은 비싼 비용, O(n) 연산이라고 공부했습니다. 이제 과연 맞을지, 어떻게 Column 을 추가해야 할지 학습하고 적용해봅니다.
DDL 알고리즘 (Native DDL)
테이블이 짠 하고 변경된다고 생각하기 쉽지만, 다양한 방법이 있습니다.
- Metadata-Only Operation (MySQL 기준, ALGORITHM=INSTANT)
- Full Table Rewrite (MySQL 기준, ALGORITHM=COPY)
- In-Place Rewrite (MySQL 기준, ALGORITHM=INPLACE)
Metadata-Only Operation
- Table 의 Row 하나하나를 변경하지 않고, 메타데이터만 변경합니다.
- 기존 Row 의 물리적 레이아웃을 바꾸지 않을 때만 사용할 수 있습니다. 끝에 Column 을 하나 추가하거나, DEFAULT 값을 변경하거나, 테이블 이름을 변경하거나.
- O(1) 연산입니다. 즉시 처리됩니다.
- Column 을 하나 추가하고, SELECT 했을 때 값이 없으면 DEFAULT 를 반환합니다.
- PostgreSQL 11+, MySQL 8.0+, SQLite 에서 지원합니다.
- 기존 Row 형식을 바꿔야 하는 경우, 다음 두가지 방법을 사용합니다.
Full Table Rewrite
- 가장 고전적인 방식입니다.
- 기존 테이블을 유지하지 않고, 새 테이블을 만들어 전체 데이터를 다시 쓰고, 마지막에 Swap 하는 방식입니다.
- 데이터 전부를 읽고, 데이터 전부를 다시 쓰기 때문에, 디스크 I/O 가 매우 큽니다.
- 일시적으로 디스크가 2배 필요합니다.
- Lock 이 장시간 발생합니다. 스키마 정합성을 유지하기 위해서 Lock 을 겁니다.
In-Place Rewrite
- 기존 Row 형식을 바꿔야 하는 경우 사용합니다.
- in-place 란, 추가 메모리 공간을 만들지 않고, 기존 공간에서 직접 수정하는 것을 의미합니다. 즉, COPY 하지 않고 수정한다는 의미를 강조한 이름입니다.
- Column 삭제, Column 을 테이블 중간에 추가, Column 타입 변경, 인덱스 생성 등.
- 테이블 전체를 새로 복사하지는 않고, 내부 데이터를 재작성합니다.
- Online DDL, 즉 DDL 수행 중에도, DML 이 실행 가능합니다. 다시 말하면, ALTER TABLE 중에, UPDATE, INSERT 가 가능하다. 내부 데이터 수정 후, 최종적으로 보정 작업이 들어갑니다
- 테이블 전체 스캔을 하므로, 여전히 디스크 I/O 가 큽니다
- 여전히 짧은 Lock 이 발생합니다.
수동 제어 (OSC Tool)
Metadata-only Operation 으로 처리가 안 되고, 테이블 규모가 크고 운영 리스크가 크다면, 수동 제어가 필요합니다. ALTER TABLE 알고리즘에 의존하지 않고, 직접 제어합니다. 이를 OSC(Online Schema Change) Tool 이라고 합니다. Online 은 테이블 이관 중에 DML 이 가능하다는 의미입니다.
이런 조건을 완벽하게 충족할 수 있도록 합니다
- 무중단 배포할 수 있다
- 데이터 이관을 중간에 멈추거나, 가속화 하는 등 제어가 가능하다.
이런 과정을 거칩니다.
- 직접 새 테이블을 만들고
- 데이터를 chunk 단위로 조금씩 복사합니다.
- 동시에 발생하는 DML 을 추적합니다. 트리거나 binlog 를 활용합니다.
- 마지막에 기조 테이블과 SWAP 합니다.
- 임시 테이블 삭제합니다.
대표적 도구로 MySQL 은 gh-ost , pt-online-schema-change, PostgreSQL 은 pgrill, pg-osc 가 있습니다.
마치며
테이블 스키마 변경이 겉으로는 단순해보이지만, 굉장히 복잡한 작업입니다. DB 는 비용이 비싸므로, 신중하게 접근해야 합니다. 추가로, 정합성을 위해서 Lock 이 필요하므로, 세심하게 접근해야 무중단이 가능합니다. 오늘은 개괄적으로나마 스키마 변경 전략을 알아보았습니다.
'서버' 카테고리의 다른 글
| DB 를 Grafana 와 연동해서 대시보드 만들기 (1) | 2026.07.25 |
|---|---|
| Promtail, Loki, Grafana 로그 파이프라인 디버깅 기록 (0) | 2026.07.05 |
| Node.js 에서 Date 객체 Time Zone 다루기 (0) | 2026.02.09 |
| Characterization Test 로 안전하게 리팩터링 하기 (0) | 2026.02.07 |
| NestJS 철학 이해하기 1 : Layered Architecture (0) | 2026.02.01 |