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

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

Shto një koment