La rakonto pri fizike forigi 300 milionojn da registroj en MySQL

Enkonduko

Saluton. Mi estas ningenMe, retejo-programisto.

Kiel la titolo diras, mia rakonto estas la rakonto pri fizike forigo de 300 milionoj da rekordoj en MySQL.

Mi interesiĝis pri tio, do mi decidis fari memorigilon (instrukciojn).

Hejmo - Atentigo

La batservilo, kiun mi uzas kaj konservas, havas regulan procezon, kiu kolektas la datumojn de la lasta monato de MySQL unufoje tage.

Kutime ĉi tiu procezo finiĝas ene de ĉirkaŭ 1 horo, sed ĉi-foje ĝi ne finiĝis dum 7 aŭ 8 horoj, kaj la atentigo ne ĉesis aperi...

Serĉante kialon

Mi provis rekomenci la procezon kaj rigardi la protokolojn, sed mi vidis nenion malbonan.
La demando estis ĝuste indeksita. Sed kiam mi pensis pri kio misfunkcias, mi rimarkis, ke la datumbazo estas sufiĉe granda.

hoge_table | 350'000'000 |

350 milionoj da rekordoj. Indeksado ŝajnis funkcii ĝuste, nur tre malrapide.

La postulata datumkolekto monate estis proksimume 12 rekordoj. Ŝajnas, ke la elekta komando daŭris longan tempon kaj la transakcio ne estis efektivigita dum longa tempo.

DB

Ĝi estas esence tabelo, kiu kreskas je ĉirkaŭ 400 enskriboj ĉiutage. La datumbazo devis kolekti datumojn nur por la lasta monato, tial oni atendis, ke ĝi eltenus ĝuste ĉi tiun kvanton da datumoj, sed, bedaŭrinde, la turna operacio ne estis inkluzivita.

Ĉi tiu datumbazo ne estis evoluigita de mi. Mi transprenis ĝin de alia programisto, do ĝi ankoraŭ sentis teknikan ŝuldon.

Venis punkto, kiam la volumo de datumoj enmetitaj ĉiutage fariĝis granda kaj finfine atingis sian limon. Oni supozas, ke kiam oni laboras kun tiom granda kvanto da datumoj, necesus disigi ilin, sed ĉi tio, bedaŭrinde, ne estis farita.

Kaj tiam mi ekagis.

Korekto

Estis pli racie redukti la grandecon de la datumbazo mem kaj redukti la tempon por prilaborado de ĝi ol ŝanĝi la logikon mem.

La situacio devus ŝanĝiĝi signife, se vi forigos 300 milionojn da rekordoj, do mi decidis fari tion... Eh, mi pensis, ke ĉi tio certe funkcios.

Ago 1

Preparinte fidindan sekurkopion, mi finfine komencis sendi petojn.

「Sendante peton」

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

"…"

"…"

“Hmm... Neniu respondo. Eble la procezo daŭras longan tempon?” — Mi pensis, sed ĉiaokaze, mi rigardis grafanan kaj vidis, ke la diskŝarĝo kreskas tre rapide.
"Danĝere," mi pensis denove kaj tuj ĉesigis la peton.

Ago 2

Analizinte ĉion, mi rimarkis, ke la volumo de datumoj estas tro granda por forigi ĉion samtempe.

Mi decidis verki skripton, kiu povus forigi ĉirkaŭ 1 rekordojn kaj lanĉis ĝin.

「Mi efektivigas la skripton」

"Nun ĉi tio certe funkcios," mi pensis.

Ago 3

La dua metodo funkciis, sed montriĝis tre labor-intensa.
Fari ĉion zorge, sen nenecesaj nervoj, bezonus ĉirkaŭ du semajnoj. Sed tamen, ĉi tiu scenaro ne plenumis la servopostulojn, do ni devis malproksimiĝi de ĝi.

Do jen kion mi decidis fari:

Kopiu la tabelon kaj renomu ĝin

De la antaŭa paŝo, mi rimarkis, ke forigo de tiom granda kvanto da datumoj kreas same grandan ŝarĝon. Do mi decidis krei novan tabelon de nulo uzante enmeti kaj movi la datumojn, kiujn mi forigos en ĝin.

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

Se vi faras la novan tabelon la saman grandecon kiel supre, la rapido pri datumtraktado ankaŭ devus fariĝi 1/7 pli rapida.

Post krei la tabelon kaj renomi ĝin, mi komencis uzi ĝin kiel la majstran tablon. Nun se mi faligas la tabelon kun 300 milionoj da rekordoj ĉio devus esti en ordo.
Mi eksciis, ke detranĉi aŭ fali kreas malpli superkoston ol forigi kaj decidis uzi ĉi tiun metodon.

Agado

「Sendante peton」

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

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

Ago 4

Mi pensis, ke la antaŭa ideo funkcios, sed post sendi la enigpeton, aperis pluraj eraroj. MySQL ne pardonas.

Mi jam estis tiom laca, ke mi ekpensis, ke mi ne plu volas fari tion.

Mi sidis kaj pensis kaj rimarkis, ke eble estas tro da enig-demandoj por unu fojo...
Mi provis sendi enigpeton pri la kvanto da datumoj, kiujn la datumbazo devus prilabori en 1 tago. Okazis!

Nu, post tio ni daŭre sendas petojn por la sama kvanto da datumoj. Ĉar ni devas forigi monatan valoron da datumoj, ni ripetas ĉi tiun operacion proksimume 35 fojojn.

Alinomi tabelon

Ĉi tie la sorto estis miaflanke: ĉio iris glate.

Atentigo malaperis

Bata prilabora rapideco pliiĝis.

Antaŭe ĉi tiu procezo daŭris ĉirkaŭ unu horon, nun ĝi daŭras ĉirkaŭ 2 minutojn.

Post kiam mi estis certa, ke ĉiuj problemoj estas solvitaj, mi faligis 300 milionojn da rekordoj. Mi forigis la tablon kaj sentis min renaskita.

Resumo

Mi rimarkis, ke rotacia prilaborado mankas en bata prilaborado, kaj tio estis la ĉefa problemo. Tia arkitektura eraro kondukas al tempoperdo.

Ĉu vi pensas pri la ŝarĝo dum reproduktado de datumoj kiam vi forigas rekordojn el la datumbazo? Ni ne troŝarĝu MySQL.

Tiuj, kiuj bone konas datumbazojn, certe ne renkontos tian problemon. Por la ceteraj, mi esperas, ke ĉi tiu artikolo estis utila.

Dankon pro legado!

Ni tre ĝojos, se vi diros al ni, ĉu vi ŝatis ĉi tiun artikolon, ĉu la traduko estas klara, ĉu ĝi estis utila al vi?

fonto: www.habr.com

Aldoni komenton