DB가 갑자기 다운되고 실행이 안되어 에러로그 확인했을 때 다음과 같은 에러메시지 확인 될 경우가 있다.
2017-02-17 16:22:49 2188 [Note] InnoDB: innodb_empty_free_list_algorithm has been changed to legacy because of small buffer pool size. In order to use backoff, increase buffer pool at least up to 20MB. 2017-02-17 16:22:49 2188 [Note] InnoDB: Using mutexes to ref count buffer pool pages 2017-02-17 16:22:49 2188 [Note] InnoDB: The InnoDB memory heap is disabled 2017-02-17 16:22:49 2188 [Note] InnoDB: Mutexes and rw_locks use Windows interlocked functions 2017-02-17 16:22:49 2188 [Note] InnoDB: _mm_lfence() and _mm_sfence() are used for memory barrier 2017-02-17 16:22:49 2188 [Note] InnoDB: Compressed tables use zlib 1.2.3 2017-02-17 16:22:49 2188 [Note] InnoDB: Using generic crc32 instructions 2017-02-17 16:22:49 2188 [Note] InnoDB: Initializing buffer pool, size = 8.0M 2017-02-17 16:22:49 2188 [Note] InnoDB: Completed initialization of buffer pool 2017-02-17 16:22:49 2188 [Note] InnoDB: Highest supported file format is Barracuda. 2017-02-17 16:22:49 2188 [Note] InnoDB: Log scan progressed past the checkpoint lsn 7300990 2017-02-17 16:22:49 2188 [Note] InnoDB: Database was not shutdown normally! 2017-02-17 16:22:49 2188 [Note] InnoDB: Starting crash recovery. 2017-02-17 16:22:49 2188 [Note] InnoDB: Reading tablespace information from the .ibd files... 2017-02-17 16:22:49 2188 [ERROR] InnoDB: Attempted to open a previously opened tablespace. Previous tablespace djtarotkr/ysuc2bd1p_aiowps_events uses space ID: 4 at filepath: .\djtarotkr\ysuc2bd1p_aiowps_events.ibd. Cannot open tablespace mysql/slave_master_info which uses space ID: 4 at filepath: .\mysql\slave_master_info.ibd InnoDB: Error: could not open single-table tablespace file .\mysql\slave_master_info.ibd InnoDB: We do not continue the crash recovery, because the table may become InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it. InnoDB: To fix the problem and start mysqld: InnoDB: 1) If there is a permission problem in the file and mysqld cannot InnoDB: open the file, you should modify the permissions. InnoDB: 2) If the table is not needed, or you can restore it from a backup, InnoDB: then you can remove the .ibd file, and InnoDB will do a normal InnoDB: crash recovery and ignore that table. InnoDB: 3) If the file system or the disk is broken, and you cannot remove InnoDB: the .ibd file, you can set innodb_force_recovery > 0 in my.cnf InnoDB: and force InnoDB to continue crash recovery here.
정확한 원인 등은 확인하지 못하였지만 일부 테이블이 손상되었고, “[ERROR] InnoDB: Attempted to open a previously opened tablespace” 문구부터 내용을 살펴보면 기존에 정상 실행되었던 테이블스페이스로 복구하라는 내용을 확인할 수 있다.
현재까지 확인된 방법은 다음과 같은 두가지이다.
- my.cnf 파일 내용에 강제복구 옵션 추가하여 재실행
- 복구 옵션으로 복구되지 못한다면 손상된 테이블 혹은 해당 DB를 삭제하고 정상 상태의 백업데이터로 복원
강제복구 옵션은 다음과 같이 진행한다.
- my.cnf 파일의 [mysqld]항목에 다음과 같이 복구 옵션 추가
[mysqld] innodb_force_recovery = 4
같이 복구 옵션 추가
- DB 재실행 후 손상된 DB 및 테이블 상태 확인
- 상태 및 데이터 정상으로 확인되면 DB 중지
- my.cnf 파일에 추가한 옵션 제거 후 DB 재실행
복구옵션의 값은 0부터 6까지이고 각 단계별 처리 내용은 다음과 같다. 큰값으로 설정될수록 아래숫자의 사항을 포함하게되고, 설정한 숫자가 커질수록 손실되는 데이터가 많아지므로 되도록 낮은숫자에서부터 순차적으로 시도해보는 것이 좋다.
- 옵션값 1 (SRV_FORCE_IGNORE_CORRUPT)
- 손상된 페이지가 발견되어도 무시하고 mysql을 가동
- 가동이되면 테이블을 덤프하여 복구시키거나 다른데이터베이스로 이전하는것이 좋다
- 손상된 레코드와 페이지는 모두 건너뛰게됨으로 데이터를 잃게됨
- 옵션값 2 (SRV_FORCE_NO_BACKGROUND)
- 메인 쓰레드가 구동되지 못하도록 한다
- 만일 퍼지 연산 (purge operation)이 진행되는 동안 크래시가 발생한다면, 이 복구 값은 퍼지 연산이 실행되는 것을 막게 된다.
- 온션값 3 (SRV_FORCE_NO_TRX_UNDO)
- mysql종료하던 시점에 진행중인 트랜잭션이있다면 mysql 단순히 그 연결을 끊는다.
- 다시실행후 innodb엔진이 롤백을 실행하는데 만약 데이터가 손상된경우 롤백을 실행할수없기때문에 이경우 사용되는 복구모드이다.
- 옵션값 4 (SRV_FORCE_NO_IBUF_MERGE)
- INSERT, UPDATE , DELETE 연산자를 실행하지 않도록 한다.
- 테이블 통계값을 계산하지 않도록 한다.
- 옵션값 5 (SRV_FORCE_NO_UNDO_LOG_SCAN)
- 데이터베이스를 시작할 때 undo log를 검사하지 않는다
- InnoDB는 완벽하지 않은 트랜젝션도 실행된 것으로 다루게 된다.
- 옵션값 6 (SRV_FORCE_NO_LOG_REDO)
- mysql이 재시작전 가장뒤에 발생한 체크포인트 이후 모든 트랜잭션을 버리고 복구시키는 모드
- 복구 연결에서 log roll-forward를 실행하지 않고 강제복구한다