gbmin's Tech Notes

서버 구축 및 유지보수, 클라우드 컴퓨팅, 네트워크 보안, IT 분야 기술 노트. :)

Tech Notes/Trouble Shooting

Innodb 구동 안 됨, InnoDB: Starting crash recovery

gbmin 2023. 6. 22. 23:28

[Note] InnoDB: Using mutexes to ref count buffer pool pages
[Note] InnoDB: The InnoDB memory heap is disabled
[Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
[Note] InnoDB: Memory barrier is not used
[Note] InnoDB: Compressed tables use zlib 1.2.7
[Note] InnoDB: Using Linux native AIO
[Note] InnoDB: Using SSE crc32 instructions
[Note] InnoDB: Initializing buffer pool, size = 4.0G
[Note] InnoDB: Completed initialization of buffer pool
[Note] InnoDB: Highest supported file format is Barracuda.
[Note] InnoDB: Log scan progressed past the checkpoint lsn 220924569893
[Note] InnoDB: Database was not shutdown normally!
[Note] InnoDB: Starting crash recovery.
[Note] InnoDB: Reading tablespace information from the .ibd files...
[Note] InnoDB: Restoring possible half-written data pages
[Note] InnoDB: from the doublewrite buffer...


innodb 데이터 베이스에서 프로세스가 정상적으로 종료되지 않아 충돌 복구(crash recovery)가 진행되었지만, 복구 과정에서 문제가 발생했음을 알 수 있다. InnoDB 저장 엔진의 초기화 함수에서 오류가 발생하였고, 이로 인해 'InnoDB'가 스토리지 엔진으로서의 등록이 실패했다. 그 결과, MySQL 서버가 시작하지 못하고 중단되었다.


 

해결 과정

1. innodb_force_recovery 옵션을 사용

MySQL 설정 파일(my.cnf 또는 my.ini)에 innodb_force_recovery 설정을 추가하면 InnoDB가 일부 오류를 무시하고 시작을 시도할 수 있다. 이 설정의 값은 1에서 6까지 있으며, 높은 수치일수록 더 많은 오류를 무시한다. 이 옵션은 데이터 손실의 위험을 수반하므로 주의가 필요하다.

[mysqld]
innodb_force_recovery = 1

위의 설정을 추가한 후, MySQL을 다시 시작했다. 동작하지 않는다면, innodb_force_recovery의 값을 2~6 까지 반복하여 최대 6까지 시도 한다.

2. DB 가 정상적으로 실행되었다면 DB dump 를 시도

백업에 성공 하면 DB 재생성후 복원해준다. DB dump 가 정상적으로 안되는 경우가 있다. 이경우 mysqlcheck 나 dump 를 시도한다.
mysqlcheck 의 옵션은 -c, -q, -r 순서로 진행 했다.
DB 구동은 성공 했으나 일부 테이블에서 에러가 발생되었다.

3. 테이블 복구가 안됨

다른 문제가 발생되었다. 일부 테이블이 DB 에서 인식하지 못한다.

[Warning] InnoDB: Cannot open table gbminnote.gbminnote_table from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html for how you can resolve the problem.

MariaDB [gbminnote]> check table morning_goods_table;
+---------------------------------+----------+----------------------------------------------------------------------+
| Table                           | Op       | Msg_type | Msg_text                                                  |
+---------------------------------+----------+----------------------------------------------------------------------+
| gbminnote.gbminnote_table       | check    | Error    | Table 'gbminnote.gbminnote_table' doesn't exist in engine |
| gbminnote.gbminnote_table       | check    | status   | Operation failed                                          |
+---------------------------------+----------+----------------------------------------------------------------------+
2 rows in set (0.00 sec)


해당 에러는 MariaDB에서 해당 테이블(gbminnote.gbminnote_table)이 존재하지 않거나, InnoDB 스토리지 엔진에서 인식하지 못하는 상황을 나타내는 에러다. 이 문제는 테이블의 .frm 파일이 존재하지만, .ibd 파일(테이블 데이터를 저장하는 파일)이 존재하지 않거나 접근할 수 없는 경우에 발생할 수 있습니다.

MySQL 서버 종료 → ibdata와 ib_logfile 파일 백업백업 → innodb_force_recovery = 6 으로 변경 → mysql start 후 복구를 시도 를 했으나 테이블 복구가 불가능한 상황이 되어버렸다.

 

4. ibdata 재생성

별개로 DB 를 재시작 하다 보니 ibdata 파일이 깨져 아래와 같이 에러로그가 발생되었다.

errno: 39 "Directory not empty"

 

[ERROR] InnoDB: Unable to lock ./ibdata1, error: 11
Check that you do not already have another mysqld process using the same InnoDB data or log files.

 

ibdata와 ib_logfile 파일 백업후 삭제 하였고 DB 를 재생성 하였다. 일부 테이블 에러는 해결 되지 못했다.


최종 복구 결정


복구 불가능한 깨진 테이블은 결국 복구가 불가능하여 깨진 테이블은 제외하고 나머지 테이블을 백업 하였다.

mysqldump --skip-lock-tables \
--ignore-table=gbminnote.gbminnote_table \
--ignore-table=gbminnote.gbminnote_table2
-u root -p gbminnote > db_crash_crash.sql

 

깨진 져서 dump 에서 제외한 테이블은 정기적으로 백업 하는 백업에서 테이블을 추출하여 복구해주고, recovery 해제후 문제가 된 DB 는 Drop 하고 재생성 해주었다.백업본 테이블의 파일과 nnodb_force_recovery 모드에서 백업할 테이블을들 각각 복구해주어 복구작업을 마쳤다.