Files
jisangs 03eea2098e 운영 서버에서 DB index 적용 작업 진행
- 01~07 작업 문서를 운영 측정값 기준으로 정리 (문서의 DB 비밀번호 삭제)
- app_highest_record 중복 8,795행 점수 기준 정리, 인덱스 5개 + UNIQUE 키 2개 추가
- 02·04 공통 측정 스크립트와 측정 결과, comparison.txt 추가
- 서버 처리 시간 18~292배 단축, 결과 행 수 동일
- 운영 데이터 백업과 권한(비밀번호 해시) 파일은 커밋에서 제외

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15 23:30:42 +09:00

4.9 KiB

06단계: 롤백 계획

문제 발생 시 인덱스를 삭제하고, 필요하면 중복 정리 전 상태로 되돌립니다.

⚠️ 작업용 jisangs 계정은 2026-09-15에 삭제했습니다. 이 문서의 -u jisangs 명령은 관리자 계정으로 바꿔 실행하세요.

모든 명령은 result/ 디렉터리에서 실행합니다.


🚨 긴급 상황 대응

1. 진행 중인 ALTER 중단

mariadb -h chocomae.jinaju.com -u jisangs -p chocomae -e "SHOW PROCESSLIST;" | grep ALTER

# 첫 번째 열(Id)의 값을 넣어 실행
mariadb -h chocomae.jinaju.com -u jisangs -p chocomae -e "KILL QUERY <Id>;"

온라인 DDL을 중단하면 그 인덱스만 만들어지지 않고 테이블 데이터는 그대로입니다. 내 계정이 실행한 쿼리는 별도 권한 없이 중단할 수 있습니다.

2. 인덱스 삭제

mariadb -h chocomae.jinaju.com -u jisangs -p chocomae << 'EOF'
-- 모든 인덱스 삭제
ALTER TABLE best_record DROP INDEX IF EXISTS idx_maestro_app_dt;
ALTER TABLE best_record DROP INDEX IF EXISTS idx_maestro_player_app_dt;
ALTER TABLE typing_exam_record DROP INDEX IF EXISTS idx_maestro_writing_dt;
ALTER TABLE typing_exam_record DROP INDEX IF EXISTS idx_maestro_player_writing_dt;
ALTER TABLE license_score DROP INDEX IF EXISTS idx_maestro_player_dt;
ALTER TABLE app_highest_record DROP INDEX IF EXISTS uk_maestro_player_app;
ALTER TABLE typing_exam_highest_record DROP INDEX IF EXISTS uk_maestro_player_writing;
EOF

UNIQUE 키 2개는 성능과 무관하므로, 성능 문제로 롤백할 때는 남겨 두어도 됩니다. 남겨 두면 중복이 다시 생기지 않습니다.


중복 정리 되돌리기 (필요할 때만)

삭제한 행은 같은 조합의 덜 좋은 기록이라 보통 되돌릴 필요가 없습니다. 되돌려야 하면 UNIQUE 키를 먼저 삭제한 뒤 03단계 3-0-2의 백업 파일을 실행합니다. (INSERT 권한 — jisangs에 임시 부여됨)

mariadb -h chocomae.jinaju.com -u jisangs -p chocomae -e "
ALTER TABLE app_highest_record DROP INDEX IF EXISTS uk_maestro_player_app;"

mariadb -h chocomae.jinaju.com -u jisangs -p chocomae < backup_app_highest_dup_rows.sql

mariadb -h chocomae.jinaju.com -u jisangs -p chocomae -e "
SELECT COUNT(*) AS total_rows FROM app_highest_record;"

백업 파일은 원래 ID 그대로 INSERT하므로 기존 행과 충돌하지 않습니다. 복원 후 total_rows는 3-0-3 삭제 전 행 수(그 사이 새로 저장된 기록 제외)와 같아야 합니다.


전체 백업에서 복원 (최후의 수단)

운영 DB는 AWS RDS가 아니라 EC2의 Docker MariaDB입니다. 인덱스 문제는 DROP INDEX로 충분하므로 데이터 손상이 있을 때만 사용하세요. 백업 이후 저장된 게임 기록은 모두 사라집니다.

방법 1: 덤프 파일 복원

# EC2 서버의 MariaDB 컨테이너 안에서 관리자 계정으로 실행
mariadb -u <관리자> -p chocomae < backup_2026-09-15.sql

방법 2: EBS 스냅샷 복원

  1. AWS 콘솔 → EC2 → 스냅샷에서 작업 전 스냅샷 선택
  2. 스냅샷으로 볼륨 생성 (EC2 인스턴스와 같은 가용 영역)
  3. MariaDB 컨테이너 중지 → 기존 데이터 볼륨 분리 → 새 볼륨 연결·마운트
  4. 컨테이너 시작 후 접속 확인

복제 상태 확인 (복제를 사용 중인 경우, 관리자 계정)

SHOW MASTER STATUS;
SHOW REPLICA STATUS\G

서비스 정상 확인

  • 웹 서비스 접속 테스트
  • 타이핑 게임 플레이 테스트 (결과 저장, 최고기록 표시)
  • 랭킹 조회 테스트

문제 원인 분석

증상 원인 대응
인덱스 생성 실패 디스크 부족 DROP INDEX + 디스크 정리
Duplicate entry ... for key 'uk_...' 3-0 이후 새 중복 발생 3-0-2·3-0-3 다시 실행 후 add_indexes.sql 재실행 (이미 만든 인덱스는 건너뜀)
서비스 느려짐 옵티마이저가 새 인덱스를 잘못 선택, 통계 부정확 ANALYZE TABLE best_record; (관리자) → 그래도 느리면 해당 인덱스 DROP
최고기록 화면 값 이상 중복 정리 결과 백업 파일에서 해당 조합 확인, 필요하면 "중복 정리 되돌리기"
복제 지연·오류 복제 서버에서 DDL 적용 중 또는 실패 SHOW REPLICA STATUS로 확인

복구 후 확인

# 테이블 상태 확인
mariadb -h chocomae.jinaju.com -u jisangs -p chocomae -e "
SHOW INDEXES FROM best_record;
SELECT COUNT(*) FROM best_record;
"

성능 확인은 zsh run_measure.sh after로 다시 측정해 baseline_perf.txt와 비교합니다. 기존 after_* 파일을 덮어쓰므로 먼저 다른 폴더로 옮기세요.


문제 발생 시 연락

  • 팀 리더: [연락처]
  • DBA: [연락처]
  • 운영팀: [연락처]

롤백은 최후의 수단입니다. 충분한 검토 후 신중하게 진행하세요. ⚠️