infra
Platform

모듈 맵

[Infra Ops] 파일/설정/DB/인증서 롤백 절차와 판단 기준

0 / 52 완료

펼치기
0 / 52 완료0%

Infra-ops · 41 / 52

[Infra Ops] 파일/설정/DB/인증서 롤백 절차와 판단 기준

롤백 판단 기준, 파일/설정/DB/인증서별 롤백 방법, 롤백 체크리스트까지 — 배포 실패 시 빠르게 원상복구하는 실무

🚨INCIDENT ALERT
HIGH

배포를 마치고 헬스체크를 돌렸더니 연속으로 실패합니다. 에러 로그에 ClassNotFoundException이 찍혀있습니다. 무언가 잘못됐습니다. 작업계획서에는 "롤백 기준: 헬스체크 실패"라고 써있었습니다. 롤백을 해야 합니다.

그런데 막상 롤백을 시작하려니 손이 떨립니다. WAR 파일 백업은 어디에 있었지? DB schema도 변경했는데, DB는 어떻게 되돌리지? 설정 파일도 바꿨는데, 그건 어떻게 롤백하지?

롤백은 미리 연습하고 절차를 문서화해둔 사람만 패닉 없이 실행할 수 있습니다. 롤백 체크리스트가 있으면 순서대로 따라가기만 하면 됩니다.

이번 챕터에서 배울 것
  • 1롤백 판단 기준(Go/No-Go)을 정의하고 상황에 따라 결정할 수 있다
  • 2WAR 파일과 설정 파일을 세트로 롤백하는 절차를 실행할 수 있다
  • 3DB 롤백의 세 가지 방법(UNDO SQL, 트랜잭션 ROLLBACK, 스냅샷)을 구분할 수 있다
  • 4인증서 롤백 후 Nginx/Tomcat 재시작까지 완료할 수 있다
  • 5롤백 불가 상황(DDL, 데이터 손상)을 인지하고 대안을 설명할 수 있다

롤백 판단 기준

💡개념

Go/No-Go 기준 정의하기

배포 직후 이상 징후가 보이는 상황에서 "조금 더 기다려볼까"와 "지금 당장 롤백해야 한다" 사이의 판단은 경험이 아니라 사전에 정해둔 기준에서 나와야 합니다. 기준 없이 버티다 보면 5분이 30분이 되고, 영향받는 사용자가 기하급수적으로 늘어납니다. Go/No-Go 기준은 감정이 아닌 숫자로 정의해야 하고, 배포 전에 팀 전체가 합의해야 실제 장애 상황에서 즉시 실행력을 가집니다.

롤백 판단 흐름과 유형별 롤백 절차

롤백은 감정이 아니라 기준으로 결정해야 합니다. "조금만 더 기다려볼까"를 반복하다가 장애 시간이 길어지는 상황을 방지하기 위해, 배포 전에 No-Go 조건을 명확히 정의해둡니다.

일반적인 No-Go(롤백) 조건:

로컬 터미널
# 조건 1: 헬스체크 연속 실패
# 배포 후 5분 안에 3회 연속 실패 시 즉시 롤백
for i in 1 2 3; do
  STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080/myapp/health)
  echo "Check $i: HTTP $STATUS"
  sleep 30
done
# → 3회 모두 200이 아니면 롤백

# 조건 2: 에러율 급증
TOTAL=$(grep "$(date +'%d/%b/%Y:%H:%M')" /var/log/nginx/access.log | wc -l)
ERRORS=$(awk '$9 ~ /^5/' /var/log/nginx/access.log \
  | grep "$(date +'%d/%b/%Y:%H:%M')" | wc -l)
# ERRORS/TOTAL > 0.05 (5%) → 롤백

# 조건 3: 핵심 기능 불가
# OOM 발생 → 즉시 롤백
grep -i "OutOfMemoryError" /opt/tomcat/logs/catalina.out | tail -3
# → 있으면 즉시 롤백

판단 기준 요약:

No-Go 조건판단 근거즉시 롤백 여부
헬스체크 3회 연속 실패서비스 기본 동작 불가즉시
500 에러율 5% 초과사용자 경험 심각 훼손즉시
OutOfMemoryError 발생서비스 불안정, 확산 위험즉시
핵심 기능(결제/로그인) 불가비즈니스 크리티컬즉시
응답시간 3배 이상 증가성능 저하, 연쇄 장애 가능검토 후 결정

WAR 파일 롤백

💡개념

파일 롤백 절차

배포 직후 500 에러가 쏟아집니다. Go/No-Go 기준에 따라 롤백을 결정했습니다. 그런데 정작 "어떻게 되돌리지?"를 그 자리에서 처음 생각하면 손이 떨립니다. 명령어를 잘못 치면 백업 파일까지 날릴 수 있습니다. 롤백 절차는 사고 전에 미리 문서화되어 있어야 하고, 복잡하지 않을수록 실수가 줄어듭니다.

WAR 파일 롤백은 가장 빈번하게 쓰이는 롤백 유형입니다. 절차가 단순하고 빠릅니다.

로컬 터미널
# 롤백 전 현재 상태 기록
echo "롤백 시작: $(date)" >> /opt/backup/rollback_log.txt
systemctl status tomcat >> /opt/backup/rollback_log.txt

# 1. Tomcat 중지
sudo systemctl stop tomcat

# Tomcat이 완전히 멈췄는지 확인
sleep 3
ps aux | grep tomcat | grep -v grep
# → 아무것도 안 나오면 완전 중지

# 2. 현재(실패한) WAR 삭제
# webapps 하위 폴더도 함께 삭제 (Tomcat이 자동 배포한 폴더)
sudo rm -rf /opt/tomcat/webapps/myapp
sudo rm -f /opt/tomcat/webapps/myapp.war

# 3. 백업 WAR 복사
BACKUP_WAR="/opt/backup/20260530_2200/myapp_current.war"
sudo cp $BACKUP_WAR /opt/tomcat/webapps/myapp.war

# 복사 확인
ls -lh /opt/tomcat/webapps/myapp.war

# 4. Tomcat 시작
sudo systemctl start tomcat

# 5. 기동 로그 확인 (에러 없는지 30초 관찰)
sudo tail -f /opt/tomcat/logs/catalina.out

설정 파일 롤백

💡개념

Nginx 설정 롤백

업스트림 주소를 잘못 변경한 Nginx 설정을 reload했더니 모든 요청이 502로 떨어졌습니다. 문제는 설정 파일 자체가 문법 오류 없이 잘못된 값을 담고 있었다는 점입니다. nginx -t는 통과했지만 실제 동작은 실패한 상황입니다. 이런 경우 이전 설정 파일로 즉시 복원하는 것이 가장 빠른 복구 경로입니다. 설정 변경 전 백업을 남기는 습관이 이 한 줄의 복원을 가능하게 합니다.

설정 파일 롤백은 항상 nginx -t 검증 후 적용합니다. 잘못된 설정으로 reload하면 Nginx가 이전 설정으로 계속 동작하지만, restart하면 서비스 중단이 발생할 수 있습니다.

로컬 터미널
# 현재 설정 파일 백업 (롤백 전 현재 상태 보존)
sudo cp /etc/nginx/conf.d/myapp.conf \
  /etc/nginx/conf.d/myapp.conf.failed_$(date +%Y%m%d_%H%M)

# 이전 설정 파일 복원
BACKUP_CONF="/opt/backup/20260530_2200/myapp.conf"
sudo cp $BACKUP_CONF /etc/nginx/conf.d/myapp.conf

# 설정 검증 (반드시 먼저)
sudo nginx -t
# 출력 예시:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful

# 검증 통과 후 무중단 reload
sudo systemctl reload nginx

# 롤백 후 확인
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost

nginx -t 실패 시에는 절대 reload하지 않습니다. 설정 파일을 다시 확인하거나, 직전 백업 파일을 찾아서 대체합니다.

롤백 판단 기준 — 언제 롤백하고 언제 핫픽스하는가

DB 롤백

💡개념

DB 롤백 세 가지 방법

배포와 함께 ALTER TABLE을 실행했는데 서비스에 문제가 생겼습니다. WAR 파일은 이전 버전으로 되돌렸지만, 스키마 변경은 이미 적용된 상태입니다. 이전 코드가 새 컬럼을 모르니 오류가 계속 납니다. DB 롤백은 단순히 파일을 복사하는 것이 아니라, 데이터 변경 여부에 따라 접근 방법이 완전히 달라집니다. 세 가지 상황별 방법을 미리 알아두어야 실제 장애에서 당황하지 않습니다.

DB 롤백은 파일 롤백보다 훨씬 복잡합니다. 배포 이후 실제 사용자 데이터가 쌓였을 수 있기 때문입니다.

방법 1: UNDO SQL (스키마 변경만 되돌리기)

배포 시 ALTER TABLE이나 ADD COLUMN을 실행했다면, 그 반대 동작을 하는 UNDO SQL을 미리 작성해둡니다.

SQL
-- 배포 SQL (예시)
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;
CREATE INDEX idx_users_last_login ON users(last_login);

-- UNDO SQL (미리 작성해둬야 함)
DROP INDEX idx_users_last_login ON users;
ALTER TABLE users DROP COLUMN last_login;
DB 클라이언트
# UNDO SQL 실행
mysql -u dbuser -p myapp_db < /opt/backup/undo_v1.2.0.sql

방법 2: 트랜잭션 ROLLBACK (배포 중 문제)

배포 스크립트 안에서 DB 변경을 트랜잭션으로 감쌌다면, 오류 시 전체를 ROLLBACK할 수 있습니다.

SQL
BEGIN;
  ALTER TABLE orders ADD COLUMN discount_rate DECIMAL(5,2);
  UPDATE orders SET discount_rate = 0;
  -- 여기서 오류 발생 시 → ROLLBACK
ROLLBACK;  -- 모든 변경 취소
-- 또는
COMMIT;    -- 정상이면 커밋

방법 3: 스냅샷 복원 (최후의 수단)

RDS 스냅샷, mysqldump 백업 등을 이용해 전체 DB를 이전 시점으로 복원합니다. 배포 이후 쌓인 실제 데이터가 모두 소실되므로, 사용자에게 공지 후 진행하는 경우에만 사용합니다.

DB 클라이언트
# mysqldump 백업 복원 (예시)
mysql -u root -p myapp_db < /opt/backup/myapp_db_20260530_2100.sql

DB 롤백이 불가한 경우:

SQL 유형롤백 가능 여부이유
INSERT/UPDATE/DELETEUNDO SQL 가능역연산 작성 가능
ADD COLUMNUNDO SQL 가능DROP COLUMN으로 역연산
DROP TABLE불가 (스냅샷 필요)데이터 소실, 복구 불가
TRUNCATE불가 (스냅샷 필요)트랜잭션 밖에서 즉시 반영
DROP COLUMN불가 (컬럼 데이터 소실)데이터 이미 삭제됨

이 때문에 운영 DB에서 DROP TABLE이나 TRUNCATE는 작업계획서에서 별도로 승인을 받아야 하는 위험 작업으로 분류됩니다.

인증서 롤백

💡개념

SSL 인증서 롤백 절차

인증서 교체 작업을 마쳤는데 일부 브라우저에서 "인증서를 신뢰할 수 없음" 오류가 납니다. 중간 인증서(chain)가 누락됐거나 도메인이 맞지 않는 인증서를 배포한 경우입니다. 사용자에게는 사이트 자체가 먹통처럼 보입니다. 이 상황에서 가장 빠른 복구는 이전 인증서로 즉시 되돌리는 것입니다. 인증서 교체 전에 반드시 이전 파일을 백업해두어야 이 복구가 가능합니다.

인증서를 교체했다가 문제가 생겼을 때, 이전 인증서로 되돌리는 절차입니다.

로컬 터미널
# 백업 인증서 위치 확인
ls -la /opt/backup/20260530_2200/ssl/
# → server.crt, server.key, server_chain.crt 확인

# 현재 인증서 백업 (롤백 실패 대비)
sudo cp /etc/nginx/ssl/server.crt /etc/nginx/ssl/server.crt.failed
sudo cp /etc/nginx/ssl/server.key /etc/nginx/ssl/server.key.failed

# 이전 인증서 복원
sudo cp /opt/backup/20260530_2200/ssl/server.crt /etc/nginx/ssl/
sudo cp /opt/backup/20260530_2200/ssl/server.key /etc/nginx/ssl/
sudo cp /opt/backup/20260530_2200/ssl/server_chain.crt /etc/nginx/ssl/

# 인증서 유효성 확인
sudo openssl x509 -noout -dates -in /etc/nginx/ssl/server.crt
# 출력 예시:
# notBefore=Jan  1 00:00:00 2026 GMT
# notAfter=Dec 31 23:59:59 2026 GMT

# Nginx 설정 검증
sudo nginx -t

# 검증 통과 후 재시작 (인증서는 reload로도 반영됨)
sudo systemctl reload nginx

# HTTPS 접속 확인
curl -sk https://localhost -o /dev/null -w "HTTP %{http_code}\n"

Tomcat에서 JKS(Java Keystore) 방식으로 SSL을 처리하는 경우:

로컬 터미널
# JKS 파일 복원
sudo cp /opt/backup/20260530_2200/keystore.jks /opt/tomcat/conf/keystore.jks

# Tomcat 재시작 (인증서 변경은 Tomcat 재시작 필요)
sudo systemctl restart tomcat

롤백 체크리스트

1WAR 파일 롤백 절차 실행

롤백 체크리스트를 한 항목씩 확인하며 진행합니다. 체크박스를 실제로 체크해가며 진행하면 빠진 단계 없이 완료할 수 있습니다.

롤백 체크리스트 (WAR 파일)

□ 롤백 결정 기록 (시각, 이유, 결정자)
□ 현재 실패한 WAR 파일 이름 기록
□ 백업 WAR 파일 위치 확인
  → ls -la /opt/backup/{날짜}/myapp_current.war
□ Tomcat shutdown 완료
  → systemctl stop tomcat
  → ps aux | grep tomcat (프로세스 없음 확인)
□ webapps/myapp 폴더 및 WAR 삭제
  → rm -rf /opt/tomcat/webapps/myapp*
□ 백업 WAR 복사
  → cp /opt/backup/{날짜}/myapp_current.war /opt/tomcat/webapps/myapp.war
□ Tomcat startup
  → systemctl start tomcat
□ 기동 로그 확인 (30초간 ERROR 없음)
  → tail -30 /opt/tomcat/logs/catalina.out
□ 헬스체크 URL 확인
  → curl http://localhost:8080/myapp/health → HTTP 200
□ 주요 기능 동작 확인 (로그인 등)
□ 담당자(팀장) 보고
□ 롤백 완료 기록 (시각, 결과)
sudo systemctl stop tomcat && sleep 3 && ps aux | grep tomcat | grep -v grep
🔍WAR 롤백 실행 확인
  • systemctl stop tomcat 후 tomcat 프로세스가 ps 결과에서 사라졌는가
  • /opt/backup/ 경로에 롤백할 WAR 파일이 존재하는가
  • systemctl start tomcat 후 catalina.out에 에러 없이 기동 메시지가 출력됐는가
  • 헬스체크 URL이 HTTP 200을 반환하는가
2Nginx 설정 파일 롤백 실행

설정 파일 롤백은 반드시 nginx -t 검증 후 진행합니다.

로컬 터미널
# 이전 설정 복원
sudo cp /opt/backup/$(ls /opt/backup | tail -1)/myapp.conf \
  /etc/nginx/conf.d/myapp.conf

# 검증
sudo nginx -t

# 이상 없으면 reload
sudo systemctl reload nginx

# 확인
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://localhost
sudo nginx -t
🔍실행 후 확인할 것
  • WAR 롤백 후 Tomcat이 active (running) 상태인가
  • 헬스체크 URL이 HTTP 200을 반환하는가
  • catalina.out에 Exception이 없는가
  • 이전 버전 기능이 정상 동작하는가 (로그인, 메인 화면)
  • 롤백 완료 시각을 기록했는가

트러블슈팅

상황: WAR를 이전 버전으로 롤백했는데도 500 에러가 계속 납니다. catalina.out에 Unknown column 'new_field' in 'field list'가 보입니다.

원인은 버전 불일치입니다. 이전 WAR 코드가 DB에 없는 컬럼을 읽으려는 것이 아니라, 새 WAR가 추가한 컬럼이 DB에 남아있고 이전 WAR가 그것을 처리 못하는 경우도 있습니다. 또는 이전 WAR가 특정 컬럼을 기대하는데 새 배포에서 컬럼명이 바뀐 경우도 있습니다.

로컬 터미널
# 에러 메시지에서 컬럼명 확인
grep "Unknown column\|Column.*not found\|Table.*doesn't exist" \
  /opt/tomcat/logs/catalina.out | tail -5

# DB 현재 스키마 확인
mysql -u dbuser -p myapp_db -e "SHOW COLUMNS FROM orders;"

# 이전 버전 WAR가 기대하는 스키마와 비교
# (UNDO SQL이 준비됐다면 실행)
mysql -u dbuser -p myapp_db < /opt/backup/undo_v1.2.0.sql

배포 시 WAR + DB migration을 함께 진행했다면, 롤백도 WAR + DB migration 되돌리기를 함께 해야 합니다. 작업계획서에 이 연계 관계가 명시돼 있어야 합니다.

상황: 롤백을 시도하려는데 /opt/backup/에 오늘 날짜 파일이 없습니다. 배포 전 백업을 건너뛴 것입니다. 이전 버전 WAR를 구할 수 없는 상황입니다.

로컬 터미널
# 1. Git 태그에서 이전 버전 빌드 파일 찾기
git log --oneline -10  # 이전 커밋 확인
git show v1.1.0:myapp.war  # 가능하면 추출

# 2. CI/CD 시스템에서 이전 빌드 아티팩트 다운로드
# Jenkins: Jobs > myapp > Build History > v1.1.0 > Artifacts
# GitLab: Pipelines > Jobs > download artifacts

# 3. 다른 환경(스테이징)에서 복사
scp staging-server:/opt/tomcat/webapps/myapp.war \
  /opt/tomcat/webapps/myapp_rollback.war

# 4. 최후 수단: 스테이징 환경에서 재빌드

이 상황을 겪고 나면 배포 전 백업이 얼마나 중요한지 체감하게 됩니다. 이후부터는 배포 스크립트에 백업 단계를 자동으로 포함시키는 것이 좋습니다.

로컬 터미널
# 배포 스크립트 첫 줄에 자동 백업 추가 예시
BACKUP_DIR="/opt/backup/$(date +%Y%m%d_%H%M)"
mkdir -p $BACKUP_DIR
cp /opt/tomcat/webapps/myapp.war $BACKUP_DIR/ || {
  echo "ERROR: 백업 실패. 배포를 중단합니다."
  exit 1
}
echo "백업 완료: $BACKUP_DIR/myapp.war"
💼
실무 맥락
현업 패턴

실제 업무에서 이 지식이 쓰이는 상황:

현장에서 롤백이 느린 팀과 빠른 팀의 차이는 롤백 절차가 문서화됐는가 여부입니다. 절차가 있는 팀은 No-Go 기준을 충족하는 순간 즉시 체크리스트를 꺼내 따라갑니다. 절차가 없는 팀은 Slack에 "어떻게 하죠?"를 올리는 것부터 시작합니다.

롤백 후 재발 방지 분석:

롤백이 완료된 후, 24시간 안에 짧은 포스트모템을 작성합니다.

롤백 후 재발 방지 분석:

발생 일시: 2026-05-30 22:30
원인: 신규 WAR에서 DB connection pool 설정이 누락됨
      (새 버전 context.xml에 maxActive 값이 기본값 8로 초기화됨)
영향: Tomcat 기동 후 10분간 커넥션 고갈, 500 에러 발생

롤백 완료: 22:47 (발견 후 17분)

재발 방지:
  1. 배포 체크리스트에 context.xml 설정값 비교 항목 추가
  2. 스테이징 환경에서 커넥션 풀 exhaustion 테스트 추가
  3. 배포 스크립트에 context.xml diff 출력 단계 추가

롤백 경험은 팀의 소중한 자산입니다. 기록하지 않으면 같은 실수가 반복됩니다. 다음 모듈에서는 이런 장애 상황에서 HTTP 에러 코드를 해석하고 로그만으로 원인을 찾는 방법을 다룹니다.

지식 확인

퀴즈 — 4문제

Q1

롤백을 결정하는 가장 중요한 판단 기준은?

Q2

WAR 파일 롤백 시 설정 파일도 함께 롤백해야 하는 이유는?

Q3

DB 롤백이 파일 롤백보다 어려운 이유는?

Q4

인증서 롤백 시 Nginx에서 추가로 해야 하는 작업은?

0 / 4 답변

🧪 실습으로 확인하기

Nginx 설치 및 기동

초급

Linux 서버에 Nginx를 설치하고 systemd 서비스로 등록하여 80포트에서 응답하는 상태까지 만든다.

30📋 3단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요

infra-ops중급 · 60
[Infra Ops] Filebeat/rsyslog 기반 로그 수집 파이프라인 구성
인프라 서비스 운영 트랙 계속
linux입문 · 30
[Linux] 개발자가 왜 리눅스 서버와 커맨드라인을 반드시 배워야 하는가
Linux 트랙 시작점