W jaki sposób tabele MySQL ulegają uszkodzeniu? Istnieje wiele sposobów na zepsucie plików danych. Często uszkodzenie jest spowodowane wadami podstawowej platformy, na której MySQL opiera się do przechowywania i pobierania danych - podsystemu dysku, kontrolerów, kanałów komunikacyjnych, sterowników, oprogramowania układowego lub innych usterek sprzętowych. Uszkodzenie danych może również wystąpić w przypadku nagłego ponownego uruchomienia demona serwera MySQL lub ponownego uruchomienia serwera z powodu awarii innych składników systemu operacyjnego. Jeśli instancja bazy danych była w trakcie zapisywania danych na dysk, może częściowo zapisać dane, co może skończyć się sumą kontrolną strony inną niż oczekiwana. Wystąpiły również błędy w MySQL, więc nawet jeśli sprzęt serwera jest w porządku, sam MySQL może powodować uszkodzenia.
Zwykle, gdy dane MySQL ulegną uszkodzeniu, zaleca się przywrócenie ich z ostatniej kopii zapasowej, przełączenie się na serwer DR lub usunięcie węzła, którego dotyczy problem, jeśli masz klaster Galera do natychmiastowego udostępniania danych z innych węzłów. W niektórych przypadkach nie jest to możliwe — jeśli nie ma kopii zapasowej, klaster nigdy nie został skonfigurowany, replikacja nie działa przez bardzo długi czas lub procedura DR nie została przetestowana. Nawet jeśli masz kopię zapasową, nadal możesz chcieć podjąć pewne działania, aby spróbować odzyskać dane, ponieważ powrót do trybu online może zająć mniej czasu.
MyISAM, zły i brzydki
InnoDB jest bardziej odporny na błędy niż MyISAM. InnoDB ma funkcje auto_recovery i jest znacznie bezpieczniejszy w porównaniu ze starszym silnikiem MyISAM.
Tabele MyISAM mogą łatwo ulec uszkodzeniu, gdy dzieje się dużo zapisów i występuje wiele blokad na tej tabeli. Silnik pamięci masowej „zapisuje” dane w pamięci podręcznej systemu plików, co może zająć trochę czasu, zanim zostaną opróżnione na dysk. Dlatego też, jeśli serwer zostanie nagle uruchomiony ponownie, pewna nieznana ilość danych w pamięci podręcznej zostanie utracona. Jest to typowy sposób na uszkodzenie danych MyISAM. Zaleca się migrację z MyISAM do InnoDB, ale mogą wystąpić przypadki, w których nie jest to możliwe.
Primum non nocere, kopia zapasowa
Przed przystąpieniem do naprawy uszkodzonych tabel należy najpierw wykonać kopię zapasową plików bazy danych. Tak, jest już zepsuty, ale ma to na celu zminimalizowanie ryzyka ewentualnych dalszych uszkodzeń, które mogą być spowodowane operacją odzyskiwania. Nie ma gwarancji, że jakiekolwiek podjęte działanie nie zaszkodzi nietkniętym blokom danych. Wymuszanie odzyskiwania InnoDB z wartościami większymi niż 4 może uszkodzić pliki danych, więc upewnij się, że zrobisz to z wcześniejszą kopią zapasową, a najlepiej na osobnej fizycznej kopii bazy danych.
Aby utworzyć kopię zapasową wszystkich plików ze wszystkich baz danych, wykonaj następujące czynności:
Zatrzymaj serwer MySQL
service mysqld stop
Wpisz następujące polecenie dla swojego katalogu danych.
cp -r /var/lib/mysql /var/lib/mysql_bkp
Po utworzeniu kopii zapasowej katalogu danych jesteśmy gotowi do rozwiązywania problemów.
Identyfikacja uszkodzenia danych
Dziennik błędów jest twoim najlepszym przyjacielem. Zwykle w przypadku uszkodzenia danych w dzienniku błędów znajdują się odpowiednie informacje (w tym łącza do dokumentacji). Jeśli nie wiesz, gdzie się znajduje, sprawdź my.cnf i zmienną log_error, więcej szczegółów znajdziesz w tym artykule https://dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration. html. Powinieneś również wiedzieć, jaki typ silnika pamięci masowej. Możesz znaleźć te informacje w dzienniku błędów lub w information_schema.
mysql> select table_name,engine from information_schema.tables where table_name = '<TABLE>' and table_schema = '<DATABASE>';
Główne narzędzia/polecenia do diagnozowania problemów z uszkodzeniem danych to CHECK TABLE, REPAIR TABLE i myisamchk. Klient mysqlcheck zajmuje się obsługą tabel:sprawdza, naprawia (MyISAM), optymalizuje lub analizuje tabele podczas działania MySQL.
mysqlcheck -uroot -p <DATABASE>
Zastąp DATABASE nazwą bazy danych, a TABLE nazwą tabeli, którą chcesz sprawdzić:
mysqlcheck -uroot -p <DATABASE> <TABLE>
Mysqlcheck sprawdza określoną bazę danych i tabele. Jeśli tabela przejdzie pomyślnie test, mysqlcheck wyświetli OK dla tabeli.
employees.departments OK
employees.dept_emp OK
employees.dept_manager OK
employees.employees OK
Employees.salaries
Warning : Tablespace is missing for table 'employees/salaries'
Error : Table 'employees.salaries' doesn't exist in engine
status : Operation failed
employees.titles OK
Problemy z uszkodzeniem danych mogą być również związane z problemami z uprawnieniami. W niektórych przypadkach system operacyjny może przełączyć punkt montowania w tryb tylko do odczytu z powodu problemów z zapisem/zapisem lub może to być spowodowane przez użytkownika, który przypadkowo zmienił właściciela plików danych. W takich przypadkach odpowiednie informacje znajdziesz w dzienniku błędów.
[[email protected] employees]# ls -rtla
...
-rw-rw----. 1 mysql mysql 28311552 05-10 06:24 titles.ibd
-rw-r-----. 1 root root 109051904 05-10 07:09 salaries.ibd
drwxr-xr-x. 7 mysql mysql 4096 05-10 07:12 ..
drwx------. 2 mysql mysql 4096 05-10 07:17 .
Klient MySQL
MariaDB [employees]> select count(*) from salaries;
ERROR 1932 (42S02): Table 'employees.salaries' doesn't exist in engine
Wpis w dzienniku błędów
2018-05-10 9:15:38 140703666226944 [ERROR] InnoDB: Failed to find tablespace for table `employees`.`salaries` in the cache. Attempting to load the tablespace with space id 9
2018-05-10 9:15:38 140703666226944 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2018-05-10 9:15:38 140703666226944 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2018-05-10 9:15:38 140703666226944 [ERROR] InnoDB: Cannot open datafile for read-only: './employees/salaries.ibd' OS error: 81
2018-05-10 9:15:38 140703666226944 [ERROR] InnoDB: Operating system error number 13 in a file operation.
2018-05-10 9:15:38 140703666226944 [ERROR] InnoDB: The error means mysqld does not have the access rights to the directory.
2018-05-10 9:15:38 140703666226944 [ERROR] InnoDB: Could not find a valid tablespace file for `employees/salaries`. Please refer to http://dev.mysql.com/doc/refman/5.7/en/innodb-troubleshooting-datadict.html for how to resolve the issue.
Odzyskiwanie tabeli InnoDB
Jeśli używasz silnika pamięci masowej InnoDB dla tabeli bazy danych, możesz uruchomić proces odzyskiwania InnoDB.
Aby włączyć automatyczne odzyskiwanie, MySQL wymaga włączenia opcji innodb_force_recovery. Innodb_force_recovery wymusza uruchomienie InnoDB, jednocześnie uniemożliwiając wykonywanie operacji w tle, dzięki czemu można zrzucić tabele.
Aby to zrobić, otwórz my.cnf i dodaj następujący wiersz do sekcji [mysqld]:
[mysqld]
innodb_force_recovery=1
service mysql restart
Powinieneś zacząć od innodb_force_recovery=1, zapisać zmiany w pliku my.cnf, a następnie ponownie uruchomić serwer MySQL, używając polecenia odpowiedniego dla Twojego systemu operacyjnego. Jeśli możesz zrzucić tabele z wartością innodb_force_recovery równą 3 lub mniejszą, jesteś względnie bezpieczny. W wielu przypadkach będziesz musiał wzrosnąć do 4, a jak już wiesz, może to uszkodzić dane.
[mysqld]
innodb_force_recovery=1
service mysql restart
W razie potrzeby zmień na wyższą wartość, sześć jest wartością maksymalną i najbardziej niebezpieczną.
Gdy będziesz w stanie uruchomić bazę danych, wpisz następujące polecenie, aby wyeksportować wszystkie bazy danych do pliku databases.sql:
mysqldump --all-databases --add-drop-database --add-drop-table > dump.sql
Uruchom mysql, a następnie spróbuj usunąć zaatakowaną bazę danych lub bazy danych za pomocą polecenia DROP DATABASE. Jeśli MySQL nie może usunąć bazy danych, możesz usunąć ją ręcznie, wykonując poniższe czynności po zatrzymaniu serwera MySQL.
service mysqld stop
Jeśli nie możesz usunąć bazy danych, wpisz następujące polecenia, aby usunąć ją ręcznie.
cd /var/lib/mysql
rm -rf <DATABASE>
Upewnij się, że nie usuwasz wewnętrznych katalogów bazy danych.
Po zakończeniu skomentuj następujący wiersz w [mysqld], aby wyłączyć tryb odzyskiwania InnoDB.
#innodb_force_recovery=...
Zapisz zmiany w pliku my.cnf, a następnie uruchom serwer MySQL
service mysqld start
Wpisz następujące polecenie, aby przywrócić bazy danych z pliku kopii zapasowej utworzonej w kroku 5:
mysql> tee import_database.log
mysql> source dump.sql
Naprawianie MyISAM
Jeśli mysqlcheck zgłosi błąd dla tabeli, wpisz polecenie mysqlcheck z flagą -repair, aby to naprawić. Opcja naprawy mysqlcheck działa, gdy serwer jest uruchomiony.
mysqlcheck -uroot -p -r <DATABASE> <TABLE>
Jeśli serwer nie działa i z jakiegoś powodu mysqlcheck nie może naprawić Twojej tabeli, nadal masz możliwość wykonania odzyskiwania bezpośrednio na plikach za pomocą myisamchk. W przypadku myisamchk musisz upewnić się, że na serwerze nie ma otwartych tabel.
Zatrzymaj MySQL
service mysqld stop
cd /var/lib/mysql
Przejdź do katalogu, w którym znajduje się baza danych.
cd /var/lib/mysql/employees
myisamchk <TABLE>
Aby sprawdzić wszystkie tabele w bazie danych, wpisz następujące polecenie:
myisamchk *.MYI
Jeśli poprzednie polecenie nie działa, możesz spróbować usunąć pliki tymczasowe, które mogą uniemożliwiać prawidłowe działanie myisamchk. Aby to zrobić, wróć do katalogu data dir, a następnie uruchom następujące polecenie:
ls */*.TMD
Jeśli na liście są jakieś pliki .TMD, usuń je:
rm */*.TMD
Następnie ponownie uruchom myisamchk.
Aby spróbować naprawić tabelę, wykonaj następujące polecenie, zastępując TABLE nazwą tabeli, którą chcesz naprawić:
myisamchk --recover <TABLE>
Zrestartuj serwer MySQL
service mysqld start
Jak uniknąć utraty danych
Jest kilka rzeczy, które możesz zrobić, aby zminimalizować ryzyko niemożliwych do odzyskania danych. Przede wszystkim kopie zapasowe. Problem z kopiami zapasowymi polega na tym, że czasami można je przeoczyć. W przypadku zaplanowanych przez cron kopii zapasowych zwykle piszemy skrypty opakowujące, które wykrywają problemy w dzienniku kopii zapasowych, ale nie obejmuje to przypadków, gdy tworzenie kopii zapasowej w ogóle się nie uruchomiło. Cron czasami może się zawiesić i często nie ma na nim ustawionego monitoringu. Innym potencjalnym problemem może być sytuacja, w której kopia zapasowa nigdy nie została skonfigurowana. Dobrą praktyką jest uruchamianie raportów z osobnego narzędzia, które przeanalizuje stan kopii zapasowej i poinformuje o brakujących harmonogramach kopii zapasowych. Możesz do tego użyć ClusterControl lub napisać własne programy.
Raport kopii zapasowej operacyjnej ClusterControlAby zmniejszyć wpływ możliwego uszkodzenia danych, należy zawsze brać pod uwagę systemy klastrowe. To tylko kwestia czasu, kiedy baza danych ulegnie awarii lub zostanie uszkodzona, dlatego dobrze jest mieć kopię, na którą można się przełączyć. Może to być replikacja Master/Slave. Ważnym aspektem jest tutaj bezpieczne automatyczne odzyskiwanie, aby zminimalizować złożoność przełączania i zminimalizować czas odzyskiwania (RTO).
Funkcje automatycznego odzyskiwania ClusterControl