Priča o fizičkom brisanju 300 miliona zapisa u MySQL-u

Uvod

Zdravo. Ja sam ningenMe, web programer.

Kao što naslov kaže, moja priča je priča o fizičkom brisanju 300 miliona zapisa u MySQL-u.

Zainteresovalo me to, pa sam odlučio da napravim podsjetnik (uputstvo).

Početna - Upozorenje

Batch server koji koristim i održavam ima redovan proces koji prikuplja podatke za prošli mjesec iz MySQL-a jednom dnevno.

Obično se ovaj proces završi u roku od oko 1 sat, ali ovaj put nije završen 7 ili 8 sati, a upozorenje nije prestalo da iskače...

Pronalaženje razloga

Pokušao sam ponovo pokrenuti proces i pogledati dnevnike, ali nisam vidio ništa loše.
Upit je ispravno indeksiran. Ali kada sam razmislio šta nije u redu, shvatio sam da je veličina baze podataka prilično velika.

hoge_table | 350'000'000 |

350 miliona zapisa. Činilo se da indeksiranje radi ispravno, samo vrlo sporo.

Mjesečno je potrebno prikupljanje podataka oko 12 zapisa. Izgleda da je naredba za odabir trajala dugo i da transakcija nije bila izvršena dugo vremena.

DB

To je u suštini tabela koja svaki dan raste za oko 400 unosa. Baza je trebala prikupljati podatke samo za prošli mjesec, pa se očekivalo da će izdržati upravo ovoliku količinu podataka, ali, nažalost, operacija rotacije nije uključena.

Ovu bazu podataka nisam razvio ja. Preuzeo sam ga od drugog programera, tako da se i dalje osjećao kao tehnički dug.

Došao je trenutak kada je količina podataka koji se ubacuju dnevno postala velika i konačno dostigla svoj limit. Pretpostavlja se da bi pri radu sa tako velikom količinom podataka bilo potrebno da ih razdvojimo, ali to, nažalost, nije učinjeno.

A onda sam krenuo u akciju.

Ispravka

Racionalnije je bilo smanjiti veličinu same baze podataka i smanjiti vrijeme za njenu obradu nego promijeniti samu logiku.

Situacija bi se trebala bitno promijeniti ako izbrišete 300 miliona zapisa, pa sam se odlučio na to... Eh, mislio sam da će ovo sigurno uspjeti.

Akcija 1

Nakon što sam pripremio pouzdanu rezervnu kopiju, konačno sam počeo slati zahtjeve.

「Slanje zahtjeva」

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

「…」

「…」

“Hmm... Bez odgovora. Možda proces traje dugo?” — Mislio sam, ali za svaki slučaj, pogledao sam grafanu i vidio da opterećenje diska raste vrlo brzo.
„Opasno“, pomislio sam ponovo i odmah prekinuo zahtev.

Akcija 2

Nakon što sam sve analizirao, shvatio sam da je količina podataka prevelika da bih sve izbrisao odjednom.

Odlučio sam da napišem skriptu koja može izbrisati oko 1 zapisa i pokrenuo sam je.

「Ja implementiram scenario」

„Sad će ovo definitivno upaliti“, pomislio sam.

Akcija 3

Druga metoda je uspjela, ali se pokazala vrlo radno intenzivnom.
Za sve pažljivo, bez nepotrebnih živaca, trebalo bi oko dvije sedmice. Ali ipak, ovaj scenario nije zadovoljio zahtjeve usluge, pa smo se morali odmaknuti od njega.

Evo šta sam odlučio da uradim:

Kopirajte tabelu i preimenujte je

Iz prethodnog koraka shvatio sam da brisanje tako velike količine podataka stvara jednako veliko opterećenje. Tako sam odlučio da kreiram novu tabelu od nule koristeći umetanje i premestim podatke koje sam nameravao da izbrišem u nju.

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

Ako novu tablicu napravite iste veličine kao gore, brzina obrade podataka bi također trebala postati 1/7 veća.

Nakon kreiranja tabele i preimenovanja, počeo sam da je koristim kao glavnu tabelu. Sada ako odbacim tabelu sa 300 miliona zapisa, sve bi trebalo biti u redu.
Saznao sam da skraćivanje ili ispuštanje stvara manje troškove od brisanja i odlučio sam da koristim ovu metodu.

Performanse

「Slanje zahtjeva」

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

「…」
「…」
"Em...?"

Akcija 4

Mislio sam da će prethodna ideja funkcionirati, ali nakon slanja zahtjeva za umetanje pojavilo se više grešaka. MySQL ne oprašta.

Već sam bio toliko umoran da sam počeo da mislim da ne želim više ovo da radim.

Sjedio sam i razmišljao i shvatio da je možda bilo previše upita za umetanje za jedan put...
Pokušao sam poslati zahtjev za umetanje količine podataka koju bi baza podataka trebala obraditi za 1 dan. Desilo se!

Pa, nakon toga nastavljamo sa slanjem zahtjeva za istu količinu podataka. Budući da trebamo ukloniti mjesečne podatke, ovu operaciju ponavljamo otprilike 35 puta.

Preimenovanje tabele

Tu je sreća bila na mojoj strani: sve je prošlo glatko.

Upozorenje je nestalo

Brzina grupne obrade je povećana.

Ranije je ovaj proces trajao oko sat vremena, sada traje oko 2 minute.

Nakon što sam bio siguran da su svi problemi riješeni, ispustio sam 300 miliona ploča. Izbrisao sam tabelu i osetio se preporođenim.

Sažetak

Shvatio sam da u batch obradi nedostaje obrada rotacije i to je bio glavni problem. Ovakva arhitektonska greška dovodi do gubljenja vremena.

Razmišljate li o opterećenju prilikom replikacije podataka prilikom brisanja zapisa iz baze podataka? Nemojmo preopteretiti MySQL.

Oni koji su dobro upućeni u baze podataka sigurno se neće susresti s takvim problemom. Za vas ostale, nadam se da je ovaj članak bio koristan.

Hvala na čitanju!

Biće nam drago ako nam kažete da li vam se dopao ovaj članak, da li je prevod jasan, da li vam je bio od koristi?

izvor: www.habr.com

Dodajte komentar