MySQL - 강제 복구 모드 innodb_force_recovery
MySQL 데이터베이스에서 InnoDB 엔진을 사용할 때 데이터 손상은 매우 드물게 발생하지만, 예기치 못한 장애 상황에서는 복구가 필요할 수 있습니다. 특히 손상이 인덱스와 같은 특정 영역에 국한될 때 복구 절차는 비교적 간단합니다. 이 글에서는 MySQL의 강제 복구 모드 옵션 innodb_force_recovery
의 다양한 설정값과 복구 절차를 상세히 설명합니다.
본론
InnoDB 테이블 손상의 원인
- InnoDB의 안정성
- InnoDB는 Double Write, Checksum, 기타 검증 로직 등으로 안정성을 높이며, MyISAM보다 데이터 파일 손상 위험이 낮습니다.
- 인덱스 손상의 빈도
- 손상의 80~90%는 Secondary Index(보조 인덱스)에서 발생합니다.
- 이 경우, 간단히
ALTER TABLE
명령 또는 데이터 덤프 후 재적재로 문제를 해결할 수 있습니다.
- 기타 원인
- 테이블 스페이스나 데이터 파일 손상은 백업본과 Binary Log를 활용한 복구를 권장합니다.
복구 모드와 설정값
InnoDB 강제 복구 모드는 설정값에 따라 복구 범위와 제한이 달라집니다. 설정값은 1
부터 6
까지 있으며, 값이 높아질수록 데이터 손실 가능성이 커지므로 낮은 값부터 시도하는 것이 중요합니다.
복구 모드
1. SRV_FORCE_IGNORE_CORRUPT
- 손상된 데이터 페이지를 무시하고 MySQL을 시작
- 데이터 덤프 및 재적재 또는 다른 데이터베이스로 이전 권장
- 손상된 인덱스 레코드 및 페이지 건너뛰기(데이터 손실 가능)
2. SRV_FORCE_NO_BACKGROUND
- InnoDB의 Main thread 시작하지 않고 MySQL 시작
- Undo 정보 삭제 작업(Purge) 오류 방지
- 전체 데이터베이스 덤프 및 재구성 필요
3. SRV_FORCE_NO_TRX_UNDO
- 진행 중인 트랜잭션 강제 종료
- 트랜잭션 정리 작업 미실행
- InnoDB가 트랜잭션 로그를 읽어 Roll forward 및 Rollback 수행
- Undo 영역 손상 시 Rollback 불가
4. SRV_FORCE_NO_IBUF_MERGE
- Insert Buffer 병합 작업 실패 방지
- 테이블 통계 정보 갱신 작업 금지
- 테이블 덤프 및 재적재 또는 ALTER TABLE 명령으로 해결 가능
5. SRV_FORCE_NO_UNDO_LOG_SCAN
- Undo 로그 무시
- 완료되지 않은 트랜잭션을 COMMIT 처리
- Undo 로그 참조하지 않음
6. SRV_FORCE_NO_LOG_REDO
- 체크포인트 이후 트랜잭션 버림
- Redo 로그 참조하지 않음
- Redo 로그 손상 시 강제 복구 가능
주의: 강제 복구 모드는 그 설정 값이 높아질수록 손실되는 데이터가 많아지기(복구 가능한 데이터가 적어지기) 때문에, 가능한 강제 복구 모드를 낮은 것(1 -> 2 -> 3 -> 4 -> 5 -> 6)부터 시도하는 것이 좋습니다.
복구 절차
- 복구 모드 설정
/etc/my.cnf
파일에innodb_force_recovery
설정 추가:[mysqld] innodb_force_recovery = 1
- MySQL 서버 시작.
- 데이터 덤프
- MySQL이 정상 기동되면
mysqldump
로 데이터베이스를 백업합니다.mysqldump -uroot -p --routines --triggers --events --single-transaction db_name > backup.sql
- MySQL이 정상 기동되면
- 복구 모드 해제
my.cnf
에서 복구 모드 설정 제거 후 MySQL 재시작.
- 데이터 재적재
- 기존 데이터베이스 삭제 및 재생성:
DROP DATABASE db_name; CREATE DATABASE db_name;
- 덤프 파일을 다시 불러옵니다:
mysql -uroot -p db_name < backup.sql
- 기존 데이터베이스 삭제 및 재생성:
- 상태 확인
- 데이터 확인 후 문제가 지속되면 복구 모드 설정값을 증가시키며 반복합니다.
recovery 옵션을 통해 복구한 경우 db를 덤프뜬 다음에, recovery옵션을 지우고 다시 데이터를 넣어주는 것이 좋다.
강제 복구를 사용한다고 하더라도, 테이블을 덤프하기 위해 SELECT를 실행하거나, 또는 DROP 또는 CREATE 테이블을 사용할 수가 있다. 만일 주어진 테이블에 롤백이 되는 동안의 크래시의 원인이 된다는 것을 알게 되면, 그 테이블을 드롭 시킨다. 또한, 대형 임포트 (mass import) 또는 ALTER TABLE의 실패로 인해 발생한 장기간의 롤백 (runaway rollback)을 중지 시키기 위해서도 이것을 사용할 수가 있다.
mysqld 프로세스를 죽이고 innodb_force_recovery를 3으로 설정함으로써 롤백 없이 데이터 베이스를 업데이트 시킨 상태로 가져올 수가 있으며, 그런 다음에는 장기간 롤백의 원인이 된 테이블을 DROP시킨다.
데이터베이스는 innodb_force_recovery에 대해서 논-제로 (non-zero) 값을 사용해야만 한다.
결론
InnoDB 강제 복구 모드는 데이터 손상 복구에 유용하지만, 데이터 손실 위험이 있으므로 신중히 사용해야 합니다. 항상 최신 백업을 유지하고 복구 절차를 진행하기 전에 데이터를 덤프하여 안전성을 확보하세요.
댓글남기기