Hyrje
Përshëndetje. Unë jam ningenMe, zhvillues ueb.
Siç thotë titulli, historia ime është një histori mbi fshirjen fizike të 300 milion rekordëve në MySQL.
Më interesoi ky temë, prandaj vendosa të bëj një udhëzues (instruksion).
Fillimi â Alert
Në paketën server, të cilën e përdor dhe mirëmbaj, ka një proces të rregullt që një herë në ditë mbledh të dhënat e muajit të fundit nga MySQL.
Zakonisht ky proces mbyllet brenda rreth 1 ore, por kĂ«tĂ« herĂ« nuk u mbyll pĂ«r 7 ose 8 orĂ«, dhe alarmin nuk e ndalejâŠ
Kërkimi i shkakut
Kam provuar të riaktivizoj procesin, të shikoj log-et, por nuk pashë asgjë alarmante.
Kërkesa u indeksua siç duhet. Por kur mendova se çfarë nuk shkon, e kuptova se volume i databazës ishte mjaft i madh.
hoge_table | 350'000'000 |350 milion rekordë. Duket se indeksi punonte siç duhet, thjesht shumë ngadalë.
Grumbullimi i të dhënave për muajin ishte rreth 12 000 000 rekordë. Duket se ekipi i select i mori shumë kohë, dhe transaksioni nuk përfundonte për një kohë të gjatë.
DB
Në thelb, kjo është një tabelë që çdo ditë rritet me rreth 400 000 rekordë. Baza duhej të grumbullonte të dhëna vetëm për muajin e fundit, prandaj llogaritja ishte që do të përballonte pikërisht këtë volum të të dhënave, por, fatkeqësisht, operacioni rotate nuk ishte aktivizuar.
Kjo databazë nuk ishte zhvilluar nga unë. E kam marrë atë nga një zhvillues tjetër, prandaj mbetet një ndjenjë e këtij borxhi teknik.
Arriti momenti kur volumi i të dhënave të vendosura përditë u bë i madh dhe përfundimisht arriti kufirin. Suppozimi është se duke punuar me një volum të tillë të dhënash, do të duhej t'i ndanë ato, por fatkeqësisht, kjo nuk ishte bërë.
Dhe këtu hyra në veprim.
Korrigjimi
Ishte më racional të zvogëloja veten e databazës dhe të shkurtoja kohën e saj për përpunim, sesa të ndryshoja logjikën e saj.
Situata duhet të ndryshojë ndjeshëm nëse fshij 300 milion rekordë, prandaj vendosa ta bëja këtë⊠Eh, mendova se do të funksiononte patjetër.
Veprimi 1
Pas përgatitjes së një kopjeje të besueshme, më në fund fillova të dërgoj kërkesat.
ăDĂ«rgimi i kĂ«rkesĂ«să
DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';ăâŠă
ăâŠă
âHmm⊠Nuk ka pĂ«rgjigje. Mund tĂ« jetĂ« se procesi merr shumĂ« kohĂ«?â â mendova unĂ«, por tĂ« bĂ«ja njĂ« verifikim nĂ« grafana dhe pashĂ« se ngarkesa e diskut po rritej shumĂ« shpejt.
«I should be careful» â I thought again and immediately stopped the request.
Action 2
After analyzing everything, I realized that the amount of data was too great to delete it all at once.
I decided to write a script that could delete about 1,000,000 records and started it.
ăI'll implement the scriptă
âNow it will definitely work,â â I thought.
Action 3
The second method worked but turned out to be very labor-intensive.
To do everything neatly and without extra nerves, it would take about two weeks. However, this scenario did not meet the service requirements, so I had to abandon it.
Therefore, hereâs what I decided to do:
We copy the table and rename it
From the previous step, I understood that deleting such a large volume of data creates an equally large load. Therefore, I decided to create a new table from scratch using insert and move the data I intended to delete into it.
| hoge_table | 350'000'000|
| tmp_hoge_table | 50'000'000|If I create a new table of the same size as indicated above, the speed of data processing should also become 1/7 faster.
After creating the table and renaming it, I began using it as the master table. Now, if I delete a table with 300 million records, everything should be fine.
I learned that truncate or drop create less load than delete, and I decided to use this method.
Execution
ăDĂ«rgimi i kĂ«rkesĂ«să
INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS'; ăâŠă
ăâŠă
ăUmâŠïŒă
Action 4
I thought the previous idea would work, but after sending the insert request, there were multiple errors. MySQL is unforgiving.
I was so exhausted that I started to think I didnât want to deal with this anymore.
I sat down and thought about it and realized that maybe, for one time, there were too many insert requestsâŠ
I tried to send an insert request for the amount of data that the database should process in one day. It worked!
Well, after that, we continue sending requests for the same amount of data. Since we need to remove a month's worth of data, we repeat this operation about 35 times.
Renaming the table
Here, luck was on my side: everything went smoothly.
Alerts disappeared
The speed of batch processing increased.
Previously, this process took about an hour; now it takes about 2 minutes.
Pasi i u sigurda që të gjitha problemet janë zgjidhur, kam hequr 300 milion rekordet. Kam fshirë tabelën dhe ndihesha si i rinovuar.
Përmbledhja
Kuptova se gjatë përpunimit në grup, ishte humbur procesi i rotacionit, dhe kjo ishte problemi kryesor. Një gabim i tillë në arkitekturë çon në humbje të kotë kohe.
A shqetësoheni për ngarkesën gjatë replikimit të të dhënave, duke fshirë rekordet nga baza e të dhënave? Le të mos e mbingarkojmë MySQL.
Ata që e kuptojnë mirë bazën e të dhënave padyshim nuk do të përballen me një problem të tillë. Shpresoj që ky artikull të ketë qenë i dobishëm për të tjerët.
Faleminderit që e lexuat!
Do të ishim shumë të lumtur nëse do të na thoni nëse ju pëlqi ky artikull, nëse përkthimi ishte i qartë, dhe nëse ishte i dobishëm për ju?
Burimi: habr.com
