MySQL-ում 300 միլիոն գրառում ֆիզիկապես ջնջելու պատմությունը

Ներածություն

Բարեւ Ձեզ. Ես ningenMe-ն եմ, վեբ ծրագրավորող:

Ինչպես վերնագրում է ասվում, իմ պատմությունը MySQL-ում 300 միլիոն գրառում ֆիզիկապես ջնջելու պատմությունն է:

Ինձ սա հետաքրքրեց, ուստի որոշեցի մի հիշեցում (ցուցումներ) անել:

Գլխավոր - Զգուշացում

Սերվերի սերվերը, որը ես օգտագործում և սպասարկում եմ, ունի կանոնավոր գործընթաց, որը հավաքում է վերջին ամսվա տվյալները MySQL-ից օրը մեկ անգամ:

Սովորաբար այս գործընթացը ավարտվում է մոտ 1 ժամվա ընթացքում, բայց այս անգամ այն ​​չի ավարտվել 7 կամ 8 ժամ, և ահազանգը չի դադարում հայտնվել...

Պատճառը գտնելը

Ես փորձեցի վերսկսել գործընթացը և դիտել տեղեկամատյանները, բայց ոչ մի վատ բան չտեսա:
Հարցումը ճիշտ է ինդեքսավորվել: Բայց երբ մտածեցի, թե ինչն է սխալ, հասկացա, որ տվյալների բազայի չափը բավականին մեծ է։

hoge_table | 350'000'000 |

350 միլիոն ձայնագրություն. Թվում էր, թե ինդեքսավորումը ճիշտ էր աշխատում, պարզապես շատ դանդաղ:

Պահանջվող տվյալների հավաքագրումը ամսական կազմում էր մոտավորապես 12 գրառում: Կարծես ընտրելու հրամանը երկար ժամանակ տևեց, և գործարքը երկար ժամանակ չէր իրականացվել:

DB

Դա, ըստ էության, աղյուսակ է, որն ամեն օր աճում է մոտ 400 գրառումով: Տվյալների բազան պետք է հավաքեր միայն վերջին ամսվա տվյալները, հետևաբար սպասվում էր, որ այն կդիմանա հենց այս քանակությամբ տվյալների, բայց, ցավոք, ռոտացիոն գործողությունը ներառված չէր։

Այս տվյալների բազան չի մշակվել իմ կողմից: Ես այն վերցրեցի մեկ այլ ծրագրավորողից, այնպես որ այն դեռևս տեխնիկական պարտք էր:

Եկավ մի պահ, երբ օրական ներմուծվող տվյալների ծավալը մեծացավ և վերջապես հասավ իր սահմանին։ Ենթադրվում է, որ այդքան մեծ քանակությամբ տվյալների հետ աշխատելիս անհրաժեշտ կլիներ դրանք առանձնացնել, սակայն դա, ցավոք, չարվեց։

Եվ հետո ես գործի անցա:

Ուղղում

Ավելի ռացիոնալ էր բուն տվյալների բազայի չափը նվազեցնելը և դրա մշակման ժամանակը կրճատելը, քան բուն տրամաբանությունը փոխելը:

Իրավիճակը պետք է էապես փոխվի, եթե ջնջես 300 միլիոն ձայնագրություն, ուստի ես որոշեցի դա անել... Էհ, կարծում էի, որ սա հաստատ կաշխատի:

Գործողություն 1

Պատրաստելով հուսալի կրկնօրինակում, ես վերջապես սկսեցի հարցումներ ուղարկել:

「Ուղարկել հարցում」

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

«...»

«...»

«Հմմ... Ոչ մի պատասխան: Միգուցե գործընթացը երկար է տևում»: — Մտածեցի, բայց ամեն դեպքում, նայեցի գրաֆանային և տեսա, որ սկավառակի բեռնվածությունը շատ արագ աճում է։
«Վտանգավոր», նորից մտածեցի ես և անմիջապես դադարեցրի խնդրանքը:

Գործողություն 2

Ամեն ինչ վերլուծելուց հետո հասկացա, որ տվյալների ծավալը չափազանց մեծ է ամեն ինչ միանգամից ջնջելու համար։

Ես որոշեցի գրել մի սցենար, որը կարող է ջնջել մոտ 1 ձայնագրություն, և գործարկեցի այն:

«Ես իրականացնում եմ սցենարը»

«Հիմա սա անպայման կաշխատի», - մտածեցի ես:

Գործողություն 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-ը։

Տվյալների բազաներին լավ տիրապետողները հաստատ նման խնդրի չեն հանդիպի։ Մնացածների համար, հուսով եմ, որ այս հոդվածը օգտակար էր:

Շնորհակալություն կարդալու համար:

Մենք շատ ուրախ կլինենք, եթե մեզ ասեք, թե արդյոք ձեզ դուր է եկել այս հոդվածը, արդյոք թարգմանությունը պարզ է, արդյոք այն օգտակար է ձեզ համար:

Source: www.habr.com

Добавить комментарий