sql >> Database teknologi >  >> RDS >> Mysql

Min MySQL-database er beskadiget... Hvad gør jeg nu?

Hvordan bliver MySQL-tabeller ødelagt? Der er mange måder at ødelægge datafiler på. Ofte skyldes korruption defekter i den underliggende platform, som MySQL er afhængig af til at lagre og hente data - diskundersystem, controllere, kommunikationskanaler, drivere, firmware eller andre hardwarefejl. Datakorruption kan også forekomme, hvis MySQL-serverdæmonen pludselig genstarter, eller din server genstarter på grund af et nedbrud af andre OS-komponenter. Hvis databaseinstansen var midt i at skrive data til disken, kunne den skrive dataene delvist, hvilket kan ende med en sidekontrolsum, der er anderledes end forventet. Der har også været fejl i MySQL, så selvom serverhardwaren er ok, kan MySQL selv forårsage korruption.

Normalt når MySQL-data bliver beskadiget, er anbefalingen at gendanne dem fra den sidste backup, skifte til DR-server eller fjerne den berørte node, hvis du har Galera-klynge til at betjene data med det samme fra andre noder. I nogle tilfælde kan du ikke - hvis sikkerhedskopien ikke er der, klyngen blev aldrig sat op, din replikering er nede i meget lang tid, eller DR-proceduren blev aldrig testet. Selvom du har en sikkerhedskopi, vil du måske stadig tage nogle handlinger for at forsøge at genoprette, da det kan tage kortere tid at komme online igen.

MyISAM, den dårlige og grimme

InnoDB er mere fejltolerant end MyISAM. InnoDB har auto_recovery-funktioner og er meget sikrere sammenlignet med den ældre MyISAM-motor.

MyISAM-tabeller kan nemt blive ødelagt, når der sker mange skrivninger, og der sker en masse låse på det bord. Lagermaskinen "skriver" data til filsystemets cache, hvilket kan tage noget tid, før det tømmes til disken. Derfor, hvis din server genstarter pludseligt, går en ukendt mængde data i cachen tabt. Det er en sædvanlig måde for MyISAM-data at blive beskadiget. Anbefalingen er at migrere fra MyISAM til InnoDB, men der kan være tilfælde, hvor dette ikke er muligt.

Primum non nocere, backup

Før du forsøger at reparere beskadigede tabeller, bør du først sikkerhedskopiere dine databasefiler. Ja, den er allerede gået i stykker, men dette er for at minimere risikoen for mulig yderligere skade, som kan være forårsaget af en genopretningsoperation. Der er ingen garanti for, at enhver handling, du foretager, ikke vil skade uberørte datablokke. At tvinge InnoDB-gendannelse med værdier større end 4 kan ødelægge datafiler, så sørg for, at du vil gøre det med forudgående sikkerhedskopiering og ideelt set på en separat fysisk kopi af databasen.

Følg disse trin for at sikkerhedskopiere alle filerne fra alle dine databaser:

Stop MySQL-serveren

service mysqld stop

Indtast følgende kommando for din datadir.

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

Når vi har en sikkerhedskopi af databiblioteket, er vi klar til at starte fejlfinding.

Identifikation af datakorruption

Fejlloggen er din bedste ven. Normalt, når datakorruption sker, vil du finde relevante oplysninger (inklusive links til dokumentation) i fejlloggen. Hvis du ikke ved, hvor den er placeret, så tjek my.cnf og variabel log_error, for flere detaljer se denne artikel https://dev.mysql.com/doc/refman/8.0/en/error-log-destination-configuration. html. Hvad du også bør vide, er din lagringsmotortype. Du kan finde disse oplysninger i fejlloggen eller i informationsskema.

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

De vigtigste værktøjer/kommandoer til at diagnosticere problemer med datakorruption er CHECK TABLE, REPAIR TABLE og myisamchk. Mysqlcheck-klienten udfører tabelvedligeholdelse:Den kontrollerer, reparerer (MyISAM), optimerer eller analyserer tabeller, mens MySQL kører.

mysqlcheck -uroot -p <DATABASE>

Erstat DATABASE med navnet på databasen, og erstat TABLE med navnet på den tabel, du vil kontrollere:

mysqlcheck -uroot -p <DATABASE> <TABLE>

Mysqlcheck kontrollerer den angivne database og tabeller. Hvis en tabel består kontrollen, viser mysqlcheck OK for 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

Problemer med datakorruption kan også være relateret til tilladelsesproblemer. I nogle tilfælde kan OS skifte monteringspunkt til skrivebeskyttet tilstand på grund af R/W-problemer, eller dette kan være forårsaget af en bruger, der ved et uheld ændrede ejerskab af datafilerne. I sådanne tilfælde vil du finde relevante oplysninger i fejlloggen.

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

Fejllogindtastning

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.

Gendannelse af InnoDB-tabel

Hvis du bruger InnoDB-lagringsmotoren til en databasetabel, kan du køre InnoDB-gendannelsesprocessen.
For at aktivere automatisk gendannelse skal MySQL-indodb_force_recovery-indstillingen være aktiveret. Innodb_force_recovery tvinger InnoDB til at starte op, mens det forhindrer baggrundshandlinger i at køre, så du kan dumpe dine tabeller.

For at gøre dette skal du åbne my.cnf og tilføje følgende linje til [mysqld]-sektionen:

[mysqld]
innodb_force_recovery=1
service mysql restart

Du skal starte fra innodb_force_recovery=1 og gemme ændringerne i filen my.cnf og derefter genstarte MySQL-serveren ved at bruge den passende kommando til dit operativsystem. Hvis du er i stand til at dumpe dine tabeller med en innodb_force_recovery værdi på 3 eller mindre, så er du relativt sikker. I mange tilfælde bliver du nødt til at gå op til 4, og som du allerede ved, kan det ødelægge data.

[mysqld]
innodb_force_recovery=1
service mysql restart

Skift om nødvendigt til den højere værdi, seks er den maksimale og farligste.

Når du er i stand til at starte din database, skal du skrive følgende kommando for at eksportere alle databaserne til filen databases.sql:

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

Start mysql, og prøv derefter at slippe den eller de berørte databaser ved hjælp af kommandoen DROP DATABASE. Hvis MySQL ikke er i stand til at slette en database, kan du slette den manuelt ved at bruge nedenstående trin, efter du har stoppet MySQL-serveren.

service mysqld stop

Hvis du ikke var i stand til at slette en database, skal du indtaste følgende kommandoer for at slette den manuelt.

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

Sørg for, at du ikke sletter de interne databasemapper.
Når du er færdig, skal du kommentere følgende linje i [mysqld] for at deaktivere InnoDB-gendannelsestilstand.

#innodb_force_recovery=...

Gem ændringerne til my.cnf-filen, og start derefter MySQL-serveren

service mysqld start

Indtast følgende kommando for at gendanne databaserne fra den sikkerhedskopifil, du oprettede i trin 5:

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

Reparerer MyISAM

Hvis mysqlcheck rapporterer en fejl for en tabel, skal du skrive mysqlcheck-kommandoen med -repair flag for at rette den. Reparationsindstillingen mysqlcheck virker, mens serveren er oppe og køre.

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

Hvis serveren er nede, og mysqlcheck af en eller anden grund ikke kan reparere din tabel, har du stadig mulighed for at udføre gendannelse direkte på filer ved hjælp af myisamchk. Med myisamchk skal du sikre dig, at serveren ikke har tabellerne åbne.

Stop MySQL

service mysqld stop
cd /var/lib/mysql

Skift til den mappe, hvor databasen er placeret.

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

For at kontrollere alle tabellerne i en database, skriv følgende kommando:

myisamchk *.MYI

Hvis den forrige kommando ikke virker, kan du prøve at slette midlertidige filer, der muligvis forhindrer myisamchk i at køre korrekt. For at gøre dette skal du skifte tilbage til mappen data dir og derefter køre følgende kommando:

ls */*.TMD

Hvis der er nogen .TMD-filer på listen, skal du slette dem:

rm */*.TMD

Kør derefter myisamchk igen.

For at forsøge at reparere en tabel skal du udføre følgende kommando og erstatte TABLE med navnet på den tabel, du vil reparere:

myisamchk --recover <TABLE>

Genstart MySQL-serveren

service mysqld start

Sådan undgår du datatab

Der er flere ting, du kan gøre for at minimere risikoen for uoprettelige data. Først og fremmest sikkerhedskopier. Problemet med sikkerhedskopier er, at nogle gange kan de overses. Til cron planlagte sikkerhedskopier skriver vi normalt wrapper-scripts, der registrerer problemer i backup-loggen, men det inkluderer ikke tilfælde, hvor sikkerhedskopieringen slet ikke startede. Cron kan nogle gange hænge og ofte er der ingen overvågning indstillet på den. Et andet potentielt problem kunne være tilfældet, når sikkerhedskopien aldrig blev sat op. Den gode praksis er at køre rapporter fra et separat værktøj, der analyserer sikkerhedskopieringsstatus og informerer dig om manglende tidsplaner for sikkerhedskopiering. Du kan bruge ClusterControl til det eller skrive dine egne programmer.

ClusterControl operationel backup rapport

For at reducere virkningen af ​​den mulige datakorruption bør du altid overveje klyngesystemer. Det er bare et spørgsmål om tid, hvornår databasen vil gå ned eller blive ødelagt, så det er godt at have en kopi, som du kan skifte til. Det kunne være Master / Slave replikering. Det vigtige aspekt her er at have sikker automatisk gendannelse for at minimere kompleksiteten af ​​overgangen og minimere gendannelsestiden (RTO).

ClusterControl automatisk gendannelsesfunktioner
  1. Indsættelse af store objektdata i Salesforce.com fra SQL Server

  2. Sådan migrerer du databaser og datafiler

  3. Ret "Mindst et af argumenterne til COALESCE skal være et udtryk, der ikke er NULL-konstanten" i SQL Server

  4. Optimizer i Oracle Database 19c