35장. Migration을 expand-contract로 운영한다
risk_level 문자열을 별 code table과 key로 전환한다고 가정한다. 1차 release는 새 nullable key와 index를 추가하고 구 code가 계속 동작함을 확인한다. 2차는 작은 batch로 backfill하며 row count·null·오류를 checkpoint한다. 3차는 새 code가 dual-write하고 두 표현 불일치를 metric으로 낸다. 4차에서 읽기를 새 열로 전환하고 안정 기간 뒤 구 열을 제거한다.
DDL은 transaction 지원 여부, table lock, replica lag, disk 여유를 사전에 본다. migration을 모든 pod startup에 맡기지 않고 CI의 단일 Job으로 실행한다. Job 성공 뒤에도 old/new application contract test가 통과해야 deployment가 진행된다. checksum이 바뀐 기존 Flyway 파일을 production에서 고치지 않고 새 version migration을 만든다.
-- V018__expand_risk_level_key.sql: 삭제보다 추가를 먼저 한다.
alter table risk_item add column risk_level_key bigint;
create index concurrently if not exists ix_risk_item_level_key
on risk_item (risk_level_key) where risk_level_key is not null;
rollback 표에는 각 단계에서 code와 schema를 어디까지 되돌릴 수 있는지 적는다. destructive contract 단계 이후에는 restore나 forward fix가 필요할 수 있다. backup이 존재한다는 말 대신 test restore 시간과 RPO/RTO를 기록한다.