Paraqitje
Përshëndetje. Unë jam ningenMe, zhvilluesi i uebit.
Siç thotë titulli, historia ime është historia e fshirjes fizike të 300 milionë regjistrimeve në MySQL.
U interesova për këtë, kështu që vendosa të bëj një kujtesë (udhëzime).
Faqja kryesore - Alert
Serveri i grupit që përdor dhe mirëmbaj ka një proces të rregullt që mbledh të dhënat e muajit të fundit nga MySQL një herë në ditë.
Zakonisht ky proces përfundon brenda rreth 1 ore, por këtë herë nuk ka përfunduar për 7 ose 8 orë dhe alarmi nuk ka pushuar së shfaquri...
Duke kërkuar për një arsye
U përpoqa të rifilloja procesin dhe të shikoja regjistrat, por nuk pashë asgjë të keqe.
Kërkesa u indeksua saktë. Por kur mendova se çfarë po shkonte keq, kuptova se madhësia e bazës së të dhënave është mjaft e madhe.
hoge_table | 350'000'000 |
350 milionë rekorde. Indeksimi dukej se po funksiononte si duhet, thjesht shumë i ngadalshëm.
Mbledhja e kërkuar e të dhënave në muaj ishte afërsisht 12 regjistrime. Duket sikur komanda zgjidhni mori shumë kohë dhe transaksioni nuk u ekzekutua për një kohë të gjatë.
DB
Në thelb është një tabelë që rritet me rreth 400 hyrje çdo ditë. Baza e të dhënave duhej të mblidhte të dhëna vetëm për muajin e fundit, prandaj pritej që të përballonte pikërisht këtë sasi të dhënash, por, për fat të keq, operacioni i rrotullimit nuk ishte përfshirë.
Kjo bazë të dhënash nuk është zhvilluar nga unë. E mora përsipër nga një zhvillues tjetër, kështu që ndihej ende si borxh teknik.
Erdhi një moment kur vëllimi i të dhënave të futura çdo ditë u bë i madh dhe më në fund arriti kufirin e tij. Supozohet se kur punoni me një sasi kaq të madhe të dhënash, do të ishte e nevojshme t'i ndani ato, por kjo, për fat të keq, nuk u bë.
Dhe pastaj hyra në veprim.
Korrigjim
Ishte më racionale të zvogëlohej madhësia e vetë bazës së të dhënave dhe të zvogëlohej koha për përpunimin e saj sesa të ndryshonte vetë logjikën.
Situata duhet të ndryshojë ndjeshëm nëse fshihen 300 milionë regjistrime, ndaj vendosa ta bëj këtë... Eh, mendova se kjo do të funksiononte patjetër.
Veprim 1
Pasi përgatita një kopje rezervë të besueshme, më në fund fillova të dërgoja kërkesa.
''Dërgimi i një kërkese''
DELETE FROM hoge_table WHERE create_time <= 'YYYY-MM-DD HH:MM:SS';
"…"
"…"
“Hmm... Asnjë përgjigje. Ndoshta procesi kërkon shumë kohë?” — Mendova, por për çdo rast, pashë grafana dhe pashë që ngarkesa e diskut po rritej shumë shpejt.
"E rrezikshme," mendova përsëri dhe e ndalova menjëherë kërkesën.
Veprim 2
Pasi analizova gjithçka, kuptova se vëllimi i të dhënave ishte shumë i madh për të fshirë gjithçka menjëherë.
Vendosa të shkruaj një skenar që mund të fshinte rreth 1 regjistrime dhe e nisa atë.
"Unë zbatoj skenarin"
"Tani kjo patjetër do të funksionojë," mendova.
Veprim 3
Metoda e dytë funksionoi, por doli të ishte shumë punë intensive.
Për të bërë gjithçka me kujdes, pa nerva të panevojshëm, do të duheshin rreth dy javë. Por gjithsesi, ky skenar nuk i plotësonte kërkesat e shërbimit, ndaj na u desh të largoheshim prej tij.
Pra, ja çfarë vendosa të bëj:
Kopjoni tabelën dhe riemërtoni atë
Nga hapi i mëparshëm, kuptova se fshirja e një sasie kaq të madhe të dhënash krijon një ngarkesë po aq të madhe. Kështu që vendosa të krijoj një tabelë të re nga e para duke përdorur insert dhe të zhvendos të dhënat që do të fshija në të.
| hoge_table | 350'000'000|
| tmp_hoge_table | 50'000'000|
Nëse e bëni tabelën e re të njëjtën madhësi si më sipër, shpejtësia e përpunimit të të dhënave duhet gjithashtu të bëhet 1/7 më e shpejtë.
Pas krijimit të tabelës dhe riemërtimit të saj, fillova ta përdor atë si tabelën kryesore. Tani nëse e heq tabelën me 300 milionë rekorde gjithçka duhet të jetë mirë.
Zbulova se shkurtimi ose rënia krijon më pak shpenzime sesa fshirja dhe vendosa të përdor këtë metodë.
ekzekutim
''Dërgimi i një kërkese''
INSERT INTO tmp_hoge_table SELECT FROM hoge_table create_time > 'YYYY-MM-DD HH:MM:SS';
"…"
"…"
"Em...?"
Veprim 4
Mendova se ideja e mëparshme do të funksiononte, por pas dërgimit të kërkesës për futje, u shfaqën gabime të shumta. MySQL nuk fal.
Unë tashmë isha aq i lodhur sa fillova të mendoj se nuk doja ta bëja më këtë.
U ula dhe mendova dhe kuptova se ndoshta kishte shumë pyetje për futje për një herë...
Provova të dërgoja një kërkesë insert për sasinë e të dhënave që baza e të dhënave duhet të përpunojë brenda 1 dite. Ndodhi!
Epo, pas kësaj ne vazhdojmë të dërgojmë kërkesa për të njëjtën sasi të dhënash. Meqenëse duhet të heqim të dhënat e një muaji, ne e përsërisim këtë operacion afërsisht 35 herë.
Riemërtimi i një tabele
Këtu fati ishte në anën time: gjithçka shkoi mirë.
Alarmi është zhdukur
Shpejtësia e përpunimit në grup është rritur.
Më parë ky proces zgjati rreth një orë, tani zgjat rreth 2 minuta.
Pasi u sigurova që të gjitha problemet ishin zgjidhur, hodha 300 milionë rekorde. Fshiva tabelën dhe u ndjeva i rilindur.
Përmbledhje
Kuptova se përpunimi me rotacion mungonte në përpunimin e grupeve dhe ky ishte problemi kryesor. Ky lloj gabimi arkitektonik çon në humbje kohe.
A mendoni për ngarkesën gjatë riprodhimit të të dhënave kur fshini të dhënat nga baza e të dhënave? Le të mos mbingarkojmë MySQL.
Ata që janë të aftë për bazat e të dhënave definitivisht nuk do të hasin në një problem të tillë. Për pjesën tjetër prej jush, shpresoj se ky artikull ishte i dobishëm.
Faleminderit per leximin!
Do të jemi shumë të lumtur nëse na tregoni nëse ju pëlqeu ky artikull, nëse përkthimi është i qartë, nëse ishte i dobishëm për ju?
Burimi: www.habr.com