Stāsts par 300 miljonu ierakstu fizisku dzēšanu pakalpojumā MySQL

Ievads

Sveiki. Es esmu ningenMe, tīmekļa izstrādātājs.

Kā saka virsraksts, mans stāsts ir stāsts par 300 miljonu ierakstu fizisku dzēšanu pakalpojumā MySQL.

Mani tas sāka interesēt, tāpēc nolēmu uztaisīt atgādinājumu (instrukciju).

Sākums — brīdinājums

Pakešserverim, kuru izmantoju un uzturu, ir regulārs process, kas reizi dienā apkopo pēdējā mēneša datus no MySQL.

Parasti šis process tiek pabeigts aptuveni 1 stundas laikā, taču šoreiz tas netika pabeigts 7 vai 8 stundas, un brīdinājums nepārstāja parādīties...

Meklē iemeslu

Es mēģināju atsākt procesu un apskatīt žurnālus, bet es neredzēju neko sliktu.
Vaicājums tika indeksēts pareizi. Bet, domājot par to, kas notiek nepareizi, es sapratu, ka datu bāzes apjoms ir diezgan liels.

hoge_table | 350'000'000 |

350 miljoni ierakstu. Šķita, ka indeksēšana darbojas pareizi, tikai ļoti lēni.

Nepieciešamā datu vākšana mēnesī bija aptuveni 12 000 000 ierakstu. Izskatās, ka atlases komanda aizņēma ilgu laiku un transakcija netika izpildīta ilgu laiku.

DB

Būtībā tā ir tabula, kas katru dienu pieaug par aptuveni 400 000 ierakstu. Datu bāzei bija paredzēts apkopot datus tikai par pēdējo mēnesi, tāpēc bija paredzēts, ka tā izturēs tieši šādu datu apjomu, taču diemžēl rotācijas darbība netika iekļauta.

Šo datu bāzi neesmu izstrādājis es. Es to pārņēmu no cita izstrādātāja, tāpēc tas joprojām likās kā tehniskais parāds.

Pienāca brīdis, kad katru dienu ievietoto datu apjoms kļuva liels un beidzot sasniedza savu robežu. Tiek pieļauts, ka, strādājot ar tik lielu datu apjomu, būtu nepieciešams tos atdalīt, taču tas diemžēl netika izdarīts.

Un tad es sāku darboties.

Korekcija

Bija racionālāk samazināt pašas datu bāzes lielumu un samazināt tās apstrādes laiku, nevis mainīt pašu loģiku.

Situācijai vajadzētu būtiski mainīties, ja izdzēsīsiet 300 miljonus ierakstu, tāpēc es nolēmu to darīt... Eh, es domāju, ka tas noteikti darbosies.

1. darbība

Sagatavojis uzticamu dublējumu, beidzot sāku sūtīt pieprasījumus.

''Pieprasījuma sūtīšana''

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

"…"

"…"

“Hmm... Nav atbildes. Varbūt process aizņem ilgu laiku?” — nodomāju, bet katram gadījumam paskatījos uz grafānu un ieraudzīju, ka diska noslodze ļoti strauji aug.
"Bīstami," es vēlreiz nodomāju un nekavējoties pārtraucu pieprasījumu.

2. darbība

Izanalizējot visu, es sapratu, ka datu apjoms ir pārāk liels, lai izdzēstu visu uzreiz.

Es nolēmu uzrakstīt skriptu, kas varētu dzēst apmēram 1 000 000 ierakstu, un palaidu to.

"Es īstenoju skriptu"

"Tagad tas noteikti darbosies," es domāju.

3. darbība

Otrā metode darbojās, taču izrādījās ļoti darbietilpīga.
Lai visu izdarītu uzmanīgi, bez liekiem nerviem, būtu vajadzīgas kādas divas nedēļas. Bet tomēr šis scenārijs neatbilda apkalpošanas prasībām, tāpēc nācās no tā atteikties.

Lūk, ko es nolēmu darīt:

Kopējiet tabulu un pārdēvējiet to

Из предыдущего шага я понял, что удаление такого большого объема данных создает такую же большую нагрузку. Поэтому я решил создать новую таблицу с нуля с помощью insert и в неё переместить данные, которые собирался удалить.

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

Ja jauno tabulu veidojat tāda paša izmēra kā iepriekš, arī datu apstrādes ātrumam vajadzētu kļūt par 1/7 ātrākam.

Pēc tabulas izveidošanas un pārdēvēšanas es sāku to izmantot kā galveno tabulu. Tagad, ja es nomestu tabulu ar 300 miljoniem ierakstu, visam vajadzētu būt kārtībā.
Es uzzināju, ka saīsināšana vai nomešana rada mazāk papildu izdevumu nekā dzēšana, un nolēmu izmantot šo metodi.

Piepildījums

''Pieprasījuma sūtīšana''

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

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

4. darbība

Es domāju, ka iepriekšējā ideja darbosies, bet pēc ievietošanas pieprasījuma nosūtīšanas parādījās vairākas kļūdas. MySQL nav piedodošs.

Es jau biju tik nogurusi, ka sāku domāt, ka vairs negribu to darīt.

Sēdēju un domāju un sapratu, ka varbūt vienu reizi bija pārāk daudz ieliktņu vaicājumu...
Попробовал отправить запрос insert на объем данных, которые база должна обрабатывать за 1 день. Получилось!

Nu, pēc tam mēs turpinām sūtīt pieprasījumus par tādu pašu datu apjomu. Tā kā mums ir jānoņem mēneša dati, mēs atkārtojam šo darbību aptuveni 35 reizes.

Tabulas pārdēvēšana

Šeit veiksme bija manā pusē: viss noritēja gludi.

Brīdinājums pazudis

Pakešu apstrādes ātrums ir palielinājies.

Iepriekš šis process ilga apmēram stundu, tagad tas aizņem apmēram 2 minūtes.

После того, как я убедился, что все проблемы решены, я дропнул 300 миллионов записей. Я удалил таблицу и почувствовал себя заново родившимся.

Kopsavilkums

Es sapratu, ka pakešu apstrādē trūkst rotācijas apstrādes, un tā bija galvenā problēma. Šāda veida arhitektūras kļūda noved pie laika izšķiešanas.

Vai, dzēšot ierakstus no datu bāzes, domājat par slodzi datu replikācijas laikā? Nepārslogosim MySQL.

Tie, kas labi pārzina datubāzes, noteikti nesaskarsies ar šādu problēmu. Pārējiem, es ceru, ka šis raksts bija noderīgs.

Paldies, ka izlasījāt!

Mēs būsim ļoti priecīgi, ja pastāstīsit, vai jums patika šis raksts, vai tulkojums ir skaidrs, vai tas jums bija noderīgs?

Avots: www.habr.com

Pievieno komentāru