300 millió rekord fizikai törlésének története a MySQL-ben

Bevezetés

Helló. NingenMe vagyok, webfejlesztő.

Ahogy a cím is mondja, az én történetem 300 millió rekord fizikai törlésének története a MySQL-ben.

Ez érdekelt, ezért úgy döntöttem, készítek egy emlékeztetőt (utasításokat).

Kezdőlap – Figyelmeztetés

Az általam használt és karbantartott kötegelt szerver rendszeres folyamattal rendelkezik, amely naponta egyszer összegyűjti a MySQL-ből az elmúlt hónap adatait.

Általában ez a folyamat körülbelül 1 órán belül befejeződik, de ezúttal 7 vagy 8 órán keresztül nem fejeződött be, és a riasztás sem szűnt meg...

Ok keresése

Megpróbáltam újraindítani a folyamatot, és megnézni a naplókat, de nem láttam semmi hibát.
A lekérdezés megfelelően lett indexelve. De amikor átgondoltam, hogy mi lehet a baj, rájöttem, hogy az adatbázis mérete meglehetősen nagy.

hoge_table | 350'000'000 |

350 millió rekord. Úgy tűnt, hogy az indexelés megfelelően működik, csak nagyon lassú.

A szükséges adatgyűjtés havonta körülbelül 12 000 000 rekord volt. Úgy tűnik, hogy a select parancs hosszú ideig tartott, és a tranzakciót sokáig nem hajtották végre.

DB

Ez lényegében egy táblázat, amely naponta körülbelül 400 000 bejegyzéssel bővül. Az adatbázisnak csak az utolsó hónap adatait kellett volna gyűjtenie, ezért várható volt, hogy pontosan ekkora adatmennyiséget fog kibírni, de sajnos a rotációs művelet nem került bele.

Ezt az adatbázist nem én fejlesztettem. Egy másik fejlesztőtől vettem át, így még mindig műszaki adósságnak éreztem.

Eljött az a pont, amikor a naponta bevitt adatok mennyisége megnőtt, és végül elérte a határt. Feltételezhető, hogy ekkora adatmennyiséggel történő munkavégzés során el kell különíteni őket, de ez sajnos nem történt meg.

És akkor akcióba léptem.

Javítás

Racionálisabb volt magának az adatbázisnak a méretét csökkenteni, és csökkenteni a feldolgozási időt, mint magát a logikát megváltoztatni.

A helyzet jelentősen megváltozhat, ha törölsz 300 millió rekordot, ezért úgy döntöttem, hogy megteszem... Eh, azt hittem, ez biztosan működni fog.

1. cselekvés

Miután elkészítettem egy megbízható biztonsági másolatot, végre elkezdtem küldeni a kéréseket.

「Kérés küldése」

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

"…"

"…"

„Hmm... Nincs válasz. Lehet, hogy a folyamat sokáig tart?” – gondoltam, de minden esetre megnéztem a grafanát, és láttam, hogy a lemezterhelés nagyon gyorsan nő.
„Veszélyes” – gondoltam újra, és azonnal leállítottam a kérést.

2. cselekvés

Miután mindent elemeztem, rájöttem, hogy az adatmennyiség túl nagy ahhoz, hogy mindent egyszerre töröljek.

Úgy döntöttem, írok egy szkriptet, amely körülbelül 1 000 000 rekordot törölhet, és elindítottam.

"Megvalósítom a forgatókönyvet"

„Most ez biztosan működni fog” – gondoltam.

3. cselekvés

A második módszer bevált, de nagyon munkaigényesnek bizonyult.
Körülbelül két hétbe telhet, ha mindent gondosan, felesleges idegek nélkül csinálunk. Ez a forgatókönyv azonban mégsem felelt meg a szolgáltatási követelményeknek, ezért el kellett távolodnunk tőle.

Tehát a következőképpen döntöttem:

Másolja ki a táblázatot, és nevezze át

Az előző lépésből rájöttem, hogy ekkora adatmennyiség törlése ugyanolyan nagy terhelést eredményez. Ezért úgy döntöttem, hogy a semmiből létrehozok egy új táblázatot a beszúrással, és áthelyezem abba a törölni kívánt adatokat.

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

Ha az új táblázatot a fentivel megegyező méretűre készíti, az adatfeldolgozási sebesség is 1/7-el gyorsabb lesz.

A tábla létrehozása és átnevezése után mestertáblaként kezdtem el használni. Ha ledobom a táblázatot 300 millió rekorddal, akkor minden rendben lesz.
Rájöttem, hogy a csonkítás vagy eldobás kevesebb többletköltséget jelent, mint a törlés, és úgy döntöttem, hogy ezt a módszert használom.

végrehajtás

「Kérés küldése」

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

"…"
"…"
– Em…?

4. cselekvés

Azt hittem, az előző ötlet működni fog, de a beszúrási kérelem elküldése után több hiba is megjelent. A MySQL nem megbocsátó.

Már annyira fáradt voltam, hogy elkezdtem azt hinni, hogy nem akarom ezt tovább csinálni.

Ültem, gondolkodtam, és rájöttem, hogy talán túl sok beszúrási lekérdezés volt egyszer...
Megpróbáltam beszúrási kérelmet küldeni, hogy mennyi adatmennyiséget kell feldolgoznia az adatbázisnak 1 napon belül. Megtörtént!

Nos, ezután továbbra is ugyanannyi adatmennyiségre küldünk kéréseket. Mivel egy hónapnyi adatot kell eltávolítanunk, ezt a műveletet körülbelül 35-ször ismételjük meg.

Táblázat átnevezése

Itt a szerencse mellettem állt: minden simán ment.

A riasztás eltűnt

A kötegelt feldolgozás sebessége nőtt.

Korábban ez a folyamat körülbelül egy órát vett igénybe, most körülbelül 2 percet vesz igénybe.

Miután biztos voltam benne, hogy minden probléma megoldódott, 300 millió rekordot dobtam le. Töröltem a táblázatot, és úgy éreztem, újjászülettem.

Összegzés

Rájöttem, hogy a rotációs feldolgozás hiányzik a kötegelt feldolgozásnál, és ez volt a fő probléma. Ez a fajta építészeti hiba időveszteséghez vezet.

Gondol az adatreplikáció közbeni terhelésre, amikor rekordokat töröl az adatbázisból? Ne terheljük túl a MySQL-t.

Aki jól ismeri az adatbázisokat, biztosan nem találkozik ilyen problémával. A többiek számára remélem, hogy ez a cikk hasznos volt.

Köszönöm, hogy elolvasta!

Nagyon örülünk, ha elmondja, hogy tetszett-e ez a cikk, egyértelmű-e a fordítás, hasznos volt-e az Ön számára?

Forrás: will.com

Hozzászólás