Historia e fshirjes fizike të 300 milionë regjistrimeve në MySQL

Hyrje

Përshëndetje. Unë jam ningenMe, zhvillues web-i.

Siç e thotë titulli, historia ime është një histori mbi fshirjen fizike të 300 milionë rekordëve në MySQL.

Isha i interesuar për këtë, kështu që vendosa të bëj një shënim (udhëzues).

Fillimi — Alert

Në paketën serveri, e cila përdorim dhe mbaj, ka një proces të rregullt që një herë në ditë mbledh të dhënat e muajit të fundit nga MySQL.

Zakonisht, ky proces përfundon rreth 1 ore, por këtë herë nuk përfundonte për 7 ose 8 orë, dhe alert nuk ndalej...

Gjetja e shkakut

Provoja të rinis procesin, të shikoj log-et, por nuk pashë asgjë të keqe.
Kërkesa ishte e indeksuar siç duhet. Por kur mendoja se çfarë po shkonte keq, kuptova se volumi i DB ishte mjaft i madh.

hoge_table | 350'000'000 |

350 milionë rekordë. Duket se indeksimi po punonte siç duhet, thjesht shumë ngadalë.

Mbledhja e të dhënave për muajin ishte rreth 12,000,000 rekordë. Duket se ekipi select mori shumë kohë, dhe transaksioni nuk përfundonte për një periudhë të gjatë.

DB

Në thelb, kjo është një tabelë që rritet çdo ditë me rreth 400,000 rekordë. Baza duhej të mbledhë të dhënat vetëm për muajin e fundit, prandaj llogaritja ishte për këtë volum të dhënash, por, për fat të keq, operacioni rotate nuk ishte aktivizuar.

Kjo bazë të dhënash nuk u zhvillua nga unë. E mora nga një zhvillues tjetër, prandaj ka një ndjenjë të borxhit teknik.

Arriti një moment kur volumi i të dhënave të futur ditor u bë i madh dhe më në fund arriti kufirin. Supozohen që, duke punuar me një volum kaq të madh të dhënash, do të duhej t'i ndaheshin, por për fat të keq, kjo nuk u bë.

Dhe këtu hyra unë.

Rregullimi

Ishin më racional të zvogëlohej vetë DB dhe të shkurtohej koha e saj e përpunimit, sesa të ndryshohej logjika e saj.

Situata duhet të ndryshojë ndjeshëm, nëse fshihen 300 milionë rekordë, kështu që vendosa ta bëj atë... Eh, mendoja se kjo do të funksiononte.

Veprimi 1

Pas përgatitjes së një kopje rezervë të besueshme, përfundimisht fillova të dërgoj kërkesa.

「DĂ«rgimi i kĂ«rkesĂ«s」

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

「
」

「
」

“Hmm... S'ka pĂ«rgjigje. Ndoshta procesi merr shumĂ« kohĂ«?” — mendova, por pĂ«r çdo rast shikova nĂ« grafana dhe pashĂ« se ngarkesa e diskut po rritej shumĂ« shpejt.
“RrezikshĂ«m” — mendova prapĂ« dhe menjĂ«herĂ« ndalova kĂ«rkesĂ«n.

Veprimi 2

Pas analizimit të gjithçkaje, kuptova se volumi i të dhënave ishte shumë i madh për ta fshirë të gjithë një herë.

Vendosa të shkruaj një skenar që mund të fshijë rreth 1,000,000 rekordë dhe e nisa atë.

「Implementoj skenarin」

“Tani do tĂ« funksionojĂ« sigurisht,” — mendova.

Veprimi 3

Metoda e dytë funksionoi, por u soll shumë punë intensive.
Për ta bërë gjithçka në mënyrë korrekte, pa nerva të tepërta, do të nevojiteshin rreth dy javë. Megjithatë, ky skenar nuk përputhej me kërkesat e shërbimeve, kështu që duhej ta lija mënjanë.

Prandaj, ja çfarë vendosa të bëj:

Kopjoj tabelën dhe e ribesoj

Nga hapi i mëparshëm kuptova se fshirja e një volumi kaq të madh të dhënash krijon një ngarkesë të tillë të madhe. Prandaj, vendosa të krijoj një tabelë të re nga zero me ndihmën e insert dhe për të transferuar të dhënat që duhej të fshiheshin.

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

Nëse e krijoj tabelën e re me madhësinë e mësipërme, shpejtësia e përpunimit të të dhënave gjithashtu duhet të bëhet 1/7 më e shpejtë.

Pasi krijova tabelën dhe e ribesha, fillova ta përdor si tabelën master. Tani, nëse fshij 300 milionë rekordë, gjithçka duhet të jetë në rregull.
Mësoha se truncate ose drop krijojnë një ngarkesë më të vogël sesa delete dhe vendosa të përdor këtë mënyrë.

Ekzekutimi

「DĂ«rgimi i kĂ«rkesĂ«s」

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

「
」
「
」
「ehâ€ŠïŒŸă€

Veprimi 4

Mendoja se ideja e mëparshme do të funksiononte, por pas dërgimit të kërkesës insert u shfaqën shumë gabime. MySQL nuk kursen.

Isha aq i lodhur sa fillova të mendoj se nuk do të doja më të merrem me këtë.

Pas një kohe, mendova se ndoshta për një herë ishin shumë kërkesa insert...
Provova të dërgoj një kërkesë insert për volumin e të dhënave që baza kishte për të përpunuar për një ditë. Arriti!

Pas kësaj vazhdoj të dërgoj kërkesa për të njëjtin volum të të dhënave. Duke qenë se duhet të largohet volumi mujor i të dhënave, e përsëris këtë operacion rreth 35 herë.

Ribeshimi i tabelës

Këtu mu dha fati: gjithçka shkoi pa probleme.

Alertet u zhdukën.

Shpejtësia e përpunimit të paketave u rrit.

Më parë ky proces zgjaste rreth një orë, tani zgjat rreth 2 minuta.

Pasi u sigurova që të gjitha problemet ishin zgjidhur, e hodha poshtë 300 milionët e rekordëve. E hodha tabelën dhe ndjeva se isha rilindur.

Përmbledhje

Kam kuptova se gjatë përpunimit me grup, u humb përpunimi i rotacionit, dhe kjo ishte problemi kryesor. Një gabim i tillë në arkitekturë çon në humbje të kotë kohe.

A mendoni për ngarkesën gjatë replikimit të të dhënave, kur fshini regjistrime nga baza? Le ta shmangim mbingarkesën në MySQL.

Ata që dinë mirë për bazat e të dhënave nuk do të hasin një problem të tillë. Ndërsa për të tjerët, shpresoj se ky artikull ishte i dobishëm.

Faleminderit për leximin!

Do të ishim shumë të lumtur nëse na tregoni nëse ju pëlqeu ky artikull, nëse përkthimi ishte i qartë, dhe nëse ishte i dobishëm për ju?

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster