sql >> Databasteknik >  >> RDS >> Mysql

Min MySQL-databas är skadad... Vad gör jag nu?

Hur skadas MySQL-tabeller? Det finns många sätt att förstöra datafiler. Ofta beror korruption på defekter i den underliggande plattformen, som MySQL förlitar sig på för att lagra och hämta data - diskundersystem, kontroller, kommunikationskanaler, drivrutiner, firmware eller andra hårdvarufel. Datakorruption kan också uppstå om MySQL-serverdemonen startar om plötsligt, eller om din server startar om på grund av en krasch av andra OS-komponenter. Om databasinstansen var mitt uppe i att skriva data till disk, kan den skriva data delvis vilket kan sluta med en sidkontrollsumma som är annorlunda än förväntat. Det har också förekommit buggar i MySQL så även om serverns hårdvara är ok kan MySQL i sig orsaka korruption.

Vanligtvis när MySQL-data skadas är rekommendationen att återställa den från den senaste säkerhetskopian, byta till DR-server eller ta ner den drabbade noden om du har Galera-kluster för att servera data direkt från andra noder. I vissa fall kan du inte - om säkerhetskopian inte finns där, klustret aldrig konfigurerats, din replikering är nere under mycket lång tid eller DR-proceduren testades aldrig. Även om du har en säkerhetskopia kanske du fortfarande vill vidta några åtgärder för att försöka återställa eftersom det kan ta kortare tid att komma tillbaka online.

MyISAM, den dåliga och fula

InnoDB är mer feltolerant än MyISAM. InnoDB har auto_recovery-funktioner och är mycket säkrare jämfört med den äldre MyISAM-motorn.

MyISAM-tabeller kan lätt skadas när många skrivningar händer och många låsningar händer på det bordet. Lagringsmotorn "skriver" data till filsystemets cache, vilket kan ta lite tid innan det spolas till disken. Om din server startar om plötsligt går därför en okänd mängd data i cachen förlorad. Det är ett vanligt sätt för MyISAM-data att skadas. Rekommendationen är att migrera från MyISAM till InnoDB, men det kan finnas fall där detta inte är möjligt.

Primum non nocere, backupen

Innan du försöker reparera skadade tabeller bör du säkerhetskopiera dina databasfiler först. Ja, den är redan trasig men detta är för att minimera risken för eventuell ytterligare skada som kan orsakas av en återställningsoperation. Det finns ingen garanti för att någon åtgärd du vidtar inte kommer att skada orörda datablock. Att tvinga fram InnoDB-återställning med värden större än 4 kan skada datafiler, så se till att du gör det med föregående säkerhetskopiering och helst på en separat fysisk kopia av databasen.

För att säkerhetskopiera alla filer från alla dina databaser, följ dessa steg:

Stoppa MySQL-servern

service mysqld stop

Skriv följande kommando för din datadir.

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

När vi har en säkerhetskopia av datakatalogen är vi redo att börja felsöka.

Identifiering av datakorruption

Felloggen är din bästa vän. Vanligtvis, när datakorruption inträffar, hittar du relevant information (inklusive länkar till dokumentation) i felloggen. Om du inte vet var den finns, kontrollera my.cnf och variabel log_error, för mer information kolla den här artikeln https://dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration. html. Vad du också bör veta är din lagringsmotortyp. Du kan hitta denna information i felloggen eller i informationsschema.

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

De viktigaste verktygen/kommandona för att diagnostisera problem med datakorruption är CHECK TABLE, REPAIR TABLE och myisamchk. Mysqlcheck-klienten utför tabellunderhåll:Den kontrollerar, reparerar (MyISAM), optimerar eller analyserar tabeller medan MySQL körs.

mysqlcheck -uroot -p <DATABASE>

Ersätt DATABASE med namnet på databasen och ersätt TABLE med namnet på tabellen som du vill kontrollera:

mysqlcheck -uroot -p <DATABASE> <TABLE>

Mysqlcheck kontrollerar den angivna databasen och tabellerna. Om en tabell klarar kontrollen visar mysqlcheck OK för tabellen.

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

Problem med datakorruption kan också vara relaterade till behörighetsfrågor. I vissa fall kan OS byta monteringspunkt till skrivskyddat läge på grund av R/W-problem eller så kan detta orsakas av en användare som av misstag ändrade äganderätten till datafilerna. I sådana fall hittar du relevant information i felloggen.

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

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

Felloggpost

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.

Återställer InnoDB-tabellen

Om du använder InnoDB-lagringsmotorn för en databastabell kan du köra InnoDB-återställningsprocessen.
För att aktivera automatisk återställning måste MySQL-alternativet innodb_force_recovery vara aktiverat. Innodb_force_recovery tvingar InnoDB att starta upp samtidigt som det förhindrar bakgrundsoperationer från att köras, så att du kan dumpa dina tabeller.

För att göra detta, öppna my.cnf och lägg till följande rad i avsnittet [mysqld]:

[mysqld]
innodb_force_recovery=1
service mysql restart

Du bör börja från innodb_force_recovery=1 och spara ändringarna i filen my.cnf och sedan starta om MySQL-servern med lämpligt kommando för ditt operativsystem. Om du kan dumpa dina tabeller med ett innodb_force_recovery-värde på 3 eller mindre, så är du relativt säker. I många fall måste du gå upp till 4 och som du redan vet kan det skada data.

[mysqld]
innodb_force_recovery=1
service mysql restart

Om det behövs ändras till det högre värdet, sex är det högsta och farligaste.

När du kan starta din databas, skriv följande kommando för att exportera alla databaser till filen databases.sql:

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

Starta mysql och försök sedan släppa den eller de berörda databaserna med kommandot DROP DATABASE. Om MySQL inte kan släppa en databas kan du radera den manuellt med hjälp av stegen nedan efter att du har stoppat MySQL-servern.

service mysqld stop

Om du inte kunde släppa en databas, skriv följande kommandon för att radera den manuellt.

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

Se till att du inte tar bort de interna databaskatalogerna.
När du är klar, kommentera följande rad i [mysqld] för att inaktivera InnoDB återställningsläge.

#innodb_force_recovery=...

Spara ändringarna i filen my.cnf och starta sedan MySQL-servern

service mysqld start

Skriv följande kommando för att återställa databaserna från säkerhetskopian som du skapade i steg 5:

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

Reparerar MyISAM

Om mysqlcheck rapporterar ett fel för en tabell, skriv kommandot mysqlcheck med -repair-flaggan för att fixa det. Reparationsalternativet mysqlcheck fungerar medan servern är igång.

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

Om servern är nere och mysqlcheck av någon anledning inte kan reparera din tabell, har du fortfarande möjlighet att utföra återställning direkt på filer med myisamchk. Med myisamchk måste du se till att servern inte har tabellerna öppna.

Stoppa MySQL

service mysqld stop
cd /var/lib/mysql

Byt till katalogen där databasen finns.

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

För att kontrollera alla tabeller i en databas, skriv följande kommando:

myisamchk *.MYI

Om det föregående kommandot inte fungerar kan du försöka ta bort temporära filer som kan hindra myisamchk från att köras korrekt. För att göra detta, byt tillbaka till data dir-katalogen och kör sedan följande kommando:

ls */*.TMD

Om det finns några .TMD-filer i listan, radera dem:

rm */*.TMD

Kör sedan myisamchk igen.

För att försöka reparera en tabell, kör följande kommando och ersätt TABLE med namnet på tabellen som du vill reparera:

myisamchk --recover <TABLE>

Starta om MySQL-servern

service mysqld start

Så undviker du dataförlust

Det finns flera saker du kan göra för att minimera risken för data som inte går att återställa. Först och främst säkerhetskopior. Problemet med säkerhetskopior är att de ibland kan förbises. För schemalagda säkerhetskopior av cron skriver vi vanligtvis omslagsskript som upptäcker problem i säkerhetskopieringsloggen, men det inkluderar inte fall då säkerhetskopieringen inte startade alls. Cron kan ibland hänga och ofta finns det ingen övervakningsuppsättning på den. Ett annat potentiellt problem kan vara fallet när säkerhetskopian aldrig konfigurerades. Den goda praxisen är att köra rapporter från ett separat verktyg som analyserar säkerhetskopieringsstatusen och informerar dig om saknade säkerhetskopieringsscheman. Du kan använda ClusterControl för det eller skriva dina egna program.

ClusterControl driftssäkerhetsrapport

För att minska effekten av eventuell datakorruption bör du alltid överväga klustrade system. Det är bara en tidsfråga när databasen kommer att krascha eller bli skadad, så det är bra att ha en kopia som du kan byta till. Det kan vara master/slav replikering. Den viktiga aspekten här är att ha säker automatisk återställning för att minimera komplexiteten i övergången och minimera återställningstiden (RTO).

ClusterControl automatisk återställningsfunktioner
  1. Använder MySQL-vyer

  2. 4 sätt att lista alla vyer i en MariaDB-databas

  3. Hur man lägger till standardbegränsning i MySQL

  4. PostgreSQL 'NOT IN' och underfråga