[DUPLÁN MEGOLDVA] [C/C++] ZFS + VPS + Ext4 = Corrupted InnoDB

Két dolog miatt szánok egy kis szösszenetet a sztorinak.

Az egyik oka, hogy igencsak meglepődtem, hogy ilyen meg tud történni a másik oka, mert készült is rá egy megoldás melyet örömmel szeretnék megosztani a közösséggel.

Nagy vonalakban a sztori, hogy egy ZFS storage -el ellátott VPS (KVM alapú) anyagépen, egy tucat Linux VPS -ből az egyik, ext4 fájlrendszere egyik pillanatról a másikra eldobta magát.

ZFS checksum ON, hiba nincs.
ext4 naplózott, nem volt hirtelen halál, ac loss, igazából nagyjából ilyen féléves uptime -ját ünnepelte maga a VPS, 1,5 évvel ezelőtt volt bővítve a fájlrendszer, amúgy Virt-IO.

A történet sajnálatos eredménye, hogy az innoDB .ibd fájlait szépen elkorruptálta, tehát I/O Error -t írt ha másolni, megnyitni akartam, éppen ezért a mySQL vagy el sem indult, vagy nagyon rövid időn belül "felakasztotta magát".

Szóval én láttam már sok mindent, de ilyet nem, mármint VPS esetén:

[23563.216403] blk_update_request: I/O error, dev vda, sector 960227912
[23563.356236] blk_update_request: I/O error, dev vda, sector 960227912
[23563.527275] blk_update_request: I/O error, dev vda, sector 960227912
[23563.805136] blk_update_request: I/O error, dev vda, sector 960227912
[23564.244561] blk_update_request: I/O error, dev vda, sector 960227912
[23564.375360] blk_update_request: I/O error, dev vda, sector 960227912
[23567.440755] blk_update_request: 12 callbacks suppressed
[23567.440781] blk_update_request: I/O error, dev vda, sector 960227912
[23567.520537] blk_update_request: I/O error, dev vda, sector 960227912
[23567.587946] blk_update_request: I/O error, dev vda, sector 960227912
[23568.054547] blk_update_request: I/O error, dev vda, sector 960227912
[23568.075419] blk_update_request: I/O error, dev vda, sector 960227912
[23568.077621] blk_update_request: I/O error, dev vda, sector 960227912
[23568.078390] blk_update_request: I/O error, dev vda, sector 960227912
[23568.079057] blk_update_request: I/O error, dev vda, sector 960227912
[23568.080408] blk_update_request: I/O error, dev vda, sector 960227912
[23568.081079] blk_update_request: I/O error, dev vda, sector 960227912
[23572.441857] blk_update_request: 7307 callbacks suppressed
[23572.441881] blk_update_request: I/O error, dev vda, sector 960227920
[23572.443353] blk_update_request: I/O error, dev vda, sector 960227920
[23572.444023] blk_update_request: I/O error, dev vda, sector 960227920
[23572.444575] blk_update_request: I/O error, dev vda, sector 960227920
[23572.445979] blk_update_request: I/O error, dev vda, sector 96022792

Tehát mégegyszer az "underlaying storage" (ZFS) rendben van, a diszkek is.
qemu-img check nem talált hibát, fsck force lefutott rendben.
qemu-nbd -vel felcsatoltam anyagépen, ott se volt hiba, egészen addig míg nem léptem bele egy "badsector" -ba.

Na erre mondjon valaki okosat nekem.

A másik oldala a dolognak, hogy ám az adatbázis rohadtúl kellett és nem találtam az interneten olyan programot amivel kimondottan csak 1-1 fájlt, helyre lehessen állítani gyorsan és az sem baj ha véres marad, illetve minimálisan testreszabható legyen a visszaállítás, ezért készítettem egyet és a helyzet az, hogy megmentette a napot.

Az ötlet onnan született, hogy van egy fájl ami 500MB, 384MB -nál I/O Error -t dob... Gondoltam, hogy most maximum 512KB -ot nem tud kiolvasni, de a többi részét meglehetne menteni, csak hogy I/O errornál minden belefut az END_OF_FILE -ba és hibával kilép, én meg maradtam egy 384MB -os fájlal amit biztos nem fog megenni a mySQL.

Ami megoldást találtam az a dd és a ddrescue volt, 

dd if=./file1 of=./file1.fix bs=512 conv=noerror,sync iflag=fullblock 

De ezzel az volt a probléma, hogy kellett egy olyan feature is, hogy ne 0x00 -val írja ki a hiányzó részeket, mert pont bekavar az innoDB -nek és nem igazán találtam megfelelő dokumentációt ennek a működéséről és rengeteg helyen kinullázott dolgokat.

Aztán született egy saját megoldás, ami ezt megoldja azzal, hogy ugyanúgy továbblépteti és a hiányzó adatokat tetszőleges karakterrel helyettesíti, és bájtonként halad a recovery része így viszont kaptam egy ugyanakkora méretű fájlt mint az eredeti, csak 1-1 helyen pár kilobájt éppenséggel killett nullázva vagy pont más karakterrel lett behelyettesítve, a visszaállítás sebessége is felülmúlta az alternatívákat.

Ennek köszönhetően, elindult az adatbázis, viszont ahogy belefutott a problémás részbe, "Buffer overflow" -al meg is döglött, létezik egy varázstrükk, ez pedig az `innodb_recovery_mode`, ezt 6 -osra állítva simán adott egy mysqldumpot, ráadásul úgy, hogy egy bájt adat nem hiányzott.

Ja és ECC RAM meg modern környezet.

A program végezetül ami mentett egy nagyott, szó szerint.
https://github.com/DaVieS007/Partial-File-Recovery

 

Hozzászólások

minden nap futtatok debsums-ot hasonlo esetekre, hogy a telepitett fajlok nem valtoznak-e meg

par honapja "fogott" is egy elterest. fajlhoz senki nem nyult megis hibas volt a sums

ujratelepitettem a csomagot es jo lett

neked aztan fura humorod van...

Nagyon érdekes hiba.

"ZFS storage -el ellátott VPS (KVM alapú) anyagépen"

A hoston (anyagépen :) ) látszik bármilyen hiba a dmesg-ben? ZFS-en hogy vannak a disk image-ek? FS+QCOW2 vagy ZVOL-on közvetlenül futnak a VM-ek?

FS + QCOW2, zpool rendben, dmesg nem beszél róla.
Vagy a qcow2 sérült amire elég kevés az esély, vagy az ext4, de nem hagy nyugodni ezt meg akarom fejteni, hogy mi okozza.
ZFS replika van, tehát ez a cucc átkerül egy másik gépre, minden nap, bár ott FreeBSD fut, de dolgozom rajta, hogy a diszk image -t ott is feltudjam csatolni, hátha a BSD kernel beszédesebb a portolt ext4 -el.
 

Running on FreeBSD/Bhyve

Szerkesztve: 2021. 04. 30., p – 12:16

Grat!

RAM hiba volt, van 2db RAM modulom amire nem feltétlenül jelez a memtest, de pont a DELL PERC vezérlőt találja meg és a PCI-E buszon okoz zavart, sehol máshol.... És kurva ritkán.
Akkor ez a misztérium is megoldva. ECC RAM pff. ugyanúgy szart sem ér.

ZFS powa.

 

Running on FreeBSD/Bhyve