MySQL-де 300 миллион жазбаны физикалық түрде жою тарихы

Кіріспе

Сәлеметсіз бе. Мен ningenMe, веб-әзірлеушімін.

Атауында айтылғандай, менің оқиғам - MySQL-тегі 300 миллион жазбаны физикалық түрде жою тарихы.

Мен бұған қызығушылық таныттым, сондықтан мен еске салуды (нұсқауларды) жасауды шештім.

Үй - ескерту

Мен пайдаланатын және қызмет көрсететін пакеттік серверде MySQL-тен күніне бір рет өткен айдың деректерін жинайтын тұрақты процесс бар.

Әдетте бұл процесс шамамен 1 сағат ішінде аяқталады, бірақ бұл жолы ол 7 немесе 8 сағатта аяқталмады және ескерту пайда болуын тоқтатпады...

Себебін табу

Мен процесті қайта іске қосып, журналдарды қарауға тырыстым, бірақ қате ештеңе көрмедім.
Сұрау дұрыс индекстелді. Бірақ мен не болып жатқанын ойлаған кезде, дерекқордың өлшемі өте үлкен екенін түсіндім.

hoge_table | 350'000'000 |

350 миллион жазба. Индекстеу дұрыс жұмыс істеп тұрған сияқты, өте баяу.

Айына қажетті деректерді жинау шамамен 12 000 000 жазбаны құрады. Таңдау пәрмені ұзақ уақытқа созылған сияқты және транзакция ұзақ уақыт бойы орындалмады.

DB

Бұл күн сайын шамамен 400 000 жазбаға өсетін кесте. Деректер базасы деректерді тек соңғы айда жинауы керек еді, сондықтан ол деректердің дәл осы мөлшеріне төтеп береді деп күтілген, бірақ, өкінішке орай, айналдыру операциясы қамтылмаған.

Бұл дерекқорды мен жасаған жоқ. Мен оны басқа әзірлеушіден алдым, сондықтан ол әлі де техникалық қарыз сияқты болды.

Күнделікті енгізілетін деректер көлемі үлкен болып, ақыры шегіне жеткен сәт келді. Мұндай үлкен көлемдегі деректермен жұмыс істегенде, оларды бөлу қажет болады деп болжанады, бірақ бұл, өкінішке орай, жасалмады.

Содан кейін мен әрекетке келдім.

Түзету

Логиканы өзгертуден гөрі дерекқордың өлшемін азайту және оны өңдеу уақытын қысқарту ұтымдырақ болды.

Егер сіз 300 миллион жазбаны өшірсеңіз, жағдай айтарлықтай өзгеруі керек, сондықтан мен осылай жасауды шештім... Эх, бұл сөзсіз жұмыс істейді деп ойладым.

Әрекет 1

Сенімді сақтық көшірме дайындап, мен ақырында сұрауларды жібере бастадым.

「Сұраныс жіберу」

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

"..."

"..."

«Хм... Жауап жоқ. Мүмкін процесс ұзаққа созылатын шығар?» — Мен ойладым, бірақ графанаға қарап, диск жүктемесінің өте тез өсіп жатқанын көрдім.
«Қауіпті», - деп тағы ойладым және сұрауды бірден тоқтаттым.

Әрекет 2

Барлығын талдағаннан кейін мен деректер көлемінің барлығын бірден жою үшін тым үлкен екенін түсіндім.

Мен шамамен 1 000 000 жазбаны жоюға болатын сценарий жазуды шештім және оны іске қостым.

「Мен сценарийді орындаймын」

«Енді бұл міндетті түрде жұмыс істейді», - деп ойладым мен.

Әрекет 3

Екінші әдіс жұмыс істеді, бірақ өте көп еңбекті қажет ететін болып шықты.
Қажет емес нервтердісіз бәрін мұқият жасау үшін екі аптаға жуық уақыт қажет. Бірақ бәрібір бұл сценарий қызмет көрсету талаптарына сәйкес келмеді, сондықтан біз одан бас тартуға тура келді.

Міне, мен не істеуге шешім қабылдадым:

Кестені көшіріп, оның атын өзгертіңіз

Алдыңғы қадамнан мен мұндай үлкен көлемдегі деректерді жою бірдей үлкен жүктемені тудыратынын түсіндім. Сондықтан мен кірістіру арқылы нөлден бастап жаңа кесте құруды және оған жоюды жоспарлаған деректерді жылжытуды шештім.

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

Жаңа кестені жоғарыдағы өлшеммен бірдей етіп жасасаңыз, деректерді өңдеу жылдамдығы да 1/7 жылдамырақ болуы керек.

Кестені жасап, атын өзгерткеннен кейін мен оны негізгі кесте ретінде пайдалана бастадым. Енді мен 300 миллион жазбалары бар кестені тастасам, бәрі жақсы болуы керек.
Мен қысқарту немесе тастау жоюға қарағанда азырақ үстеме жасайтынын білдім және осы әдісті қолдануды шештім.

Орындау

「Сұраныс жіберу」

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

"..."
"..."
«Эм...?»

Әрекет 4

Мен алдыңғы идея жұмыс істейді деп ойладым, бірақ кірістіру сұрауын жібергеннен кейін бірнеше қате пайда болды. MySQL кешірмейді.

Менің шаршағаным сонша, енді мұны істегім келмейді деп ойлай бастадым.

Мен отырдым және ойладым және бір рет кірістіру сұраулары тым көп болуы мүмкін екенін түсіндім ...
Дерекқор 1 күнде өңдеуі керек деректер көлеміне кірістіру сұрауын жіберуге тырыстым. Болды!

Осыдан кейін біз деректердің бірдей көлеміне сұрау жіберуді жалғастырамыз. Бір айлық деректерді жою қажет болғандықтан, біз бұл әрекетті шамамен 35 рет қайталаймыз.

Кестені қайта атау

Бұл жерде сәттілік мен жақта болды: бәрі ойдағыдай өтті.

Ескерту жоғалып кетті

Пакеттік өңдеу жылдамдығы артты.

Бұрын бұл процесс шамамен бір сағатқа созылатын болса, қазір шамамен 2 минутты алады.

Барлық мәселелердің шешілгеніне сенімді болғаннан кейін мен 300 миллион жазбаны тастадым. Мен кестені жойып, қайта туылғанымды сезіндім.

Түйіндеме

Мен топтамалық өңдеуде айналымды өңдеудің жоқ екенін түсіндім және бұл басты мәселе болды. Мұндай архитектуралық қате уақытты босқа кетіруге әкеледі.

Дерекқордан жазбаларды жою кезінде деректерді репликациялау кезіндегі жүктеме туралы ойлайсыз ба? MySQL-ті шамадан тыс жүктемейік.

Деректер базасын жақсы білетіндер мұндай мәселеге тап болмайды. Қалғандары үшін бұл мақала пайдалы болды деп үміттенемін.

Оқығаныңызға рахмет!

Бұл мақала сізге ұнады ма, аудармасы түсінікті болды ма, сізге пайдалы болды ма деп айтсаңыз, өте қуаныштымыз?

Ақпарат көзі: www.habr.com

пікір қалдыру