Priča o fizičkom brisanju 300 milijuna 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 milijuna zapisa u MySQL-u.

Zainteresiralo me to pa sam odlučio napraviti podsjetnik (upute).

Dom - uzbuna

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

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

Tragajući za razlogom

Pokušao sam ponovno pokrenuti proces i pogledati zapisnike, ali nisam vidio ništa loše.
Upit je ispravno indeksiran. Ali kad sam razmišljao o tome što je pošlo po zlu, shvatio sam da je veličina baze podataka prilično velika.

hoge_table | 350'000'000 |

350 milijuna zapisa. Čini se da indeksiranje radi ispravno, samo vrlo sporo.

Mjesečno potrebno prikupljanje podataka iznosilo je približno 12 zapisa. Čini se da je naredba za odabir dugo trajala i da transakcija nije izvršena dugo vremena.

DB

To je u biti tablica koja svaki dan raste za oko 400 unosa. Baza je trebala prikupljati podatke samo za prošli mjesec, stoga se očekivalo da će izdržati upravo toliku količinu podataka, ali nažalost nije uključena operacija rotiranja.

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

Došlo je do točke kada je količina dnevno unesenih podataka postala velika i konačno dosegla svoju granicu. Pretpostavlja se da bi pri radu s tako velikom količinom podataka bilo potrebno njihovo razdvajanje, no to, nažalost, nije učinjeno.

A onda sam ja stupio u akciju.

Ispravka

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

Situacija bi se trebala značajno promijeniti ako obrišete 300 milijuna zapisa, pa sam se tako odlučio... Eh, mislio sam da će ovo sigurno uspjeti.

Radnja 1

Nakon što sam pripremio pouzdanu sigurnosnu 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 dugo traje?” — pomislio sam, ali sam za svaki slučaj pogledao grafana i vidio da opterećenje diska raste vrlo brzo.
“Opasno”, opet sam pomislio i odmah zaustavio zahtjev.

Radnja 2

Nakon što sam sve analizirao, shvatio sam da je količina podataka prevelika za brisanje svih odjednom.

Odlučio sam napisati skriptu koja bi mogla izbrisati oko 1 zapisa i pokrenuo je.

「Implementiram skriptu」

"Ovo će sigurno upaliti", pomislio sam.

Radnja 3

Druga je metoda djelovala, ali se pokazalo vrlo zahtjevnom.
Da se sve obavi pažljivo, bez nepotrebnih živaca, trebalo bi oko dva tjedna. Ipak, ovaj scenarij nije ispunjavao zahtjeve usluge, pa smo se morali odmaknuti od njega.

Pa evo što sam odlučio učiniti:

Kopirajte tablicu i preimenujte je

Iz prethodnog koraka shvatio sam da brisanje tako velike količine podataka stvara jednako veliko opterećenje. Stoga sam odlučio stvoriti novu tablicu od nule pomoću umetanja i premjestiti podatke koje sam namjeravao izbrisati u nju.

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

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

Nakon što sam napravio tablicu i preimenovao je, počeo sam je koristiti kao glavnu tablicu. Sad ako ispustim tablicu s 300 milijuna zapisa, sve bi trebalo biti u redu.
Saznao sam da skraćivanje ili ispuštanje stvara manje troškova nego brisanje i odlučio sam koristiti ovu metodu.

izvršenje

「Slanje zahtjeva」

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

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

Radnja 4

Mislio sam da će prethodna ideja uspjeti, 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 misliti da ne želim ovo više raditi.

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

Pa, nakon toga nastavljamo slati zahtjeve za istom količinom podataka. Budući da moramo ukloniti podatke za mjesec dana, ovu operaciju ponavljamo otprilike 35 puta.

Preimenovanje tablice

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

Upozorenje je nestalo

Brzina skupne obrade je povećana.

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

Nakon što sam bio siguran da su svi problemi riješeni, izbacio sam 300 milijuna zapisa. Izbrisao sam tablicu i osjećao se preporođeno.

Sažetak

Shvatio sam da u skupnoj obradi nedostaje rotacijska obrada i to je glavni problem. Ova vrsta arhitektonske pogreške dovodi do gubitka vremena.

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

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

Hvala na čitanju!

Bit će nam drago ako nam kažete je li vam se svidio ovaj članak, je li prijevod jasan, je li vam bio koristan?

Izvor: www.habr.com

Dodajte komentar