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
