Příběh fyzického smazání 300 milionů záznamů v MySQL

úvod

Ahoj. Jsem ningenMe, webový vývojář.

Jak název napovídá, můj příběh je příběhem fyzického smazání 300 milionů záznamů v MySQL.

Začalo mě to zajímat, a tak jsem se rozhodl udělat připomínku (návod).

Domů - Upozornění

Dávkový server, který používám a spravuji, má pravidelný proces, který jednou denně shromažďuje data z MySQL za poslední měsíc.

Obvykle je tento proces dokončen přibližně do 1 hodiny, ale tentokrát nebyl dokončen po dobu 7 nebo 8 hodin a upozornění se nepřestalo objevovat...

Hledání důvodu

Pokusil jsem se restartovat proces a podívat se na protokoly, ale nic špatného jsem neviděl.
Dotaz byl indexován správně. Ale když jsem přemýšlel o tom, co je špatně, uvědomil jsem si, že velikost databáze je poměrně velká.

hoge_table | 350'000'000 |

350 milionů záznamů. Zdálo se, že indexování funguje správně, jen velmi pomalu.

Požadovaný sběr dat za měsíc byl přibližně 12 000 000 záznamů. Vypadá to, že příkaz select trval dlouho a transakce se dlouho neprováděla.

DB

Je to v podstatě tabulka, která se každý den rozroste asi o 400 000 záznamů. Databáze měla sbírat data pouze za poslední měsíc, proto se očekávalo, že přesně takové množství dat vydrží, ale bohužel nebyla zahrnuta operace rotace.

Tato databáze nebyla vyvinuta mnou. Převzal jsem to od jiného vývojáře, takže mi to stále připadalo jako technický dluh.

Přišel bod, kdy objem denně vkládaných dat nabyl na velikosti a nakonec dosáhl svého limitu. Předpokládá se, že při práci s tak velkým množstvím dat by bylo nutné je oddělit, ale to se bohužel nestalo.

A pak jsem vstoupil do akce.

Oprava

Racionálnější bylo zmenšit velikost samotné databáze a zkrátit čas na její zpracování, než měnit samotnou logiku.

Situace by se měla výrazně změnit, pokud vymažete 300 milionů záznamů, tak jsem se rozhodl tak učinit... Eh, myslel jsem, že to bude určitě fungovat.

Akce 1

Po připravení spolehlivé zálohy jsem konečně začal posílat požadavky.

「Odeslání žádosti」

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

"…"

"…"

"Hmm... Žádná odpověď." Možná ten proces trvá dlouho?" — Pomyslel jsem si, ale pro každý případ jsem se podíval na grafana a viděl jsem, že zatížení disku velmi rychle roste.
"Nebezpečné," pomyslel jsem si znovu a okamžitě jsem žádost zastavil.

Akce 2

Po analýze všeho jsem si uvědomil, že objem dat je příliš velký na to, aby bylo možné smazat vše najednou.

Rozhodl jsem se napsat skript, který by dokázal smazat asi 1 000 000 záznamů, a spustil jsem ho.

「Implementuji skript」

"Teď to určitě půjde," pomyslel jsem si.

Akce 3

Druhá metoda fungovala, ale ukázalo se, že je velmi pracná.
Dělat vše pečlivě, bez zbytečných nervů, by trvalo asi dva týdny. Ale přesto tento scénář nesplňoval požadavky na službu, takže jsme od něj museli odejít.

Takže tady je to, co jsem se rozhodl udělat:

Zkopírujte tabulku a přejmenujte ji

Z předchozího kroku jsem si uvědomil, že smazáním tak velkého množství dat vzniká stejně velká zátěž. Rozhodl jsem se tedy vytvořit novou tabulku od začátku pomocí insert a přesunout do ní data, která jsem se chystal smazat.

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

Pokud vytvoříte novou tabulku ve stejné velikosti jako výše, rychlost zpracování dat by se měla také zvýšit o 1/7.

Po vytvoření tabulky a jejím přejmenování jsem ji začal používat jako hlavní tabulku. Když teď shodím tabulku s 300 miliony záznamů, všechno by mělo být v pořádku.
Zjistil jsem, že zkrácení nebo přetažení vytváří menší režii než odstranění, a rozhodl jsem se použít tuto metodu.

Provedení

「Odeslání žádosti」

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

"…"
"…"
"Em…?"

Akce 4

Myslel jsem, že předchozí nápad bude fungovat, ale po odeslání žádosti o vložení se objevilo několik chyb. MySQL není shovívavé.

Už jsem byl tak unavený, že jsem si začal myslet, že už to nechci dělat.

Seděl jsem a přemýšlel a uvědomil jsem si, že možná bylo najednou příliš mnoho dotazů na vložení...
Zkusil jsem odeslat požadavek na vložení množství dat, které by databáze měla zpracovat za 1 den. Stalo!

Poté pokračujeme v odesílání žádostí o stejné množství dat. Protože potřebujeme odstranit data za měsíc, opakujeme tuto operaci přibližně 35krát.

Přejmenování tabulky

Tady bylo štěstí na mé straně: všechno šlo hladce.

Upozornění zmizelo

Rychlost dávkového zpracování se zvýšila.

Dříve tento proces trval asi hodinu, nyní to trvá asi 2 minuty.

Poté, co jsem si byl jistý, že všechny problémy byly vyřešeny, shodil jsem 300 milionů záznamů. Smazal jsem tabulku a cítil se jako znovuzrozený.

souhrn

Uvědomil jsem si, že v dávkovém zpracování chybí rotační zpracování, a to byl hlavní problém. Tento druh architektonické chyby vede ke ztrátě času.

Myslíte na zátěž při replikaci dat při mazání záznamů z databáze? Nepřetěžujme MySQL.

Kdo se v databázích dobře orientuje, s takovým problémem se rozhodně nesetká. Pro vás ostatní byl doufám tento článek užitečný.

Děkuji za přečtení!

Budeme velmi rádi, když nám řeknete, zda se vám tento článek líbil, zda je překlad jasný, zda byl pro vás užitečný?

Zdroj: www.habr.com

Přidat komentář