InnoDB 테이블 손상을 어떻게 식별합니까?


24

분할 된 테이블이 있고 복제 된 슬레이브에 여러 인덱스가 있습니다. 스냅 샷 (확인 된 안전)을 새 슬레이브에 복사하고 mysqld를 5.1.42에서 5.5.15로 업그레이드하고 복제를 다시 시작한 후 "Invalid pointer ..."오류 메시지와 함께 InnoDB가 충돌합니다

이 오류는 하드웨어 및 O / S가 다른 두 서버에서 발생했습니다. 실행 후 :

ALTER TABLE .... COALESCE PARTION n;

그 테이블에 대한 문제는 사라집니다.

제 질문은 그 범위가 더 크며 "InnoDB 테이블 손상을 어떻게 식별합니까?"입니다. 또는 "InnoDB 테이블 상태를 어떻게 평가합니까?" 가 "CHECK 표는" 사전 충돌 문제를 식별 할 수있는 유일한 도구?

중요한지 확실하지 않지만 충돌이 발생했습니다. 버전 : '5.5.15-55-log'소켓 : '/opt/mysql.sock'포트 : 3306 Percona Server (GPL), 릴리스 rel21.0, 개정판 158


2
랜디 안녕! 여기에 대한 답변은 믿을 만하다고 생각합니다. InnoDB는 자체 부패를 식별했습니다. 어쩌면 당신은 당신의 질문을 바꾸어야 할 것인데, 왜 당신이하는 일이 InnoDB를 손상시킬 것입니까?
Morgan Tocker

답변:


18

Morgan 은 InnoDB가 읽은 페이지에서 체크섬을 수행하여 손상된 페이지를 지속적으로 확인하고 있다는 힌트를주었습니다. InnoDB가 체크섬 불일치를 발견 하면 서버 가 중단 됩니다.

InnoDB가 손상된 페이지를 읽을 때까지 기다리지 않고 프로세스 속도를 높이려면 다음을 사용하십시오 innochecksum.

체크섬이 일치하지 않으면 InnoDB가 실행중인 서버를 의도적으로 종료하게되므로 프로덕션 환경에서 서버가 손상된 페이지를 기다리는 것을 기다리는 대신이 도구를 사용하는 것이 좋습니다.

흥미로운 경고 :

서버가 이미 연 테이블 스페이스 파일에는 innochecksum을 사용할 수 없습니다. 이러한 파일의 경우 CHECK TABLE을 사용하여 테이블 스페이스 내의 테이블을 확인해야합니다.

따라서 온라인 테이블의 CHECK TABLE경우 아마도 도구 일 것입니다 (또는 한 번에 여러 데이터베이스를 수행하려는 경우 다른 답변에서 지적한 것처럼 mysqlcheck).

데이터베이스를 종료 할 수 있으면 다음을 사용하여 체크섬을 강제 실행할 수 있습니다. innochecksum

일화 : 29GB의 innodb 테이블 스페이스 ( innodb_file_per_table=1)에서이 스크립트는 약 2 분이 걸렸습니다.

#!/bin/bash
for i in $(ls /var/lib/mysql/*/*.ibd)
do
  innochecksum -v $i
done

그러나 보너스로 Percona를 실행하고 있기 때문에 빠른 innodb 체크섬을 위한 새로운 방법을 구현했습니다 . 나는 그것을 사용한 적이 없지만 프로세스 속도를 높일 수 있습니다.


1
@randymelder가 +1을 찾고있는 해결책 인 것 같습니다.
marcio

2
Percona 서버에는 다른 멋진 기능이 있습니다. 참조 innodb_corrupt_table_action percona.com/doc/percona-server/5.5/reliability/... (!)
모건 Tocker

@DTest : innochecksum이가는 길입니다. 이 사람은 골키퍼입니다. +1 !!!
RolandoMySQLDBA

@ DTest : 오늘 이것 하나에 당신에게 모자 !!!!
RolandoMySQLDBA

@MorganTocker 재미있는. 내 지식 진공을 얻을 수 있고 percona에 몇 가지 조사 할 것
데릭 다우니

6

경고 : 이러한 지침을 시도하기 전에 만일을 대비하여 데이터베이스를 올바르게 백업했는지 확인하는 것이 좋습니다. (경고를 위해 @Nick에게 감사드립니다)

mysqlcheck명령 을 사용하십시오 . 터미널에서 :

mysqlcheck -u username -p --databases database1 database2

이 명령은 모든 테이블 목록과 어떤 종류의 손상이 있었는지 알려주는 상태를 출력합니다.

table1  OK
table2  OK
table3  OK
tableN  OK

그것을 손에 쥐면 어떤 테이블을 수리해야하는지 이미 알 수 있습니다. 한 번에 모든 것을 복구하려는 경우 :

mysqlcheck -u username -p --auto-repair --databases database1 database2 

추가 정보 mysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

참고 : 질문에 태그를 지정 . 나는 그것이 무엇인지에 대한 단서가 없었기 때문에 나는 구글했다. MySQL의 포크 인 것처럼 보이지만 명령이 호환되지 않는다고 생각할 이유가 없습니다 (손가락을 엇갈리게).


누군가가 전체 데이터베이스가 시작되지 않는보다 중요한 상황에 대한 InnoDB 데이터베이스 복구에 대한보다 구체적인 지침이있는이 안내서를 지적했습니다. http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-myisam-innodb-1634.html


1
mysqlcheck는 'check table ...'의 동의어이다. -1
randomx


사실이 아니다. 먼저 mysqlcheck는 명령 줄 유틸리티이고 CHECK TABLE은 SQL 문입니다 (오렌지와 lemmon을 비교하는 것 같습니다). 또한 SQL 문에 모든 테이블 이름을 포함하지 않고 CHECK TABLE을 사용하여 전체 데이터베이스를 확인할 수 없습니다 (
그것도

그리고 mysqlcheck는 손상된 테이블을 --auto-repair하는 옵션을 가지고 있으며 CHECK TABLE은 테이블이 손상되었는지 여부 만 확인하지만 복구 할 수는 없습니다.
marcio

2
@randymelder-당신은 mysqlcheck가 동의어라고 말하는 것이 잘못되었습니다 CHECK TABLE. 이 상태로 링크 된 문서는 " mysqlcheckSQL 문 사용 CHECK TABLE, REPAIR TABLE, ANALYZE TABLE,와 OPTIMIZE TABLE. 사용자를위한 편리한 방법으로 그것은 당신이 수행 할 작업에 사용하는 문을 결정하고 실행하는 서버에 문을 보냅니다. " 그것은 동의어가 아닙니다. 이는 명령문 콜렉션에 대한 사용자 인터페이스입니다.
Nick Chammas

6

MySQL 5.0 Certification Study Guide, 페이지 443,444 섹션 30.4 에 따르면 :

CHECK TABLE 명령을 사용하거나 클라이언트 프로그램을 사용하여 명령문을 발행하여 InnoDB 테이블을 점검 할 수 있습니다. 그러나 InnoDB 테이블에 문제가있는 경우 해당 명령문은 MyISAM에만 적용되므로 REPAIR TABLE을 사용하여 수정할 수 없습니다.

테이블 검사에서 InnoDB 테이블에 문제가 있음을 나타내면 mysqldump로 테이블을 덤프하고 삭제 한 다음 해당 덤프에서 테이블을 다시 생성하여 테이블을 일관된 상태로 복원 할 수 있어야합니다.

MySQL 서버 또는 서버가 실행되는 호스트에서 충돌이 발생할 경우 일부 InnoDB 테이블을 복구해야 할 수 있습니다. InnoDB 스토리지 엔진은 시작 시퀀스의 일부로 자동 복구를 수행하기 때문에 일반적으로 서버를 다시 시작하면됩니다. 드물지만 InnoDB 자동 복구 실패로 인해 서버가 시작되지 않을 수 있습니다. 이 경우 다음 절차를 따르십시오.

  • --innodb_force_recovery 옵션을 1-6 범위의 값으로 설정하여 서버를 다시 시작하십시오.이 값은 충돌을 피할 때주의 수준이 높아지고 복구 된 테이블의 불일치에 대한 허용 수준이 높아짐을 나타냅니다. 시작하기에 좋은 가치는 4입니다.

  • --innodb_force_recovery를 0이 아닌 값으로 설정하여 서버를 시작하면 InnoDB는 테이블 스페이스를 읽기 전용으로 취급합니다. 결과적으로, mysqldump로 InnoDB 테이블을 덤프 한 다음 옵션이 적용되는 동안 테이블을 삭제해야합니다. 그런 다음 --innodb_force_recovery 옵션없이 서버를 다시 시작하십시오. 서버가 나타나면 덤프 파일에서 InnoDB 테이블을 복구하십시오.

  • 이전 단계가 실패하면 이전 백업에서 InnoDB 테이블을 복원해야합니다.

InnoDB 강제 복구 에 대한 MySQL 문서를 읽어보십시오  


3
FWIW, 인증 가이드는 매우 정치적으로 정답입니다. : InnoDB 테이블에서 CHECK TABLE을 수행하고 실제로 손상된 경우 "손상"으로 반환되지 않으며 서버에 충돌이 발생합니다. InnoDB 페이지를 읽을 때마다 (페이지 체크섬을 통해) 손상 여부를 검사하기 때문에이 명령문은 InnoDB에서 거의 사용되지 않습니다.
Morgan Tocker

2

누군가 InnoDB 플러그인을 통해 생성 된 InnoDB 데이터를 사용한 다음 다른 버전의 InnoDB로 전환하면 어떻게 될지 궁금합니다. mysqld에서 눈에 띄는 페이지 손상을 일으킬 수 있습니다.

InnoDB 파일 형식에 관한 MySQL 문서 가이 가능성에 대해 말하는 것을 주목하십시오 :

일반적으로 최신 버전의 InnoDB는 충돌, 중단, 잘못된 결과 또는 손상의 위험없이 InnoDB의 이전 버전으로 안전하게 읽거나 쓸 수없는 테이블 또는 인덱스를 생성 할 수 있습니다. InnoDB 플러그인에는 이러한 조건을 방지하고 데이터베이스 파일과 InnoDB 버전 간의 호환성을 유지하는 데 도움이되는 새로운 메커니즘이 도입되었습니다.

나는 노예의 데이터를 폐기 할 것입니다. 사실, 나는 데이터의 논리적 덤프 (mysqldump)를 가져 와서 무차별 강제를 사용합니다.

  • 슬레이브에서 InnoDB를 사용하는 모든 데이터베이스 삭제
  • 슬레이브에서 MySQL 종료
  • 슬레이브에서 ibdata1, ib_logfile0 및 ib_logfile1을 삭제합니다.
  • 슬레이브에서 mysql을 시작하여 ibdata1, ib_logfile0 및 ib_logfile1을 다시 생성하십시오.
  • 마스터에서 슬레이브로 데이터를 mysqldump

게시 된 원래의 답변은 '구식 학교'로 간주됩니다. 그러나이 경우에는 .ibd 및 / 또는 ibdata1에서 사용중인 파일 형식을 확실히 살펴볼 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.