Serwer MySQL nie chce się uruchomić, w logach czytamy, że problemem jest błąd w strukturze InnoDB. Konkretnie, silnik wysypuje się na etapie odtwarzania zmian z undo log, czyli mówiąc po ludzku, na cofaniu transakcji, które nie zostały COMMITowane przed padem serwera. Co można w takiej sytuacji zrobić?

InnoDB udostępnia jeden, bardzo w tej sytuacji przydatny parametr – innodb_force_recovery. Przyjmuje on wartości od 0 do 6 a każda wartość powyżej 0 to ominięcie lub zignorowanie błędów na pewnym etapie procesu startu silnika. W szczególności, wartość 3 oznacza tyle, że w trakcie startu nie będą cofane transakcje. Zaczynamy więc od ustawienia tej zmiennej.

Ok, InnoDB wstało i działa w trybie “administracyjnym” – jak to się nazywa oficjalnie, nie wiem. W uproszczeniu, jest to tryb tylko do odczytu z tym wyjątkiem, że jest możliwość DROPowania całych baz danych. Tryb ten przydatny jest o tyle, że dzięki niemu mamy możliwość po pierwsze zdumpować problematyczną bazę danych, tak aby mieć najświeższe dane, oraz dwa, usunąć tą bazę, aby wyeliminować przyczynę problemu.

Zazwyczaj InnoDB w logach wskazuje, która baza i tabela są źródłem błędu. Jeśli nie, to pozostaje nam samodzielnie zlokalizować wszystkie bazy danych, które korzystają z silnika InnoDB, a następnie wykonać ich kopię.

W momencie, gdy dane mamy zrzucone a bazy wykasowane, przestawiamy wartość zmiennej innodb_force_recovery na 0 (na przykład komentując lub usuwając cały wpis z konfiguracji – wartość 0 jest wartością domyślną) i restartujemy serwer MySQL, tak aby działał w sposób normalny, z możliwością modyfikacji danych. Jeśli to się powiodło, wgrywamy usunięte poprzednio bazy InnoDB z possiadanych kopii. Teoretycznie problem został rozwiązany.

Niestety, ten sposób na poradzenie sobie nie jest sposobem idealnym. Po pierwsze, trzeba dane zrzucić i wgrać ponownie. To trwa. Po drugie, nie ma pewności czy problem się nie powtórzy. W opisywanym przypadku teoretycznie wystarczyłoby usunąć zawartość undo log, nie trzeba było kasować danych. Problem w tym, że nie zetknąłem się z narzędziami, które by to umożliwiały, a ręczne szukanie w plikach InnoDB nie jest najlepszym rozwiązaniem.
Jeśli któryś z Czytelników miał okazję taką operację wykonywać (czy to ręcznie, czy to automatycznie), proszę o komentarz. W tym przypadku (jak z resztą stosunkowo często) szybciej było wykonać dump/reload niż rozwiązywać problem na poziomie bebechów InnoDB.

Na szczęście, InnoDB jest stabilnym silnikiem i tego typu problemy zdarzają się bardzo rzadko.