Príbeh fyzického vymazania 300 miliónov záznamov v MySQL

Úvod

Ahoj. Som ningenMe, webový vývojár.

Ako hovorí názov, môj príbeh je príbehom fyzického vymazania 300 miliónov záznamov v MySQL.

Začalo ma to zaujímať, tak som sa rozhodol urobiť pripomienku (návod).

Domov - Upozornenie

Dávkový server, ktorý používam a udržiavam, má pravidelný proces, ktorý zhromažďuje údaje za posledný mesiac z MySQL raz denne.

Zvyčajne sa tento proces dokončí do približne 1 hodiny, ale tentoraz sa nedokončil 7 alebo 8 hodín a upozornenie sa neprestalo zobrazovať...

Hľadanie dôvodu

Pokúsil som sa reštartovať proces a pozrieť sa na protokoly, ale nevidel som nič zlé.
Dotaz bol indexovaný správne. Ale keď som sa zamyslel nad tým, čo sa deje, uvedomil som si, že veľkosť databázy je dosť veľká.

hoge_table | 350'000'000 |

350 miliónov záznamov. Zdá sa, že indexovanie funguje správne, len veľmi pomaly.

Požadovaný zber dát za mesiac bol približne 12 000 000 záznamov. Zdá sa, že príkaz select trval dlho a transakcia sa dlho nevykonávala.

DB

Je to v podstate tabuľka, ktorá sa každý deň rozrastie o približne 400 000 záznamov. Databáza mala zbierať dáta len za posledný mesiac, preto sa očakávalo, že presne takéto množstvo dát vydrží, ale žiaľ, operácia rotácie nebola zahrnutá.

Túto databázu som nevyvinul ja. Prevzal som to od iného developera, takže mi to stále pripadalo ako technický dlh.

Prišiel bod, keď objem denne vkladaných dát narástol a konečne dosiahol svoj limit. Predpokladá sa, že pri práci s takým veľkým množstvom dát by bolo potrebné ich oddeliť, čo sa však, žiaľ, neuskutočnilo.

A potom som vstúpil do akcie.

Oprava

Bolo racionálnejšie zmenšiť veľkosť samotnej databázy a skrátiť čas na jej spracovanie, ako meniť samotnú logiku.

Situácia by sa mala výrazne zmeniť, ak vymažete 300 miliónov záznamov, tak som sa rozhodol tak urobiť... Eh, myslel som si, že toto bude určite fungovať.

Akcia 1

Keď som pripravil spoľahlivú zálohu, konečne som začal posielať požiadavky.

"Odoslanie žiadosti"

DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';

"…"

"…"

„Hmm... Žiadna odpoveď. Možno ten proces trvá dlho?" — Pomyslel som si, ale pre každý prípad som sa pozrel na grafana a videl som, že zaťaženie disku veľmi rýchlo rastie.
"Nebezpečné," pomyslel som si znova a okamžite som zastavil požiadavku.

Akcia 2

Po analýze všetkého som si uvedomil, že objem údajov je príliš veľký na to, aby som všetko vymazal naraz.

Rozhodol som sa napísať skript, ktorý dokáže vymazať asi 1 000 000 záznamov a spustil som ho.

"Implementujem skript"

"Teraz to bude určite fungovať," pomyslel som si.

Akcia 3

Druhá metóda fungovala, ale ukázalo sa, že je veľmi náročná na prácu.
Robiť všetko opatrne, bez zbytočných nervov by trvalo asi dva týždne. Tento scenár však stále nespĺňal požiadavky na službu, takže sme sa od neho museli vzdialiť.

Takže tu je to, čo som sa rozhodol urobiť:

Skopírujte tabuľku a premenujte ju

Z predchádzajúceho kroku som si uvedomil, že vymazanie takého množstva dát vytvára rovnako veľkú záťaž. Rozhodol som sa teda vytvoriť novú tabuľku od začiatku pomocou vloženia a presunúť do nej údaje, ktoré som chcel vymazať.

| hoge_table     | 350'000'000|
| tmp_hoge_table |  50'000'000|

Ak vytvoríte novú tabuľku s rovnakou veľkosťou ako vyššie, rýchlosť spracovania údajov by sa tiež mala zvýšiť o 1/7.

Po vytvorení tabuľky a jej premenovaní som ju začal používať ako hlavnú tabuľku. Ak teraz zhodím tabuľku s 300 miliónmi záznamov, všetko by malo byť v poriadku.
Zistil som, že skrátenie alebo vypustenie vytvára menšiu réžiu ako odstránenie a rozhodol som sa použiť túto metódu.

poprava

"Odoslanie žiadosti"

INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS';

"…"
"…"
"Em...?"

Akcia 4

Myslel som si, že predchádzajúci nápad bude fungovať, ale po odoslaní žiadosti o vloženie sa objavilo viacero chýb. MySQL nie je zhovievavé.

Bol som už taký unavený, že som si začal myslieť, že to už nechcem robiť.

Sedel som a premýšľal a uvedomil som si, že možno bolo na jeden krát príliš veľa otázok na vloženie...
Skúsil som poslať požiadavku na vloženie množstva údajov, ktoré by mala databáza spracovať za 1 deň. Stalo!

Potom pokračujeme v odosielaní žiadostí o rovnaké množstvo údajov. Keďže potrebujeme odstrániť údaje za mesiac, túto operáciu zopakujeme približne 35-krát.

Premenovanie tabuľky

Tu bolo šťastie na mojej strane: všetko išlo hladko.

Upozornenie sa stratilo

Rýchlosť dávkového spracovania sa zvýšila.

Predtým tento proces trval asi hodinu, teraz to trvá asi 2 minúty.

Keď som si bol istý, že všetky problémy sú vyriešené, pustil som 300 miliónov záznamov. Vymazal som tabuľku a cítil som sa ako znovuzrodený.

Zhrnutie

Uvedomil som si, že pri dávkovom spracovaní chýba rotačné spracovanie a to bol hlavný problém. Tento druh architektonickej chyby vedie k strate času.

Myslíte na záťaž pri replikácii dát pri odstraňovaní záznamov z databázy? Nepreťažujme MySQL.

Kto sa dobre orientuje v databázach, s takýmto problémom sa určite nestretne. Pre vás ostatných dúfam, že bol tento článok užitočný.

Vďaka za prečítanie!

Budeme veľmi radi, ak nám poviete, či sa vám tento článok páčil, či je preklad jasný, či bol pre vás užitočný?

Zdroj: hab.com

Pridať komentár