MySQL(MariaDB) “InnoDB: Error: could not open single-table tablespace file”

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” 문구부터 내용을 살펴보면 기존에 정상 실행되었던 테이블스페이스로 복구하라는 내용을 확인할 수 있다.

현재까지 확인된 방법은 다음과 같은 두가지이다.

  1. my.cnf 파일 내용에 강제복구 옵션 추가하여 재실행
  2. 복구 옵션으로 복구되지 못한다면 손상된 테이블 혹은 해당 DB를 삭제하고 정상 상태의 백업데이터로 복원

강제복구 옵션은 다음과 같이 진행한다.

  1. my.cnf 파일의 [mysqld]항목에 다음과 같이 복구 옵션 추가
    [mysqld]
    innodb_force_recovery = 4

    같이 복구 옵션 추가

  2. DB 재실행 후 손상된 DB 및 테이블 상태 확인
  3. 상태 및 데이터 정상으로 확인되면 DB 중지
  4. my.cnf 파일에 추가한 옵션 제거 후 DB 재실행

복구옵션의 값은 0부터 6까지이고 각 단계별 처리 내용은 다음과 같다. 큰값으로 설정될수록 아래숫자의 사항을 포함하게되고, 설정한 숫자가 커질수록 손실되는 데이터가 많아지므로 되도록 낮은숫자에서부터 순차적으로 시도해보는 것이 좋다.

  1. 옵션값 1 (SRV_FORCE_IGNORE_CORRUPT)
    • 손상된 페이지가 발견되어도 무시하고 mysql을 가동
    • 가동이되면 테이블을 덤프하여 복구시키거나 다른데이터베이스로 이전하는것이 좋다
    • 손상된 레코드와 페이지는 모두 건너뛰게됨으로 데이터를 잃게됨
  2. 옵션값 2 (SRV_FORCE_NO_BACKGROUND)
    • 메인 쓰레드가 구동되지 못하도록 한다
    • 만일 퍼지 연산 (purge operation)이 진행되는 동안 크래시가 발생한다면, 이 복구 값은 퍼지 연산이 실행되는 것을 막게 된다.
  3. 온션값 3 (SRV_FORCE_NO_TRX_UNDO)
    • mysql종료하던 시점에 진행중인 트랜잭션이있다면 mysql 단순히 그 연결을 끊는다.
    • 다시실행후 innodb엔진이 롤백을 실행하는데 만약 데이터가 손상된경우 롤백을 실행할수없기때문에 이경우 사용되는 복구모드이다.
  4. 옵션값 4 (SRV_FORCE_NO_IBUF_MERGE)
    • INSERT, UPDATE , DELETE  연산자를 실행하지 않도록 한다.
    • 테이블 통계값을 계산하지 않도록 한다.
  5. 옵션값 5 (SRV_FORCE_NO_UNDO_LOG_SCAN)
    • 데이터베이스를 시작할 때 undo log를 검사하지 않는다
    • InnoDB는 완벽하지 않은 트랜젝션도 실행된 것으로 다루게 된다.
  6. 옵션값 6 (SRV_FORCE_NO_LOG_REDO)
    • mysql이 재시작전 가장뒤에 발생한 체크포인트 이후 모든 트랜잭션을 버리고 복구시키는 모드
    • 복구 연결에서 log roll-forward를 실행하지 않고 강제복구한다

 

덤프 복원 중 MySQL server has gone away 메시지

  • mysql 덤프 파일을 복원하던 중 다음과 같은 메시지가 뜬다면
$ mysql -uroot -p < dump.sql
Enter password: *********
ERROR 2006 (HY000) at line 868: MySQL server has gone away
  • max_allowed-packet 값을 확인
mysql> show variables like 'max_allowed_packet'"
+--------------------+---------+
| Variable_name      | Value   |
+--------------------+---------+
| max_allowed_packet | 1048576 |
+--------------------+---------+

대부분 max_allowed_packet 값을 높여주면 해결됨

도움 : 제타위키

우편번호 DB 만들기 (mysql)

우편번호|우편일련번호|시도|시도영문|시군구|시군구영문|읍면|읍면영문|도로명코드|도로명|도로명영문|지하여부|건물번호본번|건물번호부번|건물관리번호|다량배달처명|시군구용건물명|법정동코드|법정동명|리|산여부|지번본번|읍면동일련번호|지번부번
  • 우편번호 테이블 정보에 맞추어 다음과 같이 DB내 테이블 생성
create table `seoul` (
 `zipcode` varchar(6) default NULL,
 `zipseq` varchar(10) default NULL,
 `sido` varchar(30) default NULL,
 `sido_eng` varchar(30) default NULL,
 `sigungu` varchar(30) default NULL,
 `sigungu_eng` varchar(30) default NULL,
 `eupmyun` varchar(30) default NULL,
 `eupmyun_eng` varchar(30) default NULL,
 `streetcode` varchar(12) default NULL,
 `street` varchar(90) default NULL,
 `street_eng` varchar(90) default NULL,
 `isunder` char(1) default NULL,
 `buildingnum1` varchar(5) default NULL,
 `buildingnum2` varchar(5) default NULL,
 `buildingcode` varchar(25) default NULL,
 `massdestination` varchar(60) default NULL,
 `building` varchar(50) default NULL,
 `dongcode` varchar(10) default NULL,
 `dong` varchar(30) default NULL,
 `ri` varchar(30) default NULL,
 `ismountain` char(1) not NULL default '0',
 `jibun1` int(4) not NULL,
 `dongseq` varchar(2) default NULL,
 `jibun2` int(4) not NULL,
 primary key (`buildingcode`,`ismountain`,`jibun1`,`jibun2`),
 key `IDX_STREET` (`street`),
 key `IDX_DONG` (`dong`),
 key `IDX_BUILDING` (`building`),
 key `IDX_MASSDESTINATION` (`massdestination`),
 key `IDX_ZIPCODE` (`zipcode`)
 ) engine=myisam default charset=utf8; 
  • 다운받은 텍스트 파일은 UTF-8(BOM없음)으로 변환하고 헤더줄은 제거하여 저장

  • ftp 업로드 후 다음과 같은 형식으로 mysql에서 테이블로 로딩(파일 및 테이블 지정 반드시 확인)

LOAD DATA LOCAL INFILE '/home/cafe24/20140724_seoul.txt' INTO TABLE seoul CHARACTER SET 'utf8' FIELDS TERMINATED BY '|';