Jak se poškodí tabulky MySQL? Existuje mnoho způsobů, jak zkazit datové soubory. Poškození je často způsobeno vadami základní platformy, na kterou se MySQL spoléhá při ukládání a získávání dat – diskový subsystém, řadiče, komunikační kanály, ovladače, firmware nebo jiné hardwarové chyby. K poškození dat může také dojít, pokud se démon serveru MySQL náhle restartuje nebo se váš server restartuje kvůli havárii jiných komponent operačního systému. Pokud byla instance databáze uprostřed zápisu dat na disk, mohla by data zapsat částečně, což může skončit s kontrolním součtem stránky, který je jiný, než se očekávalo. V MySQL se také vyskytly chyby, takže i když je hardware serveru v pořádku, může způsobit poškození samotné MySQL.
Když se data MySQL poškodí, obvykle se doporučuje obnovit je z poslední zálohy, přejít na server DR nebo odstranit postižený uzel, pokud máte cluster Galera, aby okamžitě obsluhoval data z jiných uzlů. V některých případech nemůžete – pokud tam záloha není, cluster nebyl nikdy nastaven, vaše replikace je mimo provoz na velmi dlouhou dobu nebo procedura DR nebyla nikdy testována. I když máte zálohu, možná budete chtít provést nějaké akce a pokusit se o obnovu, protože návrat online může trvat kratší dobu.
MyISAM, zlý a ošklivý
InnoDB je odolnější vůči chybám než MyISAM. InnoDB má funkce auto_recovery a je mnohem bezpečnější ve srovnání se starším jádrem MyISAM.
Tabulky MyISAM se mohou snadno poškodit, když dojde k velkému množství zápisů a na této tabulce dojde k mnoha zámkům. Úložný stroj „zapisuje“ data do mezipaměti systému souborů, což může nějakou dobu trvat, než se vyprázdní na disk. Pokud se tedy váš server náhle restartuje, ztratí se nějaké neznámé množství dat v mezipaměti. To je obvyklý způsob poškození dat MyISAM. Doporučuje se migrovat z MyISAM na InnoDB, ale mohou nastat případy, kdy to není možné.
Primum non nocere, záloha
Než se pokusíte opravit poškozené tabulky, měli byste nejprve zálohovat soubory databáze. Ano, je již rozbitý, ale je to proto, aby se minimalizovalo riziko možného dalšího poškození, které může být způsobeno operací obnovy. Neexistuje žádná záruka, že jakákoli vaše akce nepoškodí nedotčené datové bloky. Vynucení obnovy InnoDB s hodnotami vyššími než 4 může poškodit datové soubory, takže se ujistěte, že to uděláte s předchozí zálohou a ideálně na samostatnou fyzickou kopii databáze.
Chcete-li zálohovat všechny soubory ze všech databází, postupujte takto:
Zastavte server MySQL
service mysqld stop
Zadejte následující příkaz pro váš datadir.
cp -r /var/lib/mysql /var/lib/mysql_bkp
Poté, co máme záložní kopii datového adresáře, jsme připraveni začít s odstraňováním problémů.
Identifikace poškození dat
Protokol chyb je váš nejlepší přítel. Obvykle, když dojde k poškození dat, najdete příslušné informace (včetně odkazů na dokumentaci) v protokolu chyb. Pokud nevíte, kde se nachází, zkontrolujte my.cnf a proměnnou log_error, další podrobnosti najdete v tomto článku https://dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration. html. Co byste také měli vědět, je typ vašeho úložiště. Tyto informace naleznete v protokolu chyb nebo v information_schema.
mysql> select table_name,engine from information_schema.tables where table_name = '<TABLE>' and table_schema = '<DATABASE>';
Hlavními nástroji/příkazy pro diagnostiku problémů s poškozením dat jsou CHECK TABLE, REPAIR TABLE a myisamchk. Klient mysqlcheck provádí údržbu tabulek:kontroluje, opravuje (MyISAM), optimalizuje nebo analyzuje tabulky za běhu MySQL.
mysqlcheck -uroot -p <DATABASE>
Nahraďte DATABASE názvem databáze a TABLE nahraďte názvem tabulky, kterou chcete zkontrolovat:
mysqlcheck -uroot -p <DATABASE> <TABLE>
Mysqlcheck zkontroluje zadanou databázi a tabulky. Pokud tabulka projde kontrolou, mysqlcheck pro tabulku zobrazí OK.
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
Problémy s poškozením dat mohou také souviset s problémy s oprávněními. V některých případech může OS přepnout bod připojení do režimu pouze pro čtení kvůli problémům s R/W nebo to může být způsobeno uživatelem, který omylem změnil vlastnictví datových souborů. V takových případech naleznete relevantní informace v protokolu chyb.
[[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
Záznam v protokolu chyb
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.
Obnova tabulky InnoDB
Pokud pro databázovou tabulku používáte úložiště InnoDB, můžete spustit proces obnovy InnoDB.
Chcete-li povolit automatické obnovení MySQL, musí být povolena možnost innodb_force_recovery. Innodb_force_recovery vynutí spuštění InnoDB a zároveň zabrání spuštění operací na pozadí, abyste mohli vypsat své tabulky.
Chcete-li to provést, otevřete soubor my.cnf a do sekce [mysqld] přidejte následující řádek:
[mysqld]
innodb_force_recovery=1
service mysql restart
Měli byste začít od innodb_force_recovery=1, uložit změny do souboru my.cnf a poté restartovat server MySQL pomocí příkazu vhodného pro váš operační systém. Pokud jste schopni vypsat vaše tabulky s hodnotou innodb_force_recovery 3 nebo méně, pak jste relativně v bezpečí. V mnoha případech budete muset přejít na 4 a jak již víte, může to poškodit data.
[mysqld]
innodb_force_recovery=1
service mysql restart
V případě potřeby změňte na vyšší hodnotu, šest je maximum a nejnebezpečnější.
Jakmile budete moci spustit databázi, zadejte následující příkaz pro export všech databází do souboru databases.sql:
mysqldump --all-databases --add-drop-database --add-drop-table > dump.sql
Spusťte mysql a poté zkuste zrušit postiženou databázi nebo databáze pomocí příkazu DROP DATABASE. Pokud MySQL nedokáže zrušit databázi, můžete ji po zastavení serveru MySQL ručně odstranit pomocí níže uvedených kroků.
service mysqld stop
Pokud se vám nepodařilo databázi zrušit, zadejte následující příkazy a odstraňte ji ručně.
cd /var/lib/mysql
rm -rf <DATABASE>
Ujistěte se, že jste nevymazali interní adresáře databází.
Až budete hotovi, zakomentujte následující řádek v [mysqld], abyste deaktivovali režim obnovy InnoDB.
#innodb_force_recovery=...
Uložte změny do souboru my.cnf a poté spusťte server MySQL
service mysqld start
Chcete-li obnovit databáze ze záložního souboru, který jste vytvořili v kroku 5, zadejte následující příkaz:
mysql> tee import_database.log
mysql> source dump.sql
Oprava MyISAM
Pokud mysqlcheck hlásí chybu pro tabulku, opravte ji zadáním příkazu mysqlcheck s příznakem -repair. Možnost opravy mysqlcheck funguje, když je server v provozu.
mysqlcheck -uroot -p -r <DATABASE> <TABLE>
Pokud je server mimo provoz a mysqlcheck nemůže z jakéhokoli důvodu opravit vaši tabulku, stále máte možnost provést obnovu přímo u souborů pomocí myisamchk. S myisamchk se musíte ujistit, že server nemá otevřené tabulky.
Zastavte MySQL
service mysqld stop
cd /var/lib/mysql
Přejděte do adresáře, kde se nachází databáze.
cd /var/lib/mysql/employees
myisamchk <TABLE>
Chcete-li zkontrolovat všechny tabulky v databázi, zadejte následující příkaz:
myisamchk *.MYI
Pokud předchozí příkaz nefunguje, můžete zkusit odstranit dočasné soubory, které mohou bránit správnému spuštění myisamchku. Chcete-li to provést, přejděte zpět do adresáře data dir a spusťte následující příkaz:
ls */*.TMD
Pokud jsou uvedeny nějaké soubory .TMD, odstraňte je:
rm */*.TMD
Poté znovu spusťte myisamchk.
Chcete-li se pokusit o opravu tabulky, spusťte následující příkaz a nahraďte TABLE názvem tabulky, kterou chcete opravit:
myisamchk --recover <TABLE>
Restartujte server MySQL
service mysqld start
Jak se vyhnout ztrátě dat
Existuje několik věcí, které můžete udělat, abyste minimalizovali riziko neobnovitelných dat. Především zálohy. Problém záloh je v tom, že je někdy lze přehlédnout. Pro zálohy plánované pomocí cron obvykle píšeme obalové skripty, které detekují problémy v protokolu zálohování, ale to nezahrnuje případy, kdy se zálohování vůbec nespustilo. Cron může někdy viset a často na něm není nastaveno sledování. Dalším potenciálním problémem může být případ, kdy záloha nebyla nikdy nastavena. Osvědčeným postupem je spouštět sestavy ze samostatného nástroje, který analyzuje stav zálohování a informuje vás o chybějících plánech zálohování. K tomu můžete použít ClusterControl nebo napsat své vlastní programy.
Hlášení provozní zálohy ClusterControlChcete-li snížit dopad možného poškození dat, měli byste vždy uvažovat o clusterových systémech. Je jen otázkou času, kdy databáze spadne nebo se poškodí, takže je dobré mít kopii, na kterou můžete přejít. Může to být replikace Master / Slave. Zde je důležitým aspektem bezpečné automatické obnovení, aby se minimalizovala složitost přepnutí a minimalizovala se doba obnovení (RTO).
Funkce automatického obnovení ClusterControl