Jak rozpoznać uszkodzenie tabeli InnoDB?

24

Mam kilka tabel, które są podzielone na partycje i mają kilka indeksów na zreplikowanym slave. Po skopiowaniu migawki (zweryfikowanej jako bezpieczna) do nowego urządzenia podrzędnego i aktualizacji mysqld z 5.1.42 do 5.5.15 i ponownym uruchomieniu replikacji, pojawia się awaria InnoDB z komunikatem o błędzie „Nieprawidłowy wskaźnik ...”

Te błędy wystąpiły na 2 serwerach z innym sprzętem i systemem operacyjnym. Po bieganiu:

ALTER TABLE .... COALESCE PARTION n;

problem zniknął dla tego stołu.

Moje pytanie ma jednak większy zakres i brzmi: „Jak rozpoznać uszkodzenie tabeli InnoDB?” lub przeformułował „Jak oceniasz zdrowie tabeli InnoDB?” Czy „CHECK TABLE” jest jedynym dostępnym narzędziem do identyfikowania problemów przed awarią?

Nie jestem pewien, czy to ważne, ale wystąpiły awarie podczas uruchamiania: Wersja: „5.5.15-55-log” gniazdo: Port „/opt/mysql.sock”: 3306 Serwer Percona (GPL), wydanie rel21.0, wersja 158

randomx
źródło
2
Cześć Randy! Myślę, że odpowiedzi tutaj są wiarygodne - InnoDB zidentyfikowało własną korupcję. Może powinieneś sformułować swoje pytanie, dlaczego to, co robisz, spowodowałoby uszkodzenie InnoDB?
Morgan Tocker 30.09.11

Odpowiedzi:

18

Morgan daje do zrozumienia w swoim komentarzu, że InnoDB stale sprawdza uszkodzone strony, wykonując sumy kontrolne na stronach, które czyta. Jeśli InnoDB znajdzie niedopasowanie sumy kontrolnej, spowoduje awarię zatrzymania serwera.

Jeśli chcesz przyspieszyć ten proces (zamiast czekać, aż InnoDB przeczyta uszkodzoną stronę), możesz użyć innochecksum:

Ponieważ niedopasowania sumy kontrolnej spowodują, że InnoDB celowo zamknie działający serwer, może być preferowane użycie tego narzędzia zamiast czekania, aż serwer w trybie produkcyjnym napotka uszkodzone strony.

Ciekawe zastrzeżenie:

Innochecksum nie może być używany w plikach obszaru tabel, które serwer już otworzył. W przypadku takich plików należy użyć SPRAWDŹ TABELĘ, aby sprawdzić tabele w obszarze tabel.

Tak więc, ponieważ tabela online CHECK TABLEjest prawdopodobnie narzędziem (lub jak wskazano w innej odpowiedzi, mysqlcheck jeśli chcesz zrobić więcej niż jedną bazę danych naraz).

Jeśli możesz zamknąć bazę danych, możesz wymusić użycie sum kontrolnych innochecksum

Anegdota: w obszarze tabel o wielkości 29 GB (z innodb_file_per_table=1) ten skrypt zajął około 2 minut

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

Jako bonus, ponieważ korzystasz z Percony, zaimplementowali nową metodę szybkiej sumy kontrolnej innodb . Nigdy go nie użyłem, ale może to przyspieszyć proces.

Derek Downey
źródło
1
Spróbuję tutaj, wydaje się być rozwiązaniem @ Randymelder szuka +1
marcio
2
Serwer Percona ma kilka innych fajnych funkcji. Zobacz innodb_corrupt_table Activity percona.com/doc/percona-server/5.5/reliability/ ... (!!)
Morgan Tocker
@DTest: innochecksum jest właściwą drogą. Ten jest opiekunem. +1 !!!
RolandoMySQLDBA 30.09.11
@DTest: Czapki z głów przed tobą w tym dniu !!!!
RolandoMySQLDBA
@MorganTocker Ciekawe. Muszę zdobyć próżnię wiedzy i przeprowadzić badania nad perkoną
Derek Downey
6

OSTRZEŻENIE: przed wypróbowaniem którejkolwiek z tych instrukcji zdecydowanie zaleca się sprawdzenie, czy na wszelki wypadek znajduje się zdrowa kopia zapasowa bazy danych. (dzięki @Nick za ostrzeżenie)

Spróbuj użyć mysqlcheckpolecenia. Na terminalu:

mysqlcheck -u username -p --databases database1 database2

To polecenie wyświetli listę wszystkich tabel i status informujący, czy nastąpiło jakieś uszkodzenie:

table1  OK
table2  OK
table3  OK
tableN  OK

Dzięki temu będziesz już wiedział, które stoły musisz naprawić. Na wypadek, gdybyś chciał naprawić wszystko na raz:

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

Więcej informacji mysqlcheck: http://dev.mysql.com/doc/refman/5.0/en/mysqlcheck.html

Uwaga: otagowałeś swoje pytanie . Nie miałem pojęcia, co to było, więc poszukałem Google. Wygląda na to, że jest rozwidleniem MySQL, ale nie mam powodu sądzić, że polecenia są niezgodne (kciuki).


Ktoś wskazał mi ten przewodnik, który zawiera bardziej szczegółowe instrukcje dotyczące odzyskiwania bazy danych InnoDB w bardziej krytycznych sytuacjach, w których cała baza danych nie uruchamia się: http://www.softwareprojects.com/resources/programming/t-how-to-fix-mysql -database-myisam-innodb-1634.html

marcio
źródło
1
mysqlcheck jest synonimem „check table ...” -1
randomx 27.09.11
Nie prawda. Po pierwsze, mysqlcheck jest narzędziem wiersza poleceń, a CHECK TABLE jest instrukcją SQL (to tak, jakby porównać pomarańczowy z cytrynami). Ponadto NIE MOŻESZ sprawdzić całej bazy danych za pomocą CHECK TABLE bez uwzględnienia WSZYSTKICH nazw tabel w instrukcji SQL ( też nie byłby zbyt produktywny)
marcio
A mysqlcheck ma opcję - - automatycznej naprawy tabel, które są uszkodzone, podczas gdy SPRAWDŹ TABELĘ sprawdza tylko, czy tabele są uszkodzone, czy nie, ale nie może dokonać żadnej naprawy.
marcio
2
@randymelder - Mylisz się twierdząc, że mysqlcheck jest synonimem CHECK TABLE. Dokumentacja jesteś związana stwierdza: " mysqlcheckwykorzystuje SQL CHECK TABLE, REPAIR TABLE, ANALYZE TABLEoraz OPTIMIZE TABLEw wygodny sposób dla użytkownika Określa Które stwierdzenia wykorzystania do operacji, którą chcesz wykonać, a następnie przesyła sprawozdanie z serwerem w celu wykonania.. „ To nie jest synonim; jest to interfejs użytkownika do zbioru instrukcji.
Nick Chammas,
6

Zgodnie z MySQL 5.0 Certification Study Guide, Strona 443,444 Sekcja 30.4 :

Możesz sprawdzić tabele InnoDB za pomocą komendy CHECK TABLE lub programu klienckiego, który wystawi za ciebie instrukcję. Jeśli jednak występują problemy z tabelą InnoDB, nie można tego naprawić za pomocą TABELI NAPRAW, ponieważ ta instrukcja dotyczy tylko MyISAM.

Jeśli sprawdzenie tabeli wskazuje, że tabela InnoDB ma problemy, powinieneś być w stanie przywrócić tabelę do spójnego stanu poprzez zrzucenie jej za pomocą mysqldump, upuszczenie i odtworzenie z tego zrzutu.

W przypadku awarii serwera MySQL lub na hoście, na którym działa, niektóre tabele InnoDB mogą wymagać naprawy. Zwykle wystarczy zrestartować serwer, ponieważ silnik pamięci InnoDB wykonuje automatyczne odzyskiwanie w ramach sekwencji startowej. W rzadkich przypadkach serwer może się nie uruchomić z powodu niepowodzenia automatycznego odzyskiwania InnoDB. Jeśli tak się stanie, zastosuj następującą procedurę:

  • Zrestartuj serwer z opcją --innodb_force_recovery ustawioną na wartość w przedziale od 1 do 6. Wartości te wskazują na rosnący poziom ostrożności w celu uniknięcia awarii i zwiększający się poziom tolerancji na możliwe niespójności w odzyskanych tabelach. Dobra wartość na początek to 4.

  • Po uruchomieniu serwera z wartością --innodb_force_recovery ustawioną na wartość niezerową, InnoDB traktuje obszar tabel jako tylko do odczytu. W związku z tym powinieneś zrzucić tabele InnoDB z mysqldump, a następnie upuścić je, gdy opcja jest włączona. Następnie uruchom ponownie serwer bez opcji --innodb_force_recovery. Po uruchomieniu serwera odzyskaj tabele InnoDB z plików zrzutu.

  • Jeśli poprzednie kroki nie powiodą się, konieczne jest przywrócenie tabel InnoDB z poprzedniej kopii zapasowej.

Przeczytaj dokumentację MySQL na temat InnoDB Forced Recovery  

RolandoMySQLDBA
źródło
3
FWIW, przewodnik certyfikacji ma bardzo politycznie poprawną odpowiedź :) Jeśli sprawdzisz TABELĘ na tabeli InnoDB i faktycznie jest on uszkodzony, nigdy nie powróci jako „uszkodzony”, spowoduje to awarię serwera. Instrukcja jest prawie nieaktualna w InnoDB, ponieważ za każdym razem, gdy czytasz strony InnoDB, sprawdza, czy nie ma uszkodzeń (za pomocą sum kontrolnych strony).
Morgan Tocker
2

Zastanawiam się, co się stanie, jeśli ktoś użyje danych InnoDB utworzonych za pomocą wtyczki InnoDB, a następnie przełączy się na inną wersję InnoDB. Może to spowodować potencjalne uszkodzenie strony w oczach mysqld.

Zwróć uwagę na to, co Dokumentacja MySQL w formacie pliku InnoDB mówi o tej możliwości:

Ogólnie rzecz biorąc, nowsza wersja InnoDB może utworzyć tabelę lub indeks, których nie można bezpiecznie odczytać ani zapisać za pomocą poprzedniej wersji InnoDB bez ryzyka awarii, zawieszenia, błędnych wyników lub uszkodzeń. Wtyczka InnoDB wprowadza nowy mechanizm chroniący przed tymi warunkami i pomagający zachować kompatybilność plików bazy danych i wersji InnoDB.

Zeskrobałbym dane na niewolniku. W rzeczywistości użyłbym brutalnej siły, uzyskując logiczny zrzut (mysqldump) danych:

  • Upuść wszystkie bazy danych za pomocą InnoDB na slave
  • Zamknij mysql na slave
  • Usuń ibdata1, ib_logfile0 i ib_logfile1 na slave
  • Uruchom mysql na slave, pozwalając na odtworzenie ibdata1, ib_logfile0 i ib_logfile1
  • mysqldump dane z master do slave

Mój oryginalny anwser jest uważany za „starą szkołę”. Jednak w tym przypadku zdecydowanie zajrzałbym do formatów plików używanych przez .ibd i / lub ibdata1.

RolandoMySQLDBA
źródło