Առաջընթացը դեռ չի կանգնում, ուստի MySQL-ի վերջին տարբերակներին թարմացնելու պատճառները գնալով ավելի գրավիչ են դառնում: Ոչ վաղ անցյալում, մեր նախագծերից մեկում, ժամանակն էր թարմացնել Percona Server 5.7-ի հարմարավետ կլաստերները 8-րդ տարբերակին: Այս ամենը տեղի է ունեցել Ubuntu Linux 16.04 հարթակում։ Ինչպես կատարել նման գործողություն նվազագույն ժամանակով և ինչ խնդիրների ենք հանդիպել թարմացման ընթացքում, կարդացեք այս հոդվածում:
Ուսուցում
Տվյալների բազայի սերվերի ցանկացած թարմացում, ամենայն հավանականությամբ, կապված է տվյալների բազայի վերակազմավորման հետ. համակարգի ռեսուրսների սահմանափակումների պահանջների փոփոխություն և տվյալների բազայի կազմաձևերի ուղղում, որոնք պետք է մաքրվեն հնացած հրահանգներից:
Թարմացումից առաջ մենք անպայման կանդրադառնանք պաշտոնական փաստաթղթերին.
Ստուգեք համատեղելիությունը կոմունալ ծառայությունների հետ:
Թարմացրեք ստրկական տվյալների բազաները՝ տեղադրելով փաթեթը percona-server-server.
Թարմացրեք վարպետը նույն փաթեթով:
Եկեք նայենք պլանի յուրաքանչյուր կետին և տեսնենք, թե ինչ կարող է սխալ լինել:
ԿԱՐԵՎՈՐ. Galera-ի վրա հիմնված MySQL կլաստերի թարմացման կարգն ունի իր նրբությունները, որոնք նկարագրված չեն հոդվածում: Այս դեպքում դուք չպետք է օգտագործեք այս հրահանգը:
Մաս 1. Կազմաձևերի ստուգում
MySQL-ը հեռացվել է 8-րդ տարբերակում query_cache. Իրականում նա էր ճանաչվել է հնացած վերադառնալ 5.7 տարբերակում, բայց հիմա ամբողջությամբ ջնջված է. Համապատասխանաբար, անհրաժեշտ է հեռացնել հարակից հրահանգները: Եվ քեշի հարցումները այժմ կարող եք օգտագործել արտաքին գործիքներ, օրինակ. ProxySQL.
Նաև կազմաձևում կային հնացած հրահանգներ innodb_file_format. Եթե MySQL 5.7-ում հնարավոր էր ընտրել InnoDB ֆորմատը, ապա 8-րդ տարբերակն արդեն աշխատում է. միայն Barracuda ձևաչափով.
Մեր արդյունքը հետևյալ հրահանգների հեռացումն է.
query_cache_type, query_cache_limit и query_cache_size;
innodb_file_format и innodb_file_format_max.
Ստուգելու համար մենք կօգտագործենք Percona սերվերի Docker պատկերը: Մենք կտեղադրենք սերվերի կազմաձևը գրացուցակում mysql_config_test, իսկ կողքին մենք կստեղծենք տեղեկատուներ տվյալների և տեղեկամատյանների համար։ Percona-սերվերի կազմաձևման փորձարկման օրինակ.
Ներքևի տող. կա՛մ Docker-ի տեղեկամատյաններում, կա՛մ տեղեկամատյաններով գրացուցակում, կախված ձեր կազմաձևերից, կհայտնվի մի ֆայլ, որտեղ կնկարագրվեն խնդրահարույց հրահանգները:
Ահա թե ինչ ունեինք.
2020-04-03T12:44:19.670831Z 0 [Warning] [MY-011068] [Server] The syntax 'expire-logs-days' is deprecated and will be removed in a future release. Please use binlog_expire_logs_seconds instead.
2020-04-03T12:44:19.671678Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.
2020-04-03T12:44:19.671682Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' is a collation of the deprecated character set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation instead.
Այսպիսով, մեզ դեռ պետք էր պարզել կոդավորումները և փոխարինել հնացած հրահանգը expire-logs-days.
Մաս 2. Աշխատանքային կայանքների ստուգում
Թարմացման փաստաթղթերը պարունակում են 2 կոմունալ ծառայություններ տվյալների բազայի համատեղելիությունը ստուգելու համար: Դրանց օգտագործումն օգնում է ադմինիստրատորին ստուգել առկա տվյալների կառուցվածքի համատեղելիությունը:
Սկսենք դասական mysqlcheck կոմունալից: Պարզապես վազեք.
Եթե որևէ խնդիր չհայտնաբերվի, կոմունալ ծրագիրը դուրս կգա 0 կոդով.
Բացի այդ, օգտակար է հասանելի MySQL-ի ժամանակակից տարբերակներում mysql-shell (Պերկոնայի դեպքում սա փաթեթն է percona-mysql-shell) Այն փոխարինում է դասական mysql հաճախորդին և համատեղում է հաճախորդի գործառույթները, SQL կոդի խմբագրիչը և MySQL կառավարման գործիքները: Սերվերը թարմացնելուց առաջ ստուգելու համար դրա միջոցով կարող եք գործարկել հետևյալ հրամանները.
Ընդհանրապես, ոչ մի կրիտիկական բան. միայն նախազգուշացումներ կոդավորման մասին (տես ներքեւում). Կատարման ընդհանուր արդյունքը.
Մենք որոշեցինք, որ թարմացումը պետք է անցնի առանց խնդիրների:
Նշում վերը նշված նախազգուշացումների մասին, որոնք ցույց են տալիս կոդավորման հետ կապված խնդիրներ: Փաստն այն է, որ UTF-8-ը MySQL-ում մինչև վերջերս UTF-8-ը «ճշմարիտ» չէր, քանի որ այն պահում էր ընդամենը 3 բայթ 4-ի փոխարեն: MySQL 8-ում սա վերջապես որոշել է ուղղել այն: կեղծանունը utf8 շուտով կբերի կոդավորման utf8mb4, և աղյուսակների հին սյունակները կդառնան utf8mb3. Հետագա կոդավորում utf8mb3 կհեռացվի, բայց ոչ այս թողարկումում: Հետևաբար, մենք որոշեցինք շտկել կոդավորումներն արդեն գործող DBMS տեղադրման վրա՝ այն թարմացնելուց հետո:
Մաս 3. Սերվերի թարմացումներ
Ի՞նչը կարող է սխալ լինել, երբ կա այդպիսի խելացի պլան: Լավ հասկանալով, որ նրբերանգները միշտ էլ տեղի են ունենում, մենք առաջին փորձն իրականացրեցինք MySQL մշակողների կլաստերի վրա:
Ինչպես արդեն նշվեց, պաշտոնական փաստաթղթեր ընդգրկում է MySQL սերվերները կրկնօրինակներով թարմացնելու հարցը։ Ներքևի տողն այն է, որ դուք նախ պետք է թարմացնեք բոլոր կրկնօրինակները (ստրուկները), քանի որ MySQL 8-ը կարող է կրկնօրինակվել 5.7-ի հիմնական տարբերակից: Որոշ դժվարություն կայանում է նրանում, որ մենք օգտագործում ենք ռեժիմը վարպետ <-> վարպետ, երբ հեռակառավարիչը ռեժիմում է միայն կարդալու համար. Այսինքն, փաստորեն, մարտական տրաֆիկը գնում է մեկ տվյալների կենտրոն, իսկ երկրորդը պահեստային է:
Տոպոլոգիան ունի հետևյալ տեսքը.
Թարմացումը պետք է սկսվի կրկնօրինակներից mysql կրկնօրինակ dc 2, mysql master dc 2 и mysql replica dc 1, և ավարտվում է mysql master dc 1 սերվերով: Ավելի հուսալի լինելու համար մենք դադարեցրինք վիրտուալ մեքենաները, լուսանկարեցինք դրանցից և թարմացումից անմիջապես առաջ դադարեցրինք կրկնօրինակումը հրամանի միջոցով: STOP SLAVE. Մնացած թարմացումն այսպիսի տեսք ունի.
Մենք վերագործարկում ենք յուրաքանչյուր կրկնօրինակ՝ կազմաձևերին ավելացնելով 3 տարբերակ. skip-networking, skip-slave-start, skip-log-bin. Փաստն այն է, որ տվյալների բազայի թարմացումն առաջացնում է երկուական տեղեկամատյաններ՝ համակարգի աղյուսակների թարմացումներով: Այս հրահանգները երաշխավորում են, որ տվյալների բազայում կիրառական տվյալների փոփոխություններ չեն լինի, և համակարգի աղյուսակների թարմացման մասին տեղեկատվությունը չի ներառվի երկուական տեղեկամատյաններում: Դա կխուսափի կրկնօրինակումը վերսկսելիս խնդիրներից:
Փաթեթի տեղադրում percona-server-server. Կարևոր է նշել, որ MySQL 8-րդ տարբերակում ոչ դուք պետք է գործարկեք հրամանը mysqlupgrade սերվերի թարմացումից հետո:
Հաջող մեկնարկից հետո մենք նորից վերագործարկում ենք սերվերը՝ առանց առաջին պարբերության մեջ ավելացված պարամետրերի:
Մենք համոզված ենք, որ կրկնօրինակումը հաջողությամբ աշխատում է. ստուգեք SHOW SLAVE STATUS և տեսեք, որ հավելվածների տվյալների բազայում հաշվիչներ ունեցող աղյուսակները թարմացվում են:
Ամեն ինչ բավականին պարզ է թվում. մշակողի թարմացումը հաջող էր: Լավ, դուք կարող եք ապահով կերպով պլանավորել գիշերային թարմացում արտադրության համար:
Տխրություն չկար. մենք թարմացրել ենք արդ
Այնուամենայնիվ, մշակողի հաջող փորձի փոխանցումը արտադրություն չէր առանց անակնկալների:
Բարեբախտաբար, թարմացման գործընթացն ինքնին սկսվում է կրկնօրինակներից, այնպես որ, երբ մենք հանդիպեցինք դժվարությունների, դադարեցրինք աշխատանքը և վերականգնեցինք կրկնօրինակը լուսանկարից: Խնդիրների քննությունը հետաձգվել է հաջորդ առավոտ։ Տեղեկամատյանները պարունակում էին հետևյալ գրառումները.
2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] table: t1 has 19 columns but InnoDB dictionary has 20 columns
2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] Error in fixing SE data for db1.t1
2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] Failed to Populate DD tables.
2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] Aborting
Google-ում տարբեր փոստային ցուցակների արխիվների ուսումնասիրությունը հանգեցրեց այն հասկացողությանը, որ այս խնդիրը առաջանում է MySQL սխալ. Թեև սա ավելի հավանական է, որ կոմունալ սխալ է mysqlcheck и mysqlsh.
Պարզվում է, որ MySQL-ը փոխել է տասնորդական դաշտերի տվյալների ներկայացման ձևը (int, tinyint և այլն), ուստի mysql-սերվերը դրանք պահելու այլ եղանակ է օգտագործում։ Եթե ձեր տվյալների բազան ի սկզբանե եղել է 5.5 կամ 5.1 տարբերակում, այնուհետև դուք թարմացրել եք 5.7-ի, այնուհետև ձեզ հարկավոր է անել OPTIMIZE որոշ սեղանների համար. Այնուհետև MySQL-ը կթարմացնի տվյալների ֆայլերը՝ դրանք փոխանցելով պահման ընթացիկ ձևաչափին:
Սա կարող եք նաև ստուգել կոմունալ ծրագրի միջոցով mysqlfrm:
Եթե field_type Եթե ունեք այն հավասար է 0-ի, ապա աղյուսակում օգտագործվում է հին տեսակը. անհրաժեշտ է իրականացնել OPTIMIZE. Այնուամենայնիվ, եթե արժեքը 246 է, դուք արդեն ունեք նոր տեսակ: Տեսակների մասին լրացուցիչ տեղեկություններ կարելի է գտնել այստեղ կոդը.
Ավելին ՝ մեջ այս սխալը Մենք դիտարկում ենք երկրորդ հնարավոր պատճառը, որը շրջանցեց մեզ՝ InnoDB աղյուսակների բացակայությունը համակարգի աղյուսակում։ INNODB_SYS_TABLESPACES, եթե դրանք՝ աղյուսակները, ստեղծվել են 5.1 տարբերակում։ Թարմացնելու ժամանակ խնդիրներից խուսափելու համար կարող եք օգտագործել կցված SQL սցենար.
Ինչու՞ մենք նման խնդիրներ չունեինք dev-ում: Տվյալների բազան պարբերաբար պատճենվում է այնտեղ արտադրությունից, այսպիսով. սեղանները վերստեղծվում են.
Ցավոք սրտի, իսկապես աշխատող մեծ տվյալների բազայում դուք չեք կարողանա պարզապես վերցնել և կատարել ունիվերսալ OPTIMIZE. percona-toolkit-ը կօգնի այստեղ. pt-online-schema-change կոմունալ ծրագիրը հիանալի է ՕՊՏԻՄԱՑԵԼ առցանց գործողության համար:
Թարմացված պլանն այսպիսի տեսք ուներ.
Օպտիմալացնել բոլոր աղյուսակները:
Թարմացրեք տվյալների բազաները:
Այն ստուգելու և միևնույն ժամանակ թարմացման ժամանակը պարզելու համար մենք անջատեցինք կրկնօրինակներից մեկը և գործարկեցինք հետևյալ հրամանը բոլոր աղյուսակների համար.
Աղյուսակները թարմացվում են առանց երկար կողպեքների, քանի որ կոմունալ ծրագիրը ստեղծում է նոր ժամանակավոր աղյուսակ, որի մեջ պատճենում է տվյալները հիմնական աղյուսակից: Այն պահին, երբ երկու աղյուսակները նույնական են, սկզբնական աղյուսակը կողպվում է և փոխարինվում նորով: Մեր դեպքում փորձնական գործարկումը ցույց տվեց, որ բոլոր աղյուսակները թարմացնելու համար կպահանջվի մոտ մեկ օր, սակայն տվյալների պատճենումը սկավառակների վրա չափազանց մեծ բեռ է առաջացրել:
Սրանից խուսափելու համար արտադրության մեջ մենք արգումենտն ավելացրինք հրամանին --sleep 10 արժեքով - այս պարամետրը կարգավորում է սպասման երկարությունը՝ տվյալների փաթեթը նոր աղյուսակ փոխանցելուց հետո: Այս կերպ Դուք կարող եք նվազեցնել բեռը, եթե իրական գործող հավելվածը պահանջում է արձագանքման ժամանակ:
Օպտիմալացումն իրականացնելուց հետո թարմացումը հաջողությամբ ավարտվեց:
... բայց ոչ ամբողջությամբ!
Թարմացումից հետո կես ժամվա ընթացքում հաճախորդը եկավ խնդիր: Տվյալների բազան շատ տարօրինակ էր աշխատում. պարբերաբար սկսում էին կապի վերականգնում. Ահա թե ինչ տեսք ուներ մոնիտորինգում.
Սքրինշոթը ցույց է տալիս սղոցային գրաֆիկը, քանի որ MySQL սերվերի որոշ թելեր պարբերաբար խափանում են սխալմամբ: Դիմումում հայտնվեցին սխալներ.
Տեղեկամատյանների արագ ստուգումը ցույց տվեց, որ mysqld daemon-ը չի կարող անհրաժեշտ ռեսուրսները ձեռք բերել օպերացիոն համակարգից: Սխալները դասավորելիս մենք հայտնաբերեցինք համակարգում «որբ» apparmor քաղաքականության ֆայլերը:
# dpkg -S /etc/apparmor.d/cache/usr.sbin.mysqld
dpkg-query: no path found matching pattern /etc/apparmor.d/cache/usr.sbin.mysqld
# dpkg -S /etc/apparmor.d/local/usr.sbin.mysqld
dpkg-query: no path found matching pattern /etc/apparmor.d/local/usr.sbin.mysqld
# dpkg -S /etc/apparmor.d/usr.sbin.mysqld
mysql-server-5.7: /etc/apparmor.d/usr.sbin.mysqld
# dpkg -l mysql-server-5.7
rc mysql-server-5.7 5.7.23-0ubuntu0.16.04.1 amd64
Այս ֆայլերը ստեղծվել են մի քանի տարի առաջ MySQL 5.7-ի թարմացման ժամանակ և պատկանում են հեռացված փաթեթին: Ֆայլերը ջնջելով և apparmor ծառայության վերագործարկումը լուծեց խնդիրը.
Ցանկացած, նույնիսկ ամենապարզ գործողությունը կարող է հանգեցնել անսպասելի խնդիրների: Եվ նույնիսկ լավ մտածված պլան ունենալը միշտ չէ, որ երաշխավորում է սպասվող արդյունքը։ Այժմ, ցանկացած թարմացման պլան, որը մեր թիմը ներառում է նաև ավելորդ ֆայլերի պարտադիր մաքրում, որոնք կարող էին հայտնվել վերջին գործողությունների արդյունքում:
Եվ այս ոչ այնքան պրոֆեսիոնալ գրաֆիկական ստեղծագործությամբ, ես կցանկանայի մեծ շնորհակալություն հայտնել Percona-ին իրենց հիանալի արտադրանքի համար: