MySQL InnoDB Corruption og Recover

Scott/Tiger - IT konsulenthus / DBA  / MySQL InnoDB Corruption og Recover

MySQL InnoDB Corruption og Recover

Vi har sikkert alle prøvet det, som vi helst ikke vil opleve; at vores databaser bliver korrupte. Databaser kan blive korrupte af mange årsager. I dette tilfælde, som jeg beskriver nu, var det en udvidelse af et LVM volume, der forårsagede en korrupt ibdata fil. Andre årsager kunne være et strømnedbrud.

InnoDB korruptioner kan påvirke alle databaser der kører på serveren bliver utilgængelige.
I vores tilfælde, så kører vi på en Oracle Enterprise Linux 7.3 på en Oracle VM host. Scenariet er det samme på ubuntu og Debian. Windows skal jeg være usagt, men denne metode, som jeg beskriver her, er specifikt til Linux.

Opbygning af MySQL og den nemme løsning

I MySQL har vi ibdata1, ib_logfile0 og ib_logfile1, som udgør metadata for selve MySQL databasen.
Hvis ib_log* bliver korrupt, så kan en løsning være, at slette dem og så bliver de oprettet automatisk, når mysql servicen bliver genstartet.
Systemctl restart mysqld

Problemet er straks større, hvis ibdata1 bliver korrupt.
Samme metode gør sig ikke gældende med ibdata1, medmindre, at man har en tidligere backup, hvor man kan være heldig, at få databasen op at køre med
innodb_force_recovery = > 0

På denne måde, vil man kunne

  1. starte databasen
  2. eksportere data med mysqldump
  3. importere i en anden database

Recover fra datafiler
Vi har lige udført en restore af data fra ibd filer. Vi havde ikke mulighed for at lave mysqldump fra databasen, da der var uoverensstemmelse mellem ibdata1 og datafilerne. Databasen kørte, men der kom nogle underlige fejl i mysql loggen og databasen crashede, når man kørte forespørgsler imod den.
Det, som vi gjorde var, at bruge et 3. part tool (undrop-for-innodb),

  1. parse vores ib_data1 på en anden server
  2. parse vore ibd fil

Herefter skulle der bruges en masse CPU tid på at dumpe data fra en 41GB stor fil til en dump fil, som så kunne importeres i tabellen.

Her er et eksempel på udførelsen:

  1. Download og installer undrop-for-innodb-master
  2. top mysql databasen
  3. Kopier ibdata1 til en anden destination (den skal indeholde informationer omkring tabeller mm) og kopier ibd fil, der skal recovers til samme destination.

Eksempel
1. ./stream_parser -f /data/ibdata1

2. Kør samme kommando for .ibd fil

3. Derefter skal data hentes fra ibd fil (dette tager CPU tid, så hav tålmodighed her)

./c_parser -6f pages-item_discovery.ibd/FIL_PAGE_INDEX/000000000000009* -t zabbix/item_discovery.sql -o dumps/item_discovery.sql

Kommando:
SET FOREIGN_KEY_CHECKS=0;
LOAD DATA LOCAL INFILE ‘dumps/item_discovery.sql’ REPLACE INTO TABLE `item_discovery` FIELDS TERMINATED BY ‘\t’ OPTIONALLY ENCLOSED BY ‘”‘ LINES STARTING BY ‘item_discovery\t’ (`itemdiscoveryid`, `itemid`, `parent_itemid`, `key_`, `lastcheck`, `ts_delete`);

4. Så skal tabellen oprettes igen i databasen, og dette kan gøre ud fra frm filerne, hvis man ikke har sql’en til dette.

5. Så lave vi en simpel mysqldump af den nye tabel
mysqldump -uroot -p zabbix.item_discovery > /data/item_discovery.sql

6. Derefter skal data importeres igen i en anden database
Mysql -uroot -p < /data/item_discovery.sql
I dette eksempel var der tale om 22.000 rækker, men det er det samme for xxx mill rækker

Konklusion
I vores tilfælde drejede data sig om historiske data, men de er vigtige for vores forretning. Vi havde ikke nået at sætte backup op på maskinen, så det var desværre den lidt besværlige vej, som vi måtte tage, men alt i alt, så fik vi recoveret 437 mill rækker, som ellers ville have været tabt.
Backup er efterfølgende sat op og testet, at det virker, hvilket er lige så vigtig som selve backuppen.

Så hvis du står med et problem med en korrupt MySQL database, så kontakt os. Ring til Ole Kramer på tlf. 2441 0630

Skrevet af:
Lars Baad-Jensen, Scott/Tiger Services

 

Download printvenlig version af artiklen her