Co je to s tím poškozováním databáze

frg
Posts: 836
Joined: 18 Jan 2012, 17:50

Co je to s tím poškozováním databáze

Postby frg » 18 Dec 2015, 16:16

Dostali jsme (teda, spíš Greg) několik PM - rady ohledně toho, co může být se serverem špatně, proč se poškozuje databáze, apod. Rád bych využil tohoto postu k podrobnějšímu vysvětlení situace, objasnění, proč není jednoduchá. Vezmu to čistě technicky bez omáčky pro smrtelníky, takže pokud to nebudete chápat, klidně ignorujte - jsou to dodatečné vysvětlující informace, nic důležité přímo pro hru.

Co se stalo.
Začlo to 3.10., emulátor byl odpojován databází (mariadb). Tohle typicky nastává, pokud se nějak poškodí innodb metadata - a skutečně, v logu se objevovalo něco jako

Code: Select all

Nov 5 05:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 06:10:24 icewow mysqld: len 16384; hex 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 Nov 5 07:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 08:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 09:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 10:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 11:10:23 icewow mysqld: InnoDB: You may have to recover from a backup. Nov 5 12:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 13:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 14:10:24 icewow mysqld: h p x ) * + , - / 0 1 2 3 4 5 6 ( 7 0 8 8 9 @ : H ; P < X = ` > h ? p @ x A B C D E F G H I J K L Nov 5 15:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 16:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 17:10:24 icewow mysqld: InnoDB: Database page corruption on disk or a failed Nov 5 18:10:24 icewow mysqld: 151105 18:10:24 [ERROR] Got error 180 when reading table './cata_char/character_pet'
Tohle nám napovídá více věcí, ale k tomu se dostanu. Nejdříve přišly na řadu testy disků a HDD controlleru, zda nepoškozuje data (ať už to při čtení nebo zápisu).

Disky
Na serveru používáme RAID0 přes prvních pár GB obou disků pro databázi - rotační HDD jsou nejrychlejší na začátku a RAID0 nám umožnil zapisovat 10-20MB/s náhodných požadavků (pro častější .save). Pro zbytek (systém a /home) je RAID1. Ohledně pravidelných kontrol - děláme SMART short selftesty každou noc a long selftesty každou neděli, raid scrub (u RAID1) pak jednou za měsíc. Tyto testy neukázaly nic abnormálního, přesto jsem ale pustil badblocks s 0xff, 0x55, 0xaa, 0x00 a pár pseudonáhodnými běhy nad partišny, kde byl RAID0. Použití pseudonáhodných dat v minulosti odhalilo např. tiché poškození dat řadičem (který měnil offsety).

Bohužel, dle mého očekávání, testy nic nenašly. Problém by mohl být ve zbylých oblastech disků, ale jelikož bylo všechno potřeba dělat za běhu systému a degradovat RAID1 jsem nechtěl, a také jelikož raid scruby ukázaly identická data, nechal jsem to být - problém zde je velmi nepravděpodobný.

RAM
Výpis z mysql logu ukazuje místy nesmyslné kusy dat, což mě navedlo na možné poškození paměti. Opět - za běhu systému toho nešlo moc dělat, ale i tak jsem vytáhl 31 instancí memtesteru pro každý GB paměti a nechal je 2 dny běžet. To otestovalo 2 věci - možné poškození samotných čipů RAM, ale i MMU (v CPU) a práci každého jádra s různými kusy RAM, jelikož CPU scheduler přehazoval těch 31 instancí náhodně mezi jádry.

Bohužel, testování nenašlo jedinou chybu. O něco později jsme zkusili server úplně vypnout, nastartovat starý dobrý memtest86p, jednak aby zkusil trochu jinou sadu testů, jednak aby otestoval celý rozsah RAM (i rozsahy dříve použité kernelem a pro PCI/DMA). O spoustu cyklů později (6x pass / 32GB RAM), ani jeden problém.

CPU
Další možností je poškození CPU. Tady jsem použil různé "testy" prime95 projektu (mprime amd64 binárka), od malých smyček, až po složitější operace zasahující přes L2 až do RAM. Taky jsem si napsal malé testy v x86 assembleru, zkoušející různé generické vektorové instrukce, které by DB server mohl používat pro vytváření indexů.

Po dalších 2 dnech testování, nic. Bez chyby. Zkoušel jsem pouštět memtester instance spolu s testováním CPU, abych to trochu zkombinoval, ale po dalším dni jsem taky nic nenašel.

Software
V tento moment jsem začal podezřívat software - prošel jsem checksumy všech souvisejících balíčků (od glibc, až po mariadb) přes dpkg/debsums, všechno sedělo. Taky jsme začli podezřívat emulátor, zda nějak nepoškozuje DB, ale jak víte, mysql protokol nemá přímý přístup na data DB, jen přes SQL protokol, přes který nejde nic úmyslně poškodit a jelikož používáme debian stable a jeho verzi mariadb, jakékoli poškození dat v důsledku chyby parsování SQL na straně serveru by byla velká, velká, celosvětová bezpečnostní chyba (emu používá velmi omezeného uživatele), což mi přišlo nepravděpodobné.

Přesto jsme zkusili novou 10.1 verzi mariadb (z původní 10.0), zkusili jsme i 10.0 verzi od mariadb vývojářů přímo (bez debianích downstream patchů), zkusili jsme i mysql 5.5, beze změny. Poškození dat nastávalo ve všech implementacích innodb. Taky jsem zkoušel různé úpravy my.cnf, vyhodil jsem veškeré optimalizace, použil prakticky distribuční verzi - nepomohlo, poškození se opět ukázalo.
Gregory také zkoušel hledat možné commity v kódu emulátoru, ale nic (alespoň pár měsíců zpátky) se nedotýkalo kódu pracujícím s DB.

Nutno dodat, že po každém poškození dat jsem znovuvytvořil celou DB od znova a nahrál .sql zálohu, přičemž si DB server znova vytvořil svoje diskové struktury a vypočetl indexy, takže to nemohlo být dlouhodobým poškozením těch stejných dat.

???
Tady už to začlo být komplikovanější - nemohli jsme chybu spolehlivě reprodukovat na žádném z izolovaných testů. Popravdě mi dochází nápady, kde by mohla být. Nemáme finance na to, abychom si mohli dovolit naslepo kupovat komponenty, dokud něco nezabere - může to být CPU, ale stejně tak to může být základní deska nebo velmi vzácná chyba v software.

Čím to nejspíš nebude
Jelikož poškození proběhlo několik a to učitým způsobem, můžu docela spolehlivě tvrdit, že to nebude HDD nebo RAM; prakticky vždy se poškodila character_pet tabulka (a poději navíc character_social a další).
  • HDD - pokaždé jsem pro jistotu vytvářel RAID0 a FS nad ním znova a zapisoval náhodné množství dat, abych dostatečně znáhodnil journal, tedy aby - pokud je např. chyba ve FS driveru - se poškození projevilo jinde, v jiném souboru. To nenastalo, chyba nastala vždy v character_pet. S ohledem na množství dat a restarty OS je prakticky nemožné, aby to mohly disky, řadič nebo filesystém předpovědět a poškodit vždy tu stejnou část.
  • RAM - z podobného důvodu jako HDD - restartovali jsme mezi poškozeními jak OS, tak i (vícekrát) mariadb. Je v podstatě nemožné, aby se kus paměti, zpracovávájící character_pet, dostal vždy na stejné fyzické místo - MMU tu stránku (page) hodí vždy jinam, zvláště po/během testování paměti, kdy je velká fragmentace stránek.
  • PSU - kdyby stroj měl nedostatek šťávy, projevilo by se to na daleko více místech, ne na jedné tabulce.
Nutno dodat, že character_pet je relativně malá tabulka a vzhledem k tomu, že např. character_achievement_progress přežila bez poškození, to nebude např. 50% poškozením paměti, kde by byla velká šance pro opětovné poškození characte_pet -- problémy by se projevily i na spoustě dalších míst, což nenastalo.

Co zbývá
Moje současná teorie tedy visí nejspíš na CPU, případně základní desce. Je teoreticky možné, jakkoli nepravděpodobné, že CPU poškozuje určitou posloupnost instrukcí, která se náhodně vyskytuje při zápisu/čtení dat character_pet. Zní to šíleně, ale je to asi nejpravděpodobnější vysvětlení. Alternativně to může být kritická chyba mariadb serveru.
V minulosti jsem taky zaznamenal několik MCE chyb na jednom z jader CPU (které je vypnuté poslední 2 roky), CPU má tedy už pomyslnou černou tečku.

Současný běh na jiném (virtuálním) železe snad rozsekne to, zda je to hardware nebo software chyba. Běží to sice na jiné verzi debianu, ale pokud je to skutečně chyba mysql/mariadb, reprodukovali jsme ji na čemkoli od mysql 5.5 do mariadb 10.1, tedy by se měla časem projevit, pokud tam je.

Závěrem
Jak vidíte, není to typický problém vadné RAM nebo odcházejícího disku a jednoduhé rady typu "tady ten program našel kamarádovi problém na disku" nám opravdu bohužel nepomůžou, jakkoli jsme rádi, že se snažíte pomoci.

Nerozebíral jsem moc způsoby obnovy dat, se kterými jsem si taky "užil" hodně zabitého času (ne, jednoduché innodb_force_recovery nepomáhalo), ale to snad nevadí / není podstatné pro podstatu problému.

V současnosti se snažíme dále izolovat problém právě během na jiném "hardwaru", ale jak spolehlivě reprodukovat poškození na původním HW bez nutnosti mít online hodně lidí, to nevím.


-------------------------------------------------------

(A post explaining various technical details regarding recent database corruptions, nothing critical for gameplay.)

Gregory
Core Developer
Posts: 4921
Joined: 20 Sep 2009, 14:51
Location: near Pilsen
Contact:

Re: Co je to s tím poškozováním databáze

Postby Gregory » 16 Jan 2016, 19:29

V posledních týdnech jsem měl server u sebe doma a prováděl jsem na něm širokou škálu různých dlouhodobých zátěžových testů (burn-in testy), a to buď obecných (klasické aritmetické operace na sto způsobů) nebo konkrétních (rozšířená instrukční sada), a to za využití často vícevláknového přístupu pro možnost vytížit CPU skutečně na 100% (tedy všechna jádra byla zapojena do výpočtů).

Výsledkem bylo bohužel pouze to, že jsem měl trvanlivě v místnosti o několik stupňů Celsia víc, ale nebyl odhalen žádný problém.

Testy budou nadále pokračovat, mám tu připravenu jednu obecnou zátěžovku, jednu obecnou na operace s čísly v pohyblivé řádové čárce (aby dostal pokouřeno i FPU), testy na RAM a pak i na disky.


Return to “Důležité informace / Important information”

Who is online

Users browsing this forum: No registered users and 5 guests