Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Baza danych MySQL jest uszkodzona... Co mam teraz zrobić?

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 ClusterControl

Aby 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
  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. BŁĄD 1452:Nie można dodać lub zaktualizować wiersza podrzędnego:ograniczenie klucza obcego nie powiodło się

  2. MySQL:Odmowa dostępu dla użytkownika 'test'@'localhost' (przy użyciu hasła:TAK) z wyjątkiem użytkownika root

  3. Wolny czas startu MySQL w trybie GTID? Problemem może być rozmiar pliku dziennika binarnego

  4. Funkcja MySQL LOG2() – Zwróć logarytm Base-2 wartości

  5. Jak odbudować niespójny serwer MySQL Slave?