Jutt fĂŒĂŒsilisest kustutamisest 300 miljoni kirje osas MySQL-is

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

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster