오전 배포 직전, 개발팀에서 "DB 컬럼 하나 추가해야 합니다"라는 요청이 왔습니다. 간단해 보입니다. 그런데 그 테이블에 데이터가 5000만 건 있습니다. ALTER TABLE을 실행하는 순간 테이블에 Lock이 걸리고, 그 시간 동안 서비스의 모든 쓰기 요청이 블로킹됩니다. 몇 분이면 되는 줄 알았던 작업이 20분짜리 서비스 장애로 변할 수 있습니다.
이 모듈은 운영 DB 스키마 변경을 안전하게 처리하는 절차를 다룹니다. DDL 반영 전 체크리스트, Flyway 버전 관리, 대용량 테이블 무중단 변경, 롤백 준비까지 포함합니다.
- 1DDL 반영 전 체크리스트(백업/영향도/Lock 예상/롤백 스크립트)를 작성할 수 있다
- 2개발DB → 검증DB → 운영DB 순서의 반영 절차를 설명할 수 있다
- 3Flyway 마이그레이션 파일 명명 규칙을 이해하고 실행 이력을 확인할 수 있다
- 4pt-online-schema-change를 써야 하는 상황(대용량 테이블)을 판단할 수 있다
- 5잘못된 DDL 반영 후 롤백 스크립트를 실행하는 절차를 따라할 수 있다
DDL 반영 절차 — 반드시 이 순서로
개발 → 검증 → 운영 순서와 체크리스트
운영 DB에 DDL을 곧바로 적용하는 것은 위험합니다. 검증되지 않은 SQL이 운영 데이터를 망가뜨리거나 서비스를 중단시킬 수 있습니다. 항상 아래 순서를 따릅니다.
확대
1. 개발 DB (dev) → SQL 작성 및 기본 검증
2. 스테이징 DB (stg) → 운영과 동일한 데이터 구조로 검증
3. 운영 DB (prod) → 체크리스트 통과 후 최종 반영
운영 DB DDL 반영 전 체크리스트:
| 항목 | 확인 방법 | 필수 여부 |
|---|---|---|
| DB 백업 완료 | mysqldump 또는 스냅샷 확인 | 필수 |
| 영향 테이블 크기 확인 | SHOW TABLE STATUS | 필수 |
| Lock 예상 시간 산정 | 스테이징에서 실행 시간 측정 | 필수 |
| 접속 세션 수 확인 | SHOW PROCESSLIST | 필수 |
| 롤백 스크립트 준비 | UNDO SQL 작성 완료 | 필수 |
| 점검 시간 또는 트래픽 저점 확인 | 모니터링 대시보드 | 필수 |
# 영향 테이블 크기 확인
mysql -h db-server -u dba -p mydb -e "
SELECT
table_name,
table_rows,
ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'mydb'
AND table_name = 'users';
"
# 현재 접속 세션 수 확인
mysql -h db-server -u dba -p mydb -e "SHOW PROCESSLIST;"
mysql -h db-server -u dba -p mydb -e "SELECT COUNT(*) FROM information_schema.processlist;"
마이그레이션 하나가 운영에 안전하게 반영되기까지 — 작성부터 롤백까지 7단계
"컬럼 하나 추가"라는 한 줄 요청도, 운영 DB에 닿기까지는 정해진 단계를 거쳐야 안전합니다. 이 흐름을 알면 배포가 틀어졌을 때 "어느 단계까지 갔나"로 대응을 좁힐 수 있습니다 — 운영에 손대기 전이면 SQL만 고치면 되고, 반영 도중이면 취소·전환, 반영 후 이상이면 롤백입니다. 아래는 변경 SQL 한 개가 요청에서 반영(또는 안전한 롤백)까지 지나는 7단계입니다.
[변경 요청] "users에 phone 컬럼 추가"
│
① 작성 변경 SQL + 되돌릴 UNDO SQL을 한 쌍으로 (V10__add / V10__undo)
│ → 비가역 DDL(DROP·TRUNCATE)은 여기서 표시하고 백업을 전제로
│
② 개발 검증 dev DB에서 실행 → 문법·제약 충돌·결과 확인
│
③ 스테이징 실측 운영과 같은 행수 테이블에서 time으로 Lock·소요 시간 측정
│
④ 방식 판단 크기·Lock 영향으로 결정
│ 작으면 직접 ALTER / 크면 pt-osc·gh-ost (온라인)
│
⑤ 백업·시점 논리·물리 백업 확인 + 트래픽 저점/점검창 확보
│
⑥ 운영 적용 SQL 또는 온라인 도구로 반영
│ → 복제 지연·PROCESSLIST 감시
│
⑦ 검증 SHOW COLUMNS·DESCRIBE로 확인
▼ 이상 → 준비한 UNDO SQL로 롤백
[반영 완료 또는 안전 롤백]
각 단계에서 무슨 일을 하고, 틀리면 어떤 증상인가:
| 단계 | 하는 일 | 여기서 틀리면 |
|---|---|---|
| ① 작성 | 변경 SQL과 UNDO SQL을 짝으로 작성. DROP·TRUNCATE처럼 되돌릴 수 없는 DDL은 별도 표시하고 백업을 전제로 | UNDO 없이 진행 → 사고 시 되돌릴 방법이 없음(DROP COLUMN은 데이터까지 소실) |
| ② 개발 검증 | dev DB에서 실행해 문법·제약·결과 확인 | 여기서 실패하면 운영 이전이라 안전 — 문법 오류·제약 충돌을 이 단계에서 잡는다 |
| ③ 스테이징 실측 | 운영과 같은 행수에서 time으로 Lock·소요 시간 측정 | 실측 생략 → 운영에서 예상 못 한 수십 분 Lock으로 쓰기 전면 블로킹 |
| ④ 방식 판단 | 크기·Lock 영향으로 직접 ALTER인지 온라인 도구(pt-osc·gh-ost)인지 결정 | 대용량을 직접 ALTER → Waiting for metadata lock으로 서비스 장애 |
| ⑤ 백업·시점 | 논리/물리 백업 확인 + 트래픽 저점·점검창 확보 | 백업 없이 적용 → 롤백 SQL로도 못 살리는 데이터는 복구 불가 |
| ⑥ 운영 적용 | SQL·온라인 도구로 반영하며 복제 지연·PROCESSLIST 감시 | 복제 지연 방치 → replica에서 stale read, 청크 write가 부하 유발 |
| ⑦ 검증·롤백 | SHOW COLUMNS·DESCRIBE로 반영 확인, 이상하면 UNDO SQL 실행 | 검증 없이 완료 선언 → 부분 반영·인덱스 누락을 배포 후에야 발견 |
즉 "운영 반영 성공"은 세 가지가 모두 참이라는 뜻입니다 — 되돌릴 UNDO가 준비됐고(①), 예상 Lock 시간이 실측으로 확인됐으며(③④), 반영 후 스키마가 검증됐다(⑦). 문제가 생기면 이 단계 중 어디까지 갔는지로 대응이 갈립니다 — ④ 이전이면 아직 운영에 손대기 전이라 SQL만 고치면 되고, ⑥ 도중이면 진행 중 ALTER를 취소(완료 전이면 원상 복귀)하거나 온라인 도구로 전환하며, ⑦에서 이상이 드러나면 곧바로 UNDO SQL로 롤백합니다. 그래서 ①의 UNDO 준비와 ③의 실측이 나머지 전부를 좌우합니다.
DDL 실행과 확인
운영 DB에서 DDL 반영하는 방법
실제 DDL을 운영 DB에 적용하는 명령입니다. SQL 파일로 관리해서 실수를 줄이고, 적용 전후 스키마를 확인합니다.
확대
# 1. 백업 확인 (반드시 먼저)
ls -lh /backup/mydb_$(date +%Y%m%d)*.sql 2>/dev/null || echo "WARNING: 오늘 백업 없음"
# 2. DDL 파일 내용 최종 확인
cat /tmp/V10__add_user_phone_column.sql
# ALTER TABLE users ADD COLUMN phone VARCHAR(20) NULL AFTER email;
# 3. 스테이징에서 실행 시간 측정 (운영 전 반드시)
time mysql -h stg-db-server -u dba -p mydb < /tmp/V10__add_user_phone_column.sql
# 4. 운영 DB 적용
mysql -h db-server -u dba -p mydb < /tmp/V10__add_user_phone_column.sql
# 5. 적용 결과 확인
mysql -h db-server -u dba -p mydb -e "SHOW COLUMNS FROM users LIKE 'phone';"
# 6. 스키마 전체 확인
mysql -h db-server -u dba -p mydb -e "DESCRIBE users;"
롤백 스크립트 — 모든 DDL에 대응하는 UNDO SQL:
-- V10__add_user_phone_column.sql (적용)
ALTER TABLE users ADD COLUMN phone VARCHAR(20) NULL AFTER email;
-- V10__undo_add_user_phone_column.sql (롤백용)
ALTER TABLE users DROP COLUMN phone;
# 잘못 적용됐을 때 롤백
mysql -h db-server -u dba -p mydb < /tmp/V10__undo_add_user_phone_column.sql
mysql -h db-server -u dba -p mydb -e "DESCRIBE users;" # 컬럼 사라졌는지 확인
Flyway — DB 마이그레이션 버전 관리
Flyway 마이그레이션 파일 구조
Flyway는 SQL 스크립트를 버전 순서대로 실행하고 이력을 기록하는 도구입니다. "어느 환경에 어느 SQL까지 반영됐나"를 추적할 수 있어 환경 간 스키마 불일치를 방지합니다.
파일 명명 규칙:
V{버전}__{설명}.sql
src/main/resources/db/migration/ 구조입니다.
V1__create_users_table.sqlV2__create_orders_table.sqlV3__add_email_index.sqlV9__add_product_category.sqlV10__add_user_phone_column.sql
-- V10__add_user_phone_column.sql
ALTER TABLE users ADD COLUMN phone VARCHAR(20) NULL AFTER email;
CREATE INDEX idx_users_phone ON users(phone);
# Spring Boot + Flyway 마이그레이션 실행
# 애플리케이션 기동 시 자동 실행, 또는 수동 실행:
mvn flyway:migrate -Dflyway.url=jdbc:mysql://db-server:3306/mydb \
-Dflyway.user=dba -Dflyway.password=${DB_PASSWORD}
# 마이그레이션 이력 확인
mvn flyway:info
# 또는 DB에서 직접 확인
mysql -h db-server -u dba -p mydb -e "SELECT * FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 10;"
+--------------+---------+------------------------------+---------+---------------------+---------+
| installed_rank | version | description | success | installed_on | checksum|
+--------------+---------+------------------------------+---------+---------------------+---------+
| 10 | 10 | add user phone column | 1 | 2026-05-30 10:30:00 | 12345678|
| 9 | 9 | add product category | 1 | 2026-05-28 15:00:00 | 87654321|
대용량 테이블 무중단 변경
pt-online-schema-change — Lock 없는 ALTER
테이블 크기가 수천만 건 이상이면 일반 ALTER TABLE은 장시간 Lock을 유발합니다. pt-online-schema-change(pt-osc)는 이 문제를 해결하는 Percona 도구입니다. 원본 테이블을 사용하면서 백그라운드에서 새 테이블에 데이터를 복사한 뒤 atomic rename으로 교체합니다.
# pt-online-schema-change 설치
yum install percona-toolkit
# 또는
apt-get install percona-toolkit
# 기본 사용법 (컬럼 추가 예시)
pt-online-schema-change \
--alter "ADD COLUMN phone VARCHAR(20) NULL AFTER email" \
--host=db-server \
--user=dba \
--password=${DB_PASSWORD} \
--database=mydb \
--table=users \
--execute
# 실행 전 dry-run (실제 실행 없이 계획만 출력)
pt-online-schema-change \
--alter "ADD COLUMN phone VARCHAR(20) NULL AFTER email" \
--host=db-server --user=dba --password=${DB_PASSWORD} \
--database=mydb --table=users \
--dry-run
# 진행 상황 모니터링 (별도 터미널)
watch -n 5 "mysql -h db-server -u dba -p mydb -e 'SHOW TABLE STATUS LIKE \"_users_new\"'"
pt-osc 사용 판단 기준:
| 테이블 크기 | 권장 방법 |
|---|---|
| 100만 건 이하 | 일반 ALTER TABLE (Lock 몇 초) |
| 100만~1000만 건 | 트래픽 저점(새벽 2~4시)에 ALTER TABLE |
| 1000만 건 초과 | pt-online-schema-change 사용 |
실습
DDL 적용 전 영향받는 테이블의 크기와 현재 접속 세션을 확인합니다. 이 정보로 Lock 시간을 예측하고 작업 시간대를 결정합니다.
# 영향 테이블 크기 확인
mysql -h localhost -u root -p mydb -e "
SELECT table_name,
table_rows,
ROUND((data_length+index_length)/1024/1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'mydb' AND table_name = 'users';"
# 현재 진행 중인 쿼리 확인
mysql -h localhost -u root -p -e "SHOW FULL PROCESSLIST;" | grep -v "Sleep"
# 테이블 Lock 상태 확인
mysql -h localhost -u root -p -e "SHOW OPEN TABLES WHERE In_use > 0;"
+------------+------------+---------+
| table_name | table_rows | size_mb |
+------------+------------+---------+
| users | 52483201 | 4523.45 |
+------------+------------+---------+
mysql -h localhost -u root -p -e 'SELECT table_name, table_rows, ROUND((data_length+index_length)/1024/1024,2) AS size_mb FROM information_schema.tables WHERE table_schema=DATABASE() ORDER BY size_mb DESC LIMIT 10;'- table_rows 값을 먼저 확인 — 1000만 건 이하면 직접 ALTER 가능, 초과하면 Lock 시간이 수십 분 이상 걸려 서비스 영향. pt-online-schema-change 또는 gh-ost 사용 검토
- SHOW PROCESSLIST의 Time 컬럼에서 60초 이상 실행 중인 쿼리가 있으면 DDL 보류 — ALTER TABLE은 해당 트랜잭션이 끝날 때까지 대기하며 그 사이 신규 요청도 모두 블로킹됨
- 테이블 크기가 크고 장시간 쿼리도 있는 조합이면 — 새벽 트래픽 최저 시간대(보통 02:00~05:00)로 점검 일정을 변경하고 롤백용 UNDO SQL을 미리 준비한 뒤 진행
Flyway가 적용된 프로젝트라면 flyway_schema_history 테이블에서 현재 반영된 스키마 버전을 확인할 수 있습니다. 어느 환경에 어느 버전까지 적용됐는지 추적하는 데 사용합니다.
# flyway_schema_history 이력 확인
mysql -h localhost -u root -p mydb -e "
SELECT installed_rank, version, description, success, installed_on
FROM flyway_schema_history
ORDER BY installed_rank DESC LIMIT 5;"
# 아직 적용 안 된 마이그레이션 확인 (Spring Boot 프로젝트에서)
# 비밀번호는 ~/.flyway.conf(권한 600) 또는 Secret Manager 연동으로 주입합니다.
mvn flyway:info -Dflyway.url=jdbc:mysql://localhost:3306/mydb \
-Dflyway.user=flyway_app 2>/dev/null | grep "Pending\|Success"
+--------------+---------+---------------------------+---------+---------------------+
| installed_rank | version | description | success | installed_on |
+--------------+---------+---------------------------+---------+---------------------+
| 10 | 10 | add user phone column | 1 | 2026-05-30 10:30:00 |
| 9 | 9 | add product category | 1 | 2026-05-28 15:00:00 |
mysql -h localhost -u root -p mydb -e 'SELECT installed_rank, version, description, success, installed_on FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 5;'- flyway_schema_history에서 success=0인 행을 먼저 찾는다 — 있으면 해당 버전의 SQL이 실패한 것. Flyway는 실패한 마이그레이션이 있으면 이후 버전 적용을 거부함
- 최신 installed_rank의 version이 stg와 prod에서 다르면 환경 불일치 — 차이가 1~2개면 미적용 마이그레이션, 10개 이상이면 환경별 배포 절차가 분리된 것으로 즉시 원인 파악 필요
- success=0이 있고 실제 스키마 상태가 불일치한 조합이면 — DESCRIBE TABLE로 현재 스키마를 확인하고 실패 지점 이전 상태로 수동 복구 후 flyway repair 명령 실행
트러블슈팅
원인: 다른 세션이 테이블을 사용하는 상태에서 ALTER TABLE이 메타데이터 Lock을 기다리고 있습니다. ALTER 자체가 Lock을 걸기도 하지만, 이미 열린 트랜잭션이 있으면 그 트랜잭션이 끝날 때까지 대기합니다.
# 1. Lock 대기 상태 확인
mysql -e "SELECT * FROM information_schema.INNODB_LOCK_WAITS;"
mysql -e "SELECT r.trx_id waiting_trx, r.trx_mysql_thread_id waiting_thread,
b.trx_id blocking_trx, b.trx_mysql_thread_id blocking_thread
FROM information_schema.INNODB_LOCK_WAITS w
JOIN information_schema.INNODB_TRX b ON b.trx_id = w.blocking_trx_id
JOIN information_schema.INNODB_TRX r ON r.trx_id = w.requesting_trx_id;"
# 2. 블로킹 세션 확인 및 종료 (DBA 판단 후)
mysql -e "SHOW FULL PROCESSLIST;" | grep -v Sleep
# 장시간 실행 중인 세션 ID 확인 후
mysql -e "KILL <세션ID>;"
# 3. 즉시 대안 — ALTER 취소 후 pt-osc로 전환
# Ctrl+C 로 ALTER 취소 (완료 전이면 테이블 원상 복귀)
# pt-online-schema-change 사용
pt-online-schema-change \
--alter "ADD COLUMN phone VARCHAR(20) NULL AFTER email" \
--host=localhost --user=dba --password=${DB_PASSWORD} \
--database=mydb --table=users \
--execute --no-drop-old-table
재발 방지: 테이블 크기를 DDL 전에 항상 확인하고, 1000만 건 이상은 pt-osc를 기본으로 사용합니다.
원인: 롤백 스크립트가 준비되지 않은 상태에서 잘못된 DDL이 실행됐습니다. DROP COLUMN은 해당 컬럼의 데이터까지 삭제합니다.
# 즉각 조치 순서
# 1. 추가 변경 즉시 중단
# 더 이상의 DML(INSERT/UPDATE/DELETE) 최소화
# 2. 백업에서 해당 컬럼 데이터 복구 가능 여부 확인
mysqldump --no-create-info mydb users > /tmp/users_backup_check.sql
grep "phone" /tmp/users_backup_check.sql | head -5
# 3. 백업 DB에서 데이터 추출
mysql -h backup-db-server -u dba -p mydb -e "
SELECT id, phone FROM users LIMIT 10;"
# 4. 컬럼 재생성 후 백업 데이터 복구
mysql -h db-server -u dba -p mydb -e "
ALTER TABLE users ADD COLUMN phone VARCHAR(20) NULL AFTER email;"
# 백업 데이터로 UPDATE
mysql -h db-server -u dba -p mydb << 'EOF'
UPDATE users u
JOIN backup_users b ON u.id = b.id
SET u.phone = b.phone
WHERE b.phone IS NOT NULL;
EOF
# 5. 복구 건수 확인
mysql -h db-server -u dba -p mydb -e "
SELECT COUNT(*) FROM users WHERE phone IS NOT NULL;"
핵심 교훈: DROP COLUMN, DROP TABLE, TRUNCATE를 포함한 모든 DDL은 실행 전 UNDO SQL을 준비합니다. 백업이 없으면 DROP으로 삭제된 데이터는 복구 불가능합니다.
심화 — 온라인 DDL은 '긴 락'만 없앨 뿐이다
심화: pt-osc·gh-ost가 만능이 아닌 이유 — 전제와 한계
"pt-osc를 붙이면 무조건 무중단"이라고 믿으면, 정작 외래키가 걸린 테이블이나 복제 클러스터에서 사고가 납니다. 도구가 무엇을 없애 주고 무엇은 그대로 두는지를 알아야 안전합니다.
- 트리거 기반 vs binlog 기반: pt-osc는 원본에 트리거를 걸어 진행 중 변경을 따라 씁니다. 그래서 원본에 이미 애플리케이션 트리거가 있으면 충돌하고, 트리거 실행 오버헤드가 write에 얹힙니다. gh-ost는 트리거 대신 binlog를 읽어 이 제약을 피하지만, row 기반 binlog와 읽을 수 있는 복제 위치를 전제로 합니다.
- 외래키(FK)의 함정: pt-osc는 원본을 새 테이블로 rename하면서 자식 테이블의 FK를 다시 연결해야 합니다.
--alter-foreign-keys-method=rebuild_constraints는 자식 테이블을 다시 ALTER하므로 자식이 크면 또 오래 걸리고,drop_swap은 짧지만 순간적으로 FK가 없는 위험한 틈이 생깁니다. FK가 많은 스키마는 온라인 DDL의 가장 큰 함정입니다. - 복제 지연과 디스크: 청크 복사는 대량 write를 만들어 복제 지연(replica lag)을 키웁니다. pt-osc는
--max-lag로 스스로 속도를 늦추지만 그만큼 작업이 길어집니다. 또 새 테이블은 원본 크기만큼의 추가 디스크를 쓰므로, 1000만 건이 넘는 테이블이면 여유 공간을 먼저 확인하고 중간 실패 시 남는_table_new·_table_old잔여 테이블 정리까지 계획해야 합니다. - 한계 요약: 온라인 DDL은 '긴 락'을 없앨 뿐, 디스크·복제·FK·부하는 그대로 옮겨 옵니다. 그래서 실행 전
--dry-run으로 FK 처리 방식과 단계를 확인하고, 트래픽 저점에 복제 지연을 모니터링하며 돌리는 절차는 여전히 필요합니다.
상황: orders에 컬럼을 추가하려 pt-osc를 --execute로 돌렸습니다. orders를 외래키로 참조하는 order_items(수천만 건)가 있습니다. 진행률이 좀처럼 오르지 않고, 읽기 복제본의 지연이 수백 초까지 치솟아 앱이 stale 데이터를 보여 줍니다.
원인: pt-osc가 orders를 새 테이블로 교체하면서 order_items의 외래키를 재구성해야 하는데, 기본이 rebuild_constraints라 대용량 order_items를 다시 ALTER하느라 시간이 폭증했습니다. 동시에 청크 복사 write가 복제 지연을 밀어 올렸습니다. 실행 전 --dry-run으로 외래키 처리 방식을 확인하지 않은 것이 근본 원인입니다.
진단: SHOW FULL PROCESSLIST에서 pt-osc가 자식 테이블 ALTER 단계에 머물러 있는지 확인합니다. 복제 상태(SHOW REPLICA STATUS의 Seconds_Behind_Source)와 pt-osc 로그의 --max-lag throttle 메시지를 함께 봅니다. 자식 테이블 크기를 information_schema로 재확인하면 rebuild 비용이 왜 큰지 드러납니다.
해결: 이런 케이스는 트리거 없이 binlog 기반으로 도는 gh-ost를 검토하거나, 트래픽 저점에 외래키를 잠시 제거→변경→재생성하는 계획으로 전환합니다. --max-lag·--chunk-time으로 부하를 제한해 복제 지연을 억제하고, 자식 테이블 크기를 사전에 산정해 예상 시간을 잡습니다. 재발 방지의 핵심은 대용량·FK 테이블에서는 반드시 --dry-run으로 외래키 처리 방식과 단계를 먼저 확인하는 것입니다.
실제 업무에서 이 지식이 쓰이는 상황:
DB 스키마 변경은 인프라 엔지니어와 DBA가 협업하는 대표적인 작업입니다.
1. 정기 배포 시 DDL 반영 절차:
# 배포 당일 오전 체크리스트 실행
# ① 백업 확인
ls -lh /backup/$(date +%Y%m%d)/mydb*.sql
# ② 스테이징에서 DDL 실행 시간 측정
time mysql -h stg-db -u dba -p mydb < /deploy/V10__add_column.sql
# ③ 운영 적용 (트래픽 저점 시간 또는 점검 시간)
mysql -h prod-db -u dba -p mydb < /deploy/V10__add_column.sql
# ④ 검증
mysql -h prod-db -u dba -p mydb -e "DESCRIBE users;" | grep phone
2. Flyway로 스키마 버전 관리: 인프라 팀이 여러 환경(dev/stg/prod)의 스키마 버전을 추적합니다.
# 각 환경의 현재 Flyway 버전 확인 스크립트
for env in dev stg prod; do
echo "=== $env ==="
mysql -h ${env}-db -u dba -p${DB_PASS} mydb \
-e "SELECT MAX(version) as current_version, MAX(installed_on) as last_migration FROM flyway_schema_history WHERE success=1;"
done
3. 긴급 롤백 판단: DDL 문제는 애플리케이션 재배포로는 해결되지 않습니다. 스키마 자체를 되돌려야 합니다. 그래서 롤백 스크립트는 배포 패키지와 함께 항상 준비해야 합니다.
명령어·단축키 빠른 참조
이 모듈에서 다룬 DDL 반영·마이그레이션 명령을 안전 옵션과 함께 모았습니다. 운영 반영 전 "예" 열 순서를 그대로 밟으면 됩니다.
| 명령어/단축키 | 용도 | 자주 쓰는 예 |
|---|---|---|
mysqldump | DDL 전 논리 백업(필수) | mysqldump mydb users > users_$(date +%F).sql |
SHOW TABLE STATUS | 행수·크기로 Lock 시간 예측 | information_schema.tables에서 size_mb 조회 |
SHOW FULL PROCESSLIST | 실행 중 세션·장시간 쿼리 확인 | Time 60초 이상 쿼리 있으면 DDL 보류 |
time mysql < file.sql | 스테이징에서 DDL 시간 측정 | 운영 반영 전 Lock 시간 산정 |
ALTER TABLE | 소용량 직접 스키마 변경 | ALTER TABLE users ADD COLUMN phone VARCHAR(20) NULL |
pt-online-schema-change | 대용량 무중단 ALTER(1000만 건↑) | --alter "ADD COLUMN ..." --execute --max-lag=1 |
pt-osc --dry-run | 실행 전 계획·외래키 처리 확인 | --alter-foreign-keys-method 사전 점검 |
mvn flyway:migrate | Flyway 마이그레이션 반영 | mvn flyway:info (Pending/Success 확인) |
mvn flyway:repair | 실패·체크섬 불일치 이력 복구 | 실패 마이그레이션 정리 후 재적용 |
SELECT … flyway_schema_history | 환경별 반영 버전 추적 | ORDER BY installed_rank DESC LIMIT 5 |
KILL <세션ID> | metadata lock 유발 세션 종료 | 블로킹 세션 확인 후 KILL 12345 |
관련 모듈로 더 깊이:
- JDBC Connection Pool과 DB 장애 분리 실무 — DDL을 반영할 대상인 DB 연결·커넥션 풀 구조
- WAR/JAR/정적파일 배포와 배포 스크립트 작성 — DDL 반영과 애플리케이션 배포를 한 절차로 묶는 법
- 파일/설정/DB/인증서 롤백 절차와 판단 기준 — 스키마 롤백을 포함한 전체 롤백 전략 설계
다음 모듈에서는 이렇게 DB까지 준비된 상태에서 애플리케이션을 배포하는 전체 배포 구조와 스크립트를 다룹니다.