Sissejuhatus
Tere. Mina olen ningenMe, veebi arendaja.
Nagu pealkirjas öeldud, on minu lugu lood fĂŒĂŒsilisest kustutamisest 300 miljoni kirje osas MySQL-is.
Olin sellest huvitatud, seega otsustasin koostada mÀrkme (juhendi).
Algus â Alert
Paketis serveril, mida ma kasutan ja hooldan, on regulaarne protsess, mis kogub igal pÀeval eelmise kuu andmeid MySQL-ist.
Tavaliselt lĂ”petatakse see protsess umbes 1 tunni jooksul, kuid seekord see ei lĂ”petanud 7 vĂ”i 8 tunni jooksul, ja hĂ€ire ei lakanud âŠ
PÔhjuse otsimine
Proovisin protsessi kÀivitada uuesti, vaatasin logisid, kuid ei nÀinud midagi tÔsist.
PĂ€ring indekseerus Ă”igesti. Kuid kui mĂ”tlesin, mis valesti lĂ€heb, sain aru, et andmebaasi maht on ĂŒsna suur.
hoge_table | 350'000'000 |350 miljonit kirjet. Tundub, et indekseerimine toimis Ôigesti, lihtsalt vÀga aeglaselt.
NÔutav andmekogumine kuus oli umbes 12 000 000 kirjet. Tundub, et select kÀsk vÔttis palju aega ning tehing ei tÀidetud pikka aega.
DB
Sisult on tabel, mis suureneb iga pÀev umbes 400 000 kirje vÔrra. Andmebaas pidi koguma andmeid ainult viimase kuu jooksul, seega oli arvutus tehtud selle nÀkku, et talub just seda andmemahtu, kuid kahjuks ei olnud rotate operatsioon aktiveeritud.
See andmebaas ei olnud minu loodud. VĂ”tsin selle ĂŒle teiselt arendajalt, seega jĂ€i tunne, et see on tehniline vĂ”lg.
JÔudis kÀtte hetk, mil pÀevaseid andmeid hakkas tekkima liiga palju ja see lÔpuks saavutas piiri. Eeldatakse, et töötades nii suure andmemahtuga peaks need jagama, kuid seda kahjuks ei tehtud.
Ja siis astusin mina mÀngu.
Parandus
Oli ratsionaalsem vĂ€hendada andmebaasi ennast ja lĂŒhendada selle töötlemise aega kui muuta kogu loogikat.
Olukord peaks oluliselt muutuma, kui kustutada 300 miljonit kirjet, seega otsustasin nii teha⊠Oh, ma arvasin, et see kindlasti töötab.
Tegevus 1
UsaldusvÀÀrse varukoopia valmistamine, alustasin lÔpuks pÀringute saatmist.
ăPĂ€ringu saatmineă
DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';ăâŠă
ăâŠă
Hmm... Ei mingit vastust. VĂ”ib-olla protsess vĂ”tab liiga kaua aega?" â mĂ”tlesin ma, kuid igaks juhuks vaatasin grafanas ja nĂ€gin, et kettaruumi kasutus kasvas vĂ€ga kiiresti.
"Ohtlik," â mĂ”tlesin ma veel kord ja peatasin kohe pĂ€ringu.
Tegevus 2
Kuna olin kĂ”ik analĂŒĂŒsinud, mĂ”istsin, et andmete maht oli liiga suur, et kĂ”ik ĂŒhekorraga kustutada.
Otsustasin kirjutada skripti, mis suudab kustutada umbes 1 000 000 kirjet ja kÀivitasin selle.
ârakendan skriptiâ
"NĂŒĂŒd kindlasti töötab," â mĂ”tlesin ma.
Tegevus 3
Teine meetod töötas, kuid osutus vÀga töömahukaks.
Et kÔik korralikult teha, ilma liigsete nÀrvideta, kuluks umbes kaks nÀdalat. Kuid see stsenaarium ei vastanud siiski teenuse nÔuetele, seega pidin sellest loobuma.
Seega otsustasin, et "
Kopeerime tabeli ja nimetame ĂŒmber.
Eelmise sammu pÔhjal mÔistsin, et sellise suure andmemahtude kustutamine tekitab sama suure koormuse. Seega otsustasin luua uue tabeli algusest peale, kasutades insert'i, ja sinna viia andmed, mille plaanisin kustutada.
| hoge_table | 350'000'000|
| tmp_hoge_table | 50'000'000|Kui teha uus tabel sama suur nagu eespool mÀrgitud, peaks andmete töötlemise kiirus olema 1/7 vÔrra kiirem.
PĂ€rast tabeli loomist ja ĂŒmbernimetamise alustasin selle kasutamist peamise tabelina. NĂŒĂŒd, kui ma kustutan tabeli, kus on 300 miljonit kirjet, peaks kĂ”ik olema korras.
Selgus, et truncate vÔi drop tekitavad vÀhem koormust kui delete, ja otsustasin seda meetodit kasutada.
TĂ€itmises
ăPĂ€ringu saatmineă
INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS'; ăâŠă
ăâŠă
âEhm...?â
Tegevus 4
Arvasin, et eelmine idee töötab, kuid pÀrast insert pÀringu saatmist tekkis hulk vigu. MySQL ei halasta.
Olen juba nii vÀsinud, et olen hakanud mÔtlema, et ma ei taha enam sellega tegeleda.
MĂ”tlesin veidi ja sain aru, et vĂ”ib-olla oli ĂŒhe korra jaoks liiga palju insert pĂ€ringuid...
Proovisin saata insert pĂ€ringu andmemahtu, mille andmebaas peaks ĂŒhe pĂ€eva jooksul töötlema. Ănnestus!
Ja pÀrast seda jÀtkame pÀringute saatmist sama andmemahu kohta. Kuna peab eemaldama kuu andmemahtu, korrame seda protseduuri umbes 35 korda.
Tabeli ĂŒmbernimetamine
Siin oli Ônn minu poolel: kÔik lÀks ladusalt.
Alert kadusid
Partii töötlemise kiirus on kasvanud.
Varem kestis see protsess umbes tund, nĂŒĂŒd kulub umbes 2 minutit.
Kui olin veendunud, et kĂ”ik probleemid on lahendatud, eemaldasin 300 miljonit kirjet. Kustutasin tabeli ja tundsin end taas sĂŒndinuna.
KokkuvÔte
MÔistsin, et partii töötlemisel jÀeti kÔrvale pööramisprotsess, ja selles peitus peamine probleem. Selline arhitektuuri viga pÔhjustab aega raiskamist.
Kuidas te mĂ”tlete andmete replikatsiooni koormusele, kustutades kirjeid andmebaasist? Ărge koormake MySQL-i.
Need, kes tunnevad andmebaase hĂ€sti, ei puutu selliste probleemidega tĂ”enĂ€oliselt kokku. Ja ĂŒlejÀÀnutele, loodan, et see artikkel oli kasulik.
AitÀh lugemise eest!
Oleksime vÀga rÔÔmsad, kui rÀÀgiksite meile, kas see artikkel meeldis teile, kas tÔlge oli selge, ja kas see oli teile kasulik?
Allikas: habr.com
