Tarina 300 miljoonan tietueen fyysisestä poistamisesta MySQL:ssä

Esittely

Hei. Olen ningenMe, verkkokehittäjä.

Kuten otsikko sanoo, tarinani on tarina 300 miljoonan tietueen fyysisesta poistamisesta MySQL:ssä.

Kiinnostuin tästä, joten päätin tehdä muistutuksen (ohjeet).

Koti - Varoitus

Käyttämäni ja ylläpitämässäni eräpalvelimessa on säännöllinen prosessi, joka kerää viimeisen kuukauden tiedot MySQL:stä kerran päivässä.

Yleensä tämä prosessi valmistuu noin 1 tunnissa, mutta tällä kertaa se ei päättynyt 7 tai 8 tuntiin, eikä hälytys lakannut ilmestymästä...

Syytä etsimässä

Yritin käynnistää prosessin uudelleen ja katsoa lokeja, mutta en nähnyt mitään vikaa.
Kysely indeksoitiin oikein. Mutta kun mietin, mikä meni pieleen, tajusin, että tietokannan koko on melko suuri.

hoge_table | 350'000'000 |

350 miljoonaa levyä. Indeksointi näytti toimivan oikein, vain hyvin hitaasti.

Vaadittu tiedonkeruu kuukaudessa oli noin 12 000 000 tietuetta. Näyttää siltä, ​​että Select-komento kesti kauan ja tapahtumaa ei suoritettu pitkään aikaan.

DB

Se on pohjimmiltaan taulukko, joka kasvaa noin 400 000 merkinnällä joka päivä. Tietokannan piti kerätä tietoja vain viimeiseltä kuukaudelta, joten sen odotettiin kestävän juuri tämän määrän dataa, mutta kiertotoimintoa ei valitettavasti otettu mukaan.

Tätä tietokantaa en ole kehittänyt. Otin sen toiselta kehittäjältä, joten se tuntui silti tekniseltä velalta.

Tuli kohta, jolloin päivittäin lisättävän tiedon määrä kasvoi suureksi ja saavutti lopulta rajansa. Oletetaan, että kun työskennellään niin suuren tietomäärän kanssa, ne olisi erotettava toisistaan, mutta valitettavasti näin ei tehty.

Ja sitten aloin toimia.

Korjaus

Oli järkevämpää pienentää itse tietokannan kokoa ja lyhentää sen käsittelyaikaa kuin muuttaa itse logiikkaa.

Tilanteen pitäisi muuttua merkittävästi, jos pyyhit 300 miljoonaa tietuetta, joten päätin tehdä niin... Eh, luulin, että tämä toimisi varmasti.

Toimi 1

Valmisteltuani luotettavan varmuuskopion aloin vihdoin lähettää pyyntöjä.

「Pyynnön lähettäminen」

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

"…"

"…"

"Hmm... Ei vastausta. Ehkä prosessi kestää kauan?" — Ajattelin, mutta varmuuden vuoksi katsoin grafanaa ja huomasin, että levykuorma kasvoi hyvin nopeasti.
"Vaarallista", ajattelin uudelleen ja lopetin heti pyynnön.

Toimi 2

Analysoituani kaiken huomasin, että datamäärä oli liian suuri poistaakseni kaiken kerralla.

Päätin kirjoittaa käsikirjoituksen, joka voisi poistaa noin 1 000 000 tietuetta, ja käynnistin sen.

"Täytän käsikirjoituksen"

"Nyt tämä varmasti toimii", ajattelin.

Toimi 3

Toinen menetelmä toimi, mutta osoittautui erittäin työvoimavaltaiseksi.
Kaiken huolellinen tekeminen ilman turhia hermoja kestäisi noin kaksi viikkoa. Mutta silti tämä skenaario ei täyttänyt palveluvaatimuksia, joten meidän piti siirtyä pois siitä.

Joten tässä päätin tehdä:

Kopioi taulukko ja nimeä se uudelleen

Edellisessä vaiheessa ymmärsin, että näin suuren tietomäärän poistaminen luo yhtä suuren kuormituksen. Joten päätin luoda uuden taulukon tyhjästä lisäämällä ja siirtää tiedot, jotka aion poistaa siihen.

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

Jos teet uudesta taulukosta samankokoisen kuin yllä, tietojenkäsittelynopeuden tulisi myös olla 1/7 nopeampi.

Taulukon luomisen ja uudelleen nimeämisen jälkeen aloin käyttää sitä päätaulukkona. Nyt jos pudotan pöydän 300 miljoonalla tietueella, kaiken pitäisi olla kunnossa.
Huomasin, että katkaiseminen tai pudottaminen aiheuttaa vähemmän kuluja kuin poistaminen, ja päätin käyttää tätä menetelmää.

suoritus

「Pyynnön lähettäminen」

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

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

Toimi 4

Luulin, että edellinen idea toimisi, mutta lisäyspyynnön lähettämisen jälkeen ilmestyi useita virheitä. MySQL ei anna anteeksi.

Olin jo niin väsynyt, että aloin ajatella, etten halua tehdä tätä enää.

Istuin ja mietin ja tajusin, että ehkä oli liian monta lisäyskyselyä kerralla...
Yritin lähettää lisäyspyynnön datamäärästä, jonka tietokannan pitäisi käsitellä 1 päivässä. Tapahtui!

No, sen jälkeen jatkamme pyyntöjen lähettämistä samalle määrälle dataa. Koska meidän on poistettava kuukauden verran tietoja, toistamme tämän toiminnon noin 35 kertaa.

Taulukon nimeäminen uudelleen

Tässä onni oli puolellani: kaikki sujui hyvin.

Varoitus katosi

Eräkäsittelyn nopeus on kasvanut.

Aikaisemmin tämä prosessi kesti noin tunnin, nyt se kestää noin 2 minuuttia.

Kun olin varma, että kaikki ongelmat oli ratkaistu, pudotin 300 miljoonaa ennätystä. Poistin taulukon ja tunsin uudestisyntyneeni.

Yhteenveto

Ymmärsin, että kiertokäsittely puuttui eräkäsittelyssä, ja se oli suurin ongelma. Tällainen arkkitehtoninen virhe johtaa ajanhukkaan.

Ajatteletko kuormitusta tietojen replikoinnin aikana, kun poistat tietueita tietokannasta? Älä ylikuormita MySQL:ää.

Tietokantoihin perehtyneet eivät varmasti kohtaa tällaista ongelmaa. Toivon teille muille, että tämä artikkeli oli hyödyllinen.

Kiitos lukemisesta!

Olemme erittäin iloisia, jos kerrot meille, piditkö tästä artikkelista, onko käännös selkeä, oliko siitä sinulle hyötyä?

Lähde: will.com

Lisää kommentti