Historia om den fysiska borttagningen av 300 miljoner poster i MySQL

Introduktion

Hej. Jag Àr ningenMe, webbutvecklare.

Som titeln antyder, Àr min berÀttelse en berÀttelse om fysiska borttagningar av 300 miljoner poster i MySQL.

Jag blev intresserad av detta, sÄ jag bestÀmde mig för att göra en pÄminnelse (instruktion).

Början - Alert

I den batch servern, som jag anvÀnder och underhÄller, finns en regelbunden process som en gÄng om dagen samlar in data frÄn den senaste mÄnaden frÄn MySQL.

Vanligtvis avslutas denna process pÄ ungefÀr 1 timme, men den hÀr gÄngen avslutades den inte pÄ 7 eller 8 timmar, och alerten slutade inte dyka upp...

Söka efter orsaken

Jag försökte starta om processen, kolla loggar, men sÄg inget alarmerande.
FrÄgan indexerades korrekt. Men nÀr jag tÀnkte pÄ vad som gick fel insÄg jag att databasens storlek var ganska stor.

hoge_table | 350'000'000 |

350 miljoner poster. Det verkar som om indexeringen fungerade korrekt, bara mycket lÄngsamt.

Den nödvÀndiga datainsamlingen för mÄnaden var cirka 12 000 000 poster. Det verkar som om select-kommandot tog mycket tid, och transaktionen fullföljdes lÀnge.

DB

Det hÀr Àr i grunden en tabell som vÀxer med ungefÀr 400 000 poster varje dag. Databasen skulle samla in data endast frÄn den senaste mÄnaden, vilket innebÀr att det var förvÀntat att den skulle klara av just denna mÀngd data, men tyvÀrr var operationen för rotation inte aktiverad.

Denna databas utvecklades inte av mig. Jag tog emot den frÄn en annan utvecklare, sÄ det kÀnns som en teknisk skuld.

Det kom en tidpunkt nÀr mÀngden dagligt tillagda data blev stor och till slut nÄdde grÀnsen. Det Àr rimligt att tÀnka att man bör dela upp sÄdana stora datamÀngder, men tyvÀrr gjordes detta inte.

Och hÀr gick jag in i bilden.

Fix

Det skulle vara mer rationellt att minska sjÀlva databasen och förkorta tiden för dess bearbetning, Àn att förÀndra sjÀlva logiken.

Situationen borde förĂ€ndras avsevĂ€rt om jag raderar 300 miljoner poster, sĂ„ jag bestĂ€mde mig för att göra just det... Åh, jag trodde att det verkligen skulle fungera.

ÅtgĂ€rd 1

Efter att ha förberett en sÀkerhetskopia, började jag Àntligen skicka förfrÄgningar.

„Skickar förfrĂ„gan“

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

「
」

「
」

“Hm... Ingen respons. Kanske processen tar lĂ„ng tid?” — tĂ€nkte jag, men av nĂ„gon anledning kollade jag pĂ„ grafana och sĂ„g att diskbelastningen vĂ€xte vĂ€ldigt snabbt.
"Det kĂ€nns farligt" — tĂ€nkte jag igen och stoppade omedelbart förfrĂ„gan.

Handling 2

Efter att ha analyserat allt insÄg jag att datavolymen var för stor för att radera allt pÄ en gÄng.

Jag beslöt mig för att skriva ett skript som kan ta bort ungefÀr 1 000 000 poster och körde det.

「jag implementerar skriptet」

"Nu bör det verkligen fungera", — tĂ€nkte jag

Handling 3

Den andra metoden fungerade, men visade sig vara mycket arbetsintensiv.
För att göra allt pÄ ett ordnat sÀtt, utan onödig stress, skulle det ta ungefÀr tvÄ veckor. Men detta scenario uppfyllde inte tjÀnstekraven, sÄ jag var tvungen att ge upp det.

SÄ hÀr Àr vad jag beslöt mig för att göra:

Kopiera tabellen och byta namn

FrÄn föregÄende steg insÄg jag att borttagning av en sÄ stor datavolym skapar en lika stor belastning. DÀrför beslutade jag att skapa en ny tabell frÄn grunden med hjÀlp av insert och flytta de data jag planerade att ta bort dit.

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

Om jag skapar en ny tabell med samma storlek som angivet ovan, bör hastigheten för databehandling ocksÄ bli 1/7 snabbare.

Efter att ha skapat tabellen och bytt namn pÄ den började jag anvÀnda den som mastertabell. Nu, om jag tar bort tabellen med 300 miljoner poster, borde allt vara i ordning.
Jag lÀrde mig att truncate eller drop skapar mindre belastning Àn delete och bestÀmde mig för att anvÀnda det alternativet.

Genomförande

„Skickar förfrĂ„gan“

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

「
」
「
」
「ehâ€ŠïŒŸă€

Handling 4

Jag trodde att den föregÄende idén skulle fungera, men efter att jag skickade insert-förfrÄgan uppstod flera fel. MySQL visar ingen nÄd.

Jag var sÄ trött att jag började tÀnka att jag inte ville göra detta lÀngre.

Jag satte mig ner och insĂ„g att, kanske, för en enda gĂ„ng var mĂ€ngden insert-förfrĂ„gningar för stor

Jag försökte skicka en insert-förfrÄgan pÄ den datamÀngd som databasen borde hantera pÄ en dag. Det lyckades!

Och efter det fortsÀtter vi att skicka förfrÄgningar med samma datamÀngd. Eftersom jag behöver ta bort en mÄnads datamÀngd, upprepar vi denna operation ungefÀr 35 gÄnger.

Byta namn pÄ tabellen

HÀr var turen pÄ min sida: allt gick smidigt.

Alert försvann

Hastigheten för batchbearbetningen ökade.

Tidigare tog den hÀr processen ungefÀr en timme, nu tar det cirka 2 minuter.

NÀr jag hade sÀkerstÀllt att alla problem var lösta, tog jag bort 300 miljoner poster. Jag raderade tabellen och kÀnde mig som nyfödd.

Sammanfattning

Jag insÄg att rotate processing hade missats under batchbearbetning, och det var den huvudsakliga problemet. Ett sÄdant arkitektoniskt misstag leder till bortkastad tid.

TÀnker du pÄ belastningen vid dat replication nÀr du tar bort poster frÄn databasen? LÄt oss inte överbelasta MySQL.

De som Àr kunniga inom databaser kommer definitivt inte att möta ett sÄdant problem. Jag hoppas att denna artikel har varit anvÀndbar för andra.

Tack för att du lÀste!

Vi skulle vara mycket glada om du berÀttar för oss om du gillade denna artikel, om översÀttningen var tydlig, och om den var till hjÀlp för dig?

KĂ€lla: habr.com

Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster