Sissejuhatus
Tere. Mina olen ningenMe, veebi arendaja.
Nagu pealkirjas öeldud, on minu lugu 300 miljoni kirje fĂŒĂŒsilisest kustutamisest MySQL-is.
See huvitab mind, seetÔttu otsustasin koostada meelespea (juhendi).
Algus â Alarm
Kogumisprotsessis, mida ma kasutan ja hooldan, on regulaarne protsess, mis korjab MySQL-ist andmed viimase kuu kohta ĂŒks kord pĂ€evas. serverisTavaliselt lĂ”petatakse see protsess umbes 1 tunni jooksul, kuid seekord ei lĂ”petanud see 7 vĂ”i 8 tunni jooksul ja alarm ei lakka ilmumastâŠ
PÔhjuse otsimine
Proovisin protsessi taaskÀivitada, vaadata logisid, kuid midagi hullemat ma ei nÀinud.
PĂ€ring indekseeriti Ă”igesti. Kuid kui ma mĂ”tlema hakkasin, mis valesti kĂ€ib, sain ma aru, et andmebaasi suurus on ĂŒsna suur.
hoge_table | 350'000'000 |
350 miljonit kirjet. Tundub, et indekseerimine toimis Ôigesti, lihtsalt vÀga aeglaselt.Kogutud andmed kuu kohta olid umbes 12 000 000 kirjet. Tundub, et select-kÀsk vÔttis palju aega ja tehing ei tÀitunud pikka aega.
DB
PĂ”himĂ”tteliselt on see tabel, mis kasvab iga pĂ€ev umbes 400 000 kirje vĂ”rra. Andmebaas pidi koguma andmeid ainult viimase kuu kohta, seega arvati, et see talub just selle mahu andmeid, kuid kahjuks ei olnud rotate operatsioon sisse lĂŒlitatud.
See andmebaas ei olnud minu loodud. VĂ”tsin selle ĂŒle teiselt arendajalt, seetĂ”ttu on jÀÀnud tunne, et see on tehniline vĂ”lg.
Kohale jÔudis hetk, mil igapÀevaselt sisestatav andmemahu suurenemine saavutas lÔpuks piiri. Eeldatakse, et töötades sellise suure andmemahuga, tuleks neid jagada, kuid kahjuks seda ei tehtud.
Ja siis astusin ma mÀngu.
Parandus
Mugav oli andmebaasi mahtu vĂ€hendada ja töötlusaega lĂŒhendada, kui muuta kogu loogikat.
Kuna olukord peaks paranema oluliselt, kui kustutada 300 miljonit kirjet, otsustasin seda teha⊠Ah, ma arvasin, et see tÔesti toimib.
Tegevus 1
UsaldusvÀÀrse varukoopia teinud, hakkasin lÔpuks pÀringut saatma.
ăPĂ€ringu saatmineă
DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';
KUSTUTA FROM hoge_table KUS create_time <= 'YYYY-MM-DD HH:MM:SS';ăâŠă
ăâŠă
âHmm... Pole pole puudub. Kas protsess vĂ”tab palju aega?â â mĂ”tlesin ma, kuid igaks juhuks vaatasin grafanasse ja nĂ€gin, et ketta koormus suurenes vĂ€ga kiiresti.
âOhtlikâ â mĂ”tlesin ma veel kord ja peatasin kohe pĂ€ringu.
Tegevus 2
KĂ”ike analĂŒĂŒsides sain aru, et andmehulka oli liiga suur, et kĂ”ike ĂŒhel korral kustutada.
Otsustasin kirjutada skripti, mis suudab kustutada umbes 1 000 000 kirjet ja kÀivitasin selle.
ârakendan skriptiâ
âNĂŒĂŒd peaks kindlasti toimima,â â mĂ”tlesin ma.
Tegevus 3
Teine meetod toimis, kuid osutus kĂŒllalt töömahukaks.
Kui kÔik teha korralikult, ilma liigsete nÀrvideta, kuluks umbes kaks nÀdalat. Kuid see stsenaarium ei vastanud teenuse nÔuetele, seega tuli sellest loobuda.
SeetÔttu otsustasin:
Kopeerime tabeli ja nimetame ĂŒmber.
Eelmise sammu pÔhjal sain aru, et sellise suure andmemahtu kustutamine tekitab sama suure koormuse. Seega otsustasin luua uue tabeli nullist insert'i abil ja kanda sinna andmed, mille kavatsesin kustutada.
| hoge_table | 350'000'000|
| tmp_hoge_table | 50'000'000|Kui luua uus tabel, mis on sama suur kui eespool nÀidatud, siis peaks andmete töötlemise kiirus olema 1/7 kiiremini.
Loomiseks ja ĂŒmbernimetamiseks tabeli, hakkasin seda kasutama peamise tabelina. NĂŒĂŒd, kui kustutan 300 miljoni kirje tabeli, peaks kĂ”ik olema korras.
Selgus, et truncate vÔi drop tekitavad vÀiksemat koormust kui delete, ja otsustasin seda meetodit kasutada.
Tegevus
DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';
INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS'; ăâŠă
ăâŠă
âHmm...?â
Tegevus 4
MÔtlesin, et eelmine idee toimib, kuid pÀrast insert pÀringu saatmist lÀks palju viga. MySQL ei hooli.
Olin juba nii vÀsinud, et hakkasin mÔtlema, et ei taha enam sellega tegeleda.
MĂ”tlesin veidi ja sain aru, et vĂ”ib-olla oli ĂŒhe korra jaoks too palju insert pĂ€ringuid...
Katsusin saata insert pĂ€ringu andmemahtudele, mida andmebaas peab 1 pĂ€evaga töötlema. Ănnestus!
Ja pÀrast seda jÀtkame samade andmemahtude pÀringute saatmist. Kuna peame eemaldama kuu andmemahtu, korrame seda operatsiooni umbes 35 korda.
Tabeli ĂŒmbernimetamine
Siin oli Ônn minu poolel: kÔik lÀks sujuvalt.
HĂ€ired kadusid
Partii töötlemise kiirus suurenes.
Varasemalt vĂ”ttis see protsess umbes tund aega, nĂŒĂŒd kulub umbes 2 minutit.
PĂ€rast seda, kui ma veendusin, et kĂ”ik probleemid on lahendatud, kustutasin 300 miljonit kirjet. Kustutasin tabeli ja tundsin end nagu uuesti sĂŒndinud.
KokkuvÔte
Sain aru, et partii töötlemise kÀigus jÀi vÀlja pööramise töötlemine ja see oli peamine probleem. Selline arhitektuuri viga toob kaasa ajakulu.
Kas mĂ”tlete koormusele andmete replikatsiooni ajal, kustutades kirjeid andmebaasist? Ărgem koormake MySQL-i ĂŒle.
Need, kes tunnevad andmebaase hÀsti, ei puutu sellise probleemiga tÔenÀoliselt kokku. Loodetavasti oli see artikkel teistele kasulik.
AitÀh lugemise eest!
Oleksime vÀga tÀnulikud, kui rÀÀgiksite meile, kas see artikkel meeldis, kas tÔlge oli arusaadav ja kas see oli teile kasulik?
Allikas: habr.com
