sql >> Database >  >> RDS >> Mysql

Mijn MySQL-database is beschadigd... Wat moet ik nu doen?

Hoe worden MySQL-tabellen beschadigd? Er zijn veel manieren om gegevensbestanden te bederven. Corruptie is vaak te wijten aan defecten in het onderliggende platform, waarop MySQL vertrouwt om gegevens op te slaan en op te halen - schijfsubsysteem, controllers, communicatiekanalen, stuurprogramma's, firmware of andere hardwarefouten. Gegevenscorruptie kan ook optreden als de MySQL-serverdaemon plotseling opnieuw opstart, of als uw server opnieuw opstart vanwege een crash van andere OS-componenten. Als de database-instantie bezig was met het schrijven van gegevens naar schijf, zou het de gegevens gedeeltelijk kunnen wegschrijven, wat kan resulteren in een paginacontrolesom die anders is dan verwacht. Er zijn ook bugs in MySQL, dus zelfs als de serverhardware in orde is, kan MySQL zelf corruptie veroorzaken.

Wanneer MySQL-gegevens beschadigd raken, is de aanbeveling meestal om deze te herstellen vanaf de laatste back-up, over te schakelen naar de DR-server of het getroffen knooppunt te verwijderen als u een Galera-cluster hebt om gegevens onmiddellijk van andere knooppunten te leveren. In sommige gevallen kunt u dat niet - als de back-up er niet is, is het cluster nooit opgezet, is uw replicatie lange tijd niet beschikbaar geweest of is de DR-procedure nooit getest. Zelfs als je een back-up hebt, wil je misschien nog enkele acties ondernemen om het herstel te proberen, omdat het minder tijd kan kosten om weer online te zijn.

MijnISAM, het slechte en lelijke

InnoDB is fouttoleranter dan MyISAM. InnoDB heeft auto_recovery-functies en is veel veiliger in vergelijking met de oudere MyISAM-engine.

MyISAM-tabellen kunnen gemakkelijk beschadigd raken wanneer er veel wordt geschreven en er veel vergrendelingen op die tafel plaatsvinden. De opslagengine "schrijft" gegevens naar de cache van het bestandssysteem, wat enige tijd kan duren voordat ze naar de schijf zijn gewist. Als uw server plotseling opnieuw opstart, gaat er dus een onbekende hoeveelheid gegevens in de cache verloren. Dat is een gebruikelijke manier om MyISAM-gegevens te beschadigen. De aanbeveling is om te migreren van MyISAM naar InnoDB, maar er kunnen gevallen zijn waarin dit niet mogelijk is.

Primum non nocere, de back-up

Voordat u beschadigde tabellen probeert te herstellen, moet u eerst uw databasebestanden back-uppen. Ja, het is al kapot, maar dit is om het risico op mogelijke verdere schade die kan worden veroorzaakt door een hersteloperatie te minimaliseren. Er is geen garantie dat enige actie die u onderneemt geen schade toebrengt aan ongerepte gegevensblokken. Het forceren van InnoDB-herstel met waarden groter dan 4 kan gegevensbestanden beschadigen, dus zorg ervoor dat u dit doet met een voorafgaande back-up en idealiter op een afzonderlijke fysieke kopie van de database.

Volg deze stappen om een ​​back-up te maken van alle bestanden uit al uw databases:

Stop de MySQL-server

service mysqld stop

Typ de volgende opdracht voor uw datadir.

cp -r /var/lib/mysql /var/lib/mysql_bkp

Nadat we een reservekopie van de gegevensmap hebben, zijn we klaar om te beginnen met het oplossen van problemen.

Identificatie van gegevenscorruptie

Het foutenlogboek is je beste vriend. Wanneer gegevenscorruptie plaatsvindt, vindt u meestal relevante informatie (inclusief koppelingen naar documentatie) in het foutenlogboek. Als u niet weet waar het zich bevindt, controleer dan my.cnf en variabele log_error, voor meer details raadpleegt u dit artikel https://dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration. html. Wat u ook moet weten, is uw type opslagengine. U kunt deze informatie vinden in het foutenlogboek of in information_schema.

mysql> select table_name,engine from information_schema.tables where table_name = '<TABLE>' and table_schema = '<DATABASE>';

De belangrijkste tools/commando's om problemen met datacorruptie te diagnosticeren zijn CHECK TABLE, REPAIR TABLE en myisamchk. De mysqlcheck-client voert tabelonderhoud uit:het controleert, repareert (MyISAM), optimaliseert of analyseert tabellen terwijl MySQL actief is.

mysqlcheck -uroot -p <DATABASE>

Vervang DATABASE door de naam van de database en vervang TABLE door de naam van de tabel die u wilt controleren:

mysqlcheck -uroot -p <DATABASE> <TABLE>

Mysqlcheck controleert de opgegeven database en tabellen. Als een tafel de controle doorstaat, geeft mysqlcheck OK weer voor de tafel.

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

Problemen met gegevenscorruptie kunnen ook verband houden met toestemmingsproblemen. In sommige gevallen kan het besturingssysteem het koppelpunt overschakelen naar de alleen-lezen modus vanwege R/W-problemen of dit kan worden veroorzaakt door een gebruiker die per ongeluk het eigendom van de gegevensbestanden heeft gewijzigd. In dergelijke gevallen vindt u relevante informatie in het foutenlogboek.

[[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 .

MySQL-client

MariaDB [employees]> select count(*) from salaries;
ERROR 1932 (42S02): Table 'employees.salaries' doesn't exist in engine

Invoer in het foutenlogboek

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.

InnoDB-tabel herstellen

Als u de InnoDB-opslagengine voor een databasetabel gebruikt, kunt u het InnoDB-herstelproces uitvoeren.
Om automatisch herstel in te schakelen, moet MySQL de innodb_force_recovery-optie inschakelen. Innodb_force_recovery dwingt InnoDB om op te starten, terwijl wordt voorkomen dat achtergrondbewerkingen worden uitgevoerd, zodat u uw tabellen kunt dumpen.

Open hiervoor my.cnf en voeg de volgende regel toe aan de sectie [mysqld]:

[mysqld]
innodb_force_recovery=1
service mysql restart

U moet beginnen met innodb_force_recovery=1, de wijzigingen opslaan in het my.cnf-bestand en vervolgens de MySQL-server opnieuw opstarten met de juiste opdracht voor uw besturingssysteem. Als je in staat bent om je tabellen te dumpen met een innodb_force_recovery waarde van 3 of minder, dan ben je relatief veilig. In veel gevallen zul je tot 4 moeten gaan en zoals je al weet, kan dat gegevens beschadigen.

[mysqld]
innodb_force_recovery=1
service mysql restart

Verander indien nodig naar de hogere waarde, zes is het maximum en het gevaarlijkst.

Zodra u uw database kunt starten, typt u de volgende opdracht om alle databases naar het bestand databases.sql te exporteren:

mysqldump --all-databases --add-drop-database --add-drop-table > dump.sql

Start mysql en probeer vervolgens de betrokken database of databases te verwijderen met de opdracht DROP DATABASE. Als MySQL een database niet kan verwijderen, kunt u deze handmatig verwijderen met behulp van de onderstaande stappen nadat u de MySQL-server hebt gestopt.

service mysqld stop

Als u een database niet kunt verwijderen, typt u de volgende opdrachten om deze handmatig te verwijderen.

cd /var/lib/mysql
rm -rf <DATABASE>

Zorg ervoor dat u de interne databasedirectory's niet verwijdert.
Als u klaar bent, geeft u commentaar op de volgende regel in de [mysqld] om de InnoDB-herstelmodus uit te schakelen.

#innodb_force_recovery=...

Sla de wijzigingen op in het my.cnf-bestand en start vervolgens de MySQL-server

service mysqld start

Typ de volgende opdracht om de databases te herstellen van het back-upbestand dat u in stap 5 hebt gemaakt:

mysql> tee import_database.log
mysql> source dump.sql

MijnISAM repareren

Als mysqlcheck een fout voor een tabel meldt, typt u de opdracht mysqlcheck met de vlag -repair om deze te herstellen. De mysqlcheck-reparatieoptie werkt terwijl de server actief is.

mysqlcheck -uroot -p -r <DATABASE> <TABLE>

Als de server down is en mysqlcheck om welke reden dan ook uw tabel niet kan repareren, heeft u nog steeds een optie om bestanden direct te herstellen met myisamchk. Met myisamchk moet je ervoor zorgen dat de server de tafels niet open heeft staan.

Stop de MySQL

service mysqld stop
cd /var/lib/mysql

Ga naar de directory waar de database zich bevindt.

cd /var/lib/mysql/employees
myisamchk <TABLE>

Typ de volgende opdracht om alle tabellen in een database te controleren:

myisamchk *.MYI

Als de vorige opdracht niet werkt, kunt u proberen tijdelijke bestanden te verwijderen die mogelijk verhinderen dat myisamchk correct wordt uitgevoerd. Om dit te doen, gaat u terug naar de map data dir en voert u de volgende opdracht uit:

ls */*.TMD

Als er .TMD-bestanden in de lijst staan, verwijder ze dan:

rm */*.TMD

Voer vervolgens myisamchk opnieuw uit.

Om te proberen een tabel te repareren, voert u de volgende opdracht uit, waarbij u TABLE vervangt door de naam van de tabel die u wilt repareren:

myisamchk --recover <TABLE>

Start de MySQL-server opnieuw

service mysqld start

Hoe gegevensverlies te voorkomen

Er zijn verschillende dingen die u kunt doen om het risico op onherstelbare gegevens te minimaliseren. Allereerst back-ups. Het probleem met back-ups is dat ze soms over het hoofd worden gezien. Voor cron-geplande back-ups schrijven we meestal wrapper-scripts die problemen detecteren in het back-uplogboek, maar dat geldt niet voor gevallen waarin de back-up helemaal niet is gestart. Cron kan soms hangen en vaak staat er geen monitoring op. Een ander potentieel probleem kan het geval zijn wanneer de back-up nooit is ingesteld. Het is een goede gewoonte om rapporten uit te voeren vanuit een aparte tool die de back-upstatus analyseert en u informeert over ontbrekende back-upschema's. U kunt daarvoor ClusterControl gebruiken of uw eigen programma's schrijven.

ClusterControl operationeel back-uprapport

Om de impact van mogelijke datacorruptie te verminderen, moet u altijd geclusterde systemen overwegen. Het is slechts een kwestie van tijd wanneer de database crasht of beschadigd raakt, dus het is goed om een ​​kopie te hebben waarnaar u kunt overschakelen. Het kan master/slave-replicatie zijn. Het belangrijkste aspect hier is een veilig automatisch herstel om de complexiteit van de omschakeling te minimaliseren en de hersteltijd (RTO) te minimaliseren.

ClusterControl-functies voor automatisch herstel
  1. 3 manieren om NULL te vervangen door "N/A" in SQLite

  2. Gegevenswijzigingen onder Read Committed Snapshot Isolation

  3. Database subsetting – Hoe in IRI Voracity

  4. Databasecorruptie in MS Access en hoe ermee om te gaan