Lugu 300 miljoni MySQL-i kirje füüsilisest kustutamisest

Sissejuhatus

Tere. Olen ningenMe, veebiarendaja.

Nagu pealkiri ütleb, on minu lugu MySQL-is 300 miljoni kirje füüsilisest kustutamisest.

Mind hakkas see huvitama, nii et otsustasin teha meeldetuletuse (juhised).

Avaleht – hoiatus

Minu kasutatavas ja hooldatavas partiiserveris on tavaline protsess, mis kogub MySQL-ist kord päevas viimase kuu andmeid.

Tavaliselt viiakse see protsess lõpule umbes 1 tunni jooksul, kuid seekord ei lõppenud see 7 või 8 tunni jooksul ja hoiatus ei lakanud ilmumast...

Põhjust otsides

Proovisin protsessi taaskäivitada ja logisid vaadata, kuid ma ei näinud midagi valesti.
Päring indekseeriti õigesti. Kui aga mõtlesin, mis valesti läks, sain aru, et andmebaasi maht on päris suur.

hoge_table | 350'000'000 |

350 miljonit rekordit. Indekseerimine näis toimivat õigesti, lihtsalt väga aeglaselt.

Nõutav andmete kogumine kuus oli ligikaudu 12 000 000 kirjet. Paistab, et valikukäsk võttis kaua aega ja tehingut ei tehtud pikka aega.

DB

See on sisuliselt tabel, mis kasvab iga päev umbes 400 000 kirje võrra. Andmebaas pidi koguma andmeid ainult viimase kuu kohta, mistõttu eeldati, et see peab vastu just sellisele andmemahule, kuid paraku rotatsioonioperatsiooni kaasas ei olnud.

Seda andmebaasi ei loonud mina. Võtsin selle üle teiselt arendajalt, nii et tundus ikkagi tehnilise võlana.

Saabus hetk, mil iga päev sisestatud andmete maht muutus suureks ja jõudis lõpuks oma piirini. Eeldatakse, et nii suure andmemahuga töötades oleks vaja need eraldada, kuid seda kahjuks ei tehtud.

Ja siis asusin tegutsema.

Parandus

Ratsionaalsem oli vähendada andmebaasi enda suurust ja lühendada selle töötlemise aega, kui muuta loogikat ennast.

Olukord peaks oluliselt muutuma, kui kustutate 300 miljonit plaati, nii et ma otsustasin seda teha... Eh, ma arvasin, et see toimib kindlasti.

Tegevus 1

Olles valmistanud usaldusväärse varukoopia, hakkasin lõpuks päringuid saatma.

"Taotluse saatmine"

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

"…"

"…"

“Hmm... Pole vastust. Võib-olla võtab protsess kaua aega?” — mõtlesin, aga igaks juhuks vaatasin grafana peale ja nägin, et kettakoormus kasvab väga kiiresti.
"Ohtlik," mõtlesin uuesti ja lõpetasin taotluse kohe.

Tegevus 2

Pärast kõike analüüsimist mõistsin, et andmete maht on liiga suur, et kõike korraga kustutada.

Otsustasin kirjutada skripti, mis suudab kustutada umbes 1 000 000 kirjet, ja käivitasin selle.

"Ma rakendan skripti"

"Nüüd see kindlasti toimib," mõtlesin ma.

Tegevus 3

Teine meetod töötas, kuid osutus väga töömahukaks.
Et kõike teha hoolikalt, ilma liigsete närvideta, kuluks umbes kaks nädalat. Kuid ikkagi ei vastanud see stsenaarium teenindusnõuetele, mistõttu pidime sellest eemalduma.

Nii et siin on see, mida ma otsustasin teha:

Kopeerige tabel ja nimetage see ümber

Eelmisest sammust sain aru, et nii suure andmehulga kustutamine tekitab sama suure koormuse. Seega otsustasin luua uue tabeli algusest sisestamise abil ja teisaldada kustutatavad andmed sinna.

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

Kui teha uus tabel ülalolevaga sama suurusega, peaks ka andmetöötluskiirus muutuma 1/7 võrra kiiremaks.

Pärast tabeli loomist ja ümbernimetamist hakkasin seda kasutama põhitabelina. Kui ma nüüd 300 miljoni rekordiga tabeli maha jätan, peaks kõik korras olema.
Sain teada, et kärpimine või kukutamine tekitab vähem lisakulusid kui kustutamine, ja otsustasin kasutada seda meetodit.

Performance

"Taotluse saatmine"

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

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

Tegevus 4

Arvasin, et eelmine idee töötab, kuid pärast lisamistaotluse saatmist ilmnes mitu viga. MySQL ei andesta.

Ma olin juba nii väsinud, et hakkasin mõtlema, et ma ei taha seda enam teha.

Istusin ja mõtlesin ning sain aru, et võib-olla oli ühe korra kohta liiga palju sisestamispäringuid...
Proovisin saata sisestamistaotlust andmemahu kohta, mida andmebaas peaks 1 päeva jooksul töötlema. Juhtus!

Noh, pärast seda jätkame sama andmemahu päringute saatmist. Kuna peame eemaldama ühe kuu andmeid, kordame seda toimingut umbes 35 korda.

Tabeli ümbernimetamine

Siin oli õnn minu poolel: kõik sujus.

Hoiatus on kadunud

Partii töötlemise kiirus on suurenenud.

Varem võttis see protsess aega umbes tund, nüüd aga umbes 2 minutit.

Kui olin kindel, et kõik probleemid on lahendatud, kukkusin maha 300 miljonit rekordit. Kustutasin tabeli ära ja tundsin end uuesti sündinuna.

Kokkuvõte

Sain aru, et rotatsioonitöötlus puudub partiitöötluses ja see oli põhiprobleem. Selline arhitektuuriline viga viib aja raiskamiseni.

Kas mõtlete andmebaasist kirjete kustutamisel andmete replikatsiooni koormusele? Ärgem MySQL-i üle koormakem.

Need, kes on andmebaasidega hästi kursis, sellise probleemiga kindlasti ei puutu. Loodan, et teistele teile oli see artikkel kasulik.

Täname lugemise eest!

Meil on väga hea meel, kui ütlete meile, kas teile meeldis see artikkel, kas tõlge on selge, kas see oli teile kasulik?

Allikas: www.habr.com

Lisa kommentaar