
İnkişaf dayanmaz, buna görə də MySQL-ın aktual versiyalarına yenilənmək üçün səbəblər daha da ağırlıq qazanır. Tezliklə, layihələrimizdən birində Percona Server 5.7-dən 8-ci versiyaya keçid etmə vaxtı gəldi. Bütün bunlar Ubuntu Linux 16.04 platformasında baş verdi. Belə bir əməliyyatı minimal dayanmalarla necə həyata keçirmək və yeniləmə zamanı hansı problemlərlə üzləşdiyimizi bu məqalədə oxuyun.
Hazırlıq
Hər hansı bir verilənlər bazası serverinin yenilənməsi, ehtimal ki, bazanın konfiqurasiyasının yenidən tənzimlənməsi ilə bağlıdır: sistem resursları üçün limit tələblərinin dəyişməsi və köhnəlmiş direktivlərdən təmizlənməsi lazım olan baza konfiqurasiyalarının düzəldilməsi.
Yeniləməzdən əvvəl mütləq rəsmi sənədlərə müraciət edəcəyik:
- ;
- ;
- ;
- .
Və icra planı hazırlayacağıq:
- Köhnəlmiş direktivləri silərək konfiqurasiya fayllarını düzəldin.
- Uyğunluğu yoxlayın.
- Slave bazalarını yenileyin, paketi quraşdırın
percona-server-server. - Master-i yeniləyin, eyni paketi quraşdırın.
Planın hər bir maddəsini müzakirə edək və nələrin səhv gedə biləcəyinə baxaq.
VACİB! Galera bazası üzərində MySQL-klasterlərinin yeniləmə prosesi özünəməxsus incəliklərə malikdir ki, bu məqalədə təsvir edilməyib. Belə bir halda bu təlimatı istifadə etmək düzgün deyil.
Bölüm 1: Konfiqurasiyaların yoxlanması
MySQL 8-ci versiyasında query_cachesilinib. Əslində, o, 5.7 versiyasında, lakin indi Bu səbəbdən, əlaqəli direktivləri aradan qaldırmaq lazımdır. İndi sorğu keşi üçün xarici alətlərdən istifadə edə bilərsiniz — məsələn, .
Həmçinin konfiqurasiyada köhnəlmiş direktivlər tapdıq innodb_file_format. MySQL 5.7-də InnoDB formatını seçmək imkanı olsa da, 8-ci versiya artıq .
Nəticəmiz — aşağıdakı direktivlərin silinməsi:
-
query_cache_type,query_cache_limitvəquery_cache_size; -
innodb_file_formatvəinnodb_file_format_max.
Yoxlamaq üçün Percona Server-in Docker imicindən istifadə edəcəyik. Serverin konfiqurasiyasını mysql_config_test, yanında isə məlumat və loglar üçün direktoriyalar yaradacağıq. Percona-server konfiqurasiyasının test nümunəsi:
mkdir -p {mysql_config_test,mysql_data,mysql_logs}
cp -r /etc/mysql/conf.d/* mysql_config_test/
docker run --name some-percona -v $(pwd)/mysql_config_test:/etc/my.cnf.d/ -v $(pwd)/mysql_data/:/var/lib/mysql/ -v $(pwd)/mysql_logs/:/var/log/mysql/ -e MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD} -d percona:8-centosNəticə: ya Docker loglarında, ya da loglar üçün direktoriyada — konfiqurasiyalarınıza bağlı olaraq — problemləri təsvir edən bir fayl yaranacaq.
Bizim vəziyyətimiz belə oldu:
2020-04-03T12:44:19.670831Z 0 [Warning] [MY-011068] [Server] 'expire-logs-days' sintaksisi köhnəlmişdir və gələcək bir buraxılışda çıxarılacaq. Zəhmət olmasa 'binlog_expire_logs_seconds' istifadə edin.
2020-04-03T12:44:19.671678Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' hal-hazırda UTF8MB3 simvol dəstinin sinonimidir, amma gələcək buraxılışda UTF8MB4 üçün sinonim olacaq. Zəhmət olmasa, mübahisəni aradan qaldırmaq üçün UTF8MB4 istifadə etməyi düşünün.
2020-04-03T12:44:19.671682Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' köhnəlmiş UTF8MB3 simvol dəstinin kolasiyasıdır. Zəhmət olmasa düzgün kolasiya ilə UTF8MB4 istifadə etməyi düşünün. Beləliklə, kodlamalarla bağlı daha çox işləməli olduq və köhnə direktivi əvəz etməli olduq. expire-logs-days.
Hissə 2: İşləyən quraşdırmaların yoxlanması
Yeniləmə sənədində verilən 2 utilit var ki, bunlar verilənlər bazasının uyğunluğunu yoxlamaq üçün istifadə olunur. Onların istifadəsi administratora mövcud məlumat strukturlarının uyğunluğunu yoxlamağa kömək edir.
Klassik mysqlcheck utilitindən başlayarıq. Sadəcə olaraq çalıştırmaq kifayətdir:
mysqlcheck -u root -p --all-databases --check-upgradeƏgər heç bir problem aşkar edilməyibsə, utilit 0 kodu ilə bitəcək:

Bundan əlavə, müasir MySQL versiyalarında mövcud olan (Percona üçün bu paket percona-mysql-shell). Bu, klassik mysql müştərisinin əvəzinədir və MySQL müştərinin, SQL kodu redaktorunun və idarəetmə vasitələrinin funksiyalarını birləşdirir. Yeniləmədən əvvəl serveri yoxlamaq üçün burada aşağıdakı əmri icra edə bilərsiniz:
mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=\/etc\/mysql\/my.cnfVə aşağıdakı qeydləri aldıq:

Ümumiyyətlə, ciddi bir şey yoxdur — yalnız kodlamalarla bağlı xəbərdarlıqlar var (aşağıya baxın). İcra nəticəsinin ümumi nəticəsi:

Yeniləmənin problemsiz getməli olduğuna qərar verdik.
Yuxarıdakı xəbərdarlıqlara dair qeydlər kodlamalarla bağlı problemlərin olduğunu göstərir. Məsələ ondadır ki, hazırda MySQL-də UTF-8 əvvəllər bunu düzəltmək qərarına gəldilər tezliklə kodlama olacaq utf8mb4 , və köhnə sütunlar cədvəllərdə olacaq utf8mb3. İrəlidə bu kodlama çıxarılacaq, amma bu buraxılışda deyil. Buna görə də, yeniləmədən sonra işlək verilənlər bazasında kodlamaları düzəltməyə qərar verdik. Hissə 3: Serverlərin yenilənməsiBir çox gözəl plan olduğunda, nə pis ola bilər?.. Nüansların hər zaman baş verdiyini mükəmməl başa düşərək, ilk eksperimentimizi MySQL dev klasterində apardıq. Hissə 3: Serverlərin yenilənməsi Artıq qeyd olunduğu kimi,
rəsmi sənəd
MySQL serverlərinin replika ilə yenilənməsi məsələsini işıqlandırır. Məsələ odur ki, əvvəlcə bütün replika (slave) yenilənməlidir, çünki MySQL 8, 5.7 versiya masterindən replikasiyaya imkan verir. Bəzi çətinliklər var ki, bizim 'master master' rejimi istifadə edilir
, uzaq master 'read-only' rejimindədir. Topologiya belə görünür: Yeniləmə replikalardan başlayacaqmysql replica dc 2 mysql master dc 2. То есть фактически боевой трафик поступает в один ЦОД, а 2-й является резервным.
Топология выглядит следующим образом:

Обновление должно начаться с реплик mysql replica dc 2, mysql master dc 2 və mysql replika dc 1, və sona doğru — mysql master dc 1 serveri. Daha çox etibarlılıq üçün virtual maşınları dayandırdıq, onların snapshotlarını aldıq və yeniləmədən əvvəl replikasiyonu "STOP SLAVE" komandasını istifadə edərək dayandırdıq. STOP SLAVE. Qalan hissədə yeniləmə belə görünür:
- Hər bir replikanı yenidən başladırıq, konfiqurasiyalara 3 opsiya əlavə edirik:
skip-networking,skip-slave-start,skip-log-bin. Məlumat bazasının yenilənməsi sistem cədvəllərinin yenilənməsi ilə bağlı ikili loglar yaradır. Bu direktivlər, tətbiq məlumatlarının məlumat bazasında dəyişməməsinə və ikili loglarda sistem cədvəllərinin yenilənməsi ilə bağlı məlumatların olmamasını təmin edir. Bu, replikasiyanın bərpa olunmasında problemlərin qarşısını almağa kömək edəcək. - Paketin quraşdırılması
percona-server-server. Qeyd etmək vacibdir ki, MySQL 8 versiyasında deyil mysqlupgradekomandasını serveri yenilədikdən sonra işə salmaq lazımdır.Server uğurla başladıqdan sonra bir daha serveri ilk maddədə əlavə olunan parametrlərlə olmadan yenidən başladırıq. - Replikasiyanın uğurla işlədiyinə əmin oluruq: baxırıq
- SHOW SLAVE STATUS
və görürük ki, tətbiq məlumat bazasında sayğacların cədvəlləri yenilənir.Bu, olduqca sadə görünür: dev yeniləməsi uğurla başa çatdı. Yaxşı, production üçün gecə yeniləməsini rahat şəkildə planlaşdıra bilərik.
Heç bir problem olmadan — prod-u yenilədik.
Ancaq devdən production-a müvəffəqiyyətlə transfer edərkən sürprizlər oldu.
Xoşbəxtlikdən, yeniləmə prosesi replikalardan başlayır, buna görə çətinliklərlə rastlaşdıqda işləri dayandırdıq və replikanı snapshotdan bərpa etdik. Problemlərə araşdırma ertəsi günə keçirildi. Loglarda aşağıdakı qeydlər var idi:
2020-01-14T21:43:21.500563Z 2 [ERROR] [MY-012069] [InnoDB] cədvəl: t1 19 sütun var, lakin InnoDB lüğətində 20 sütun var 2020-01-14T21:43:21.500722Z 2 [ERROR] [MY-010767] [Server] db1.t1 üçün SE məlumatlarının düzəldilməsində xəta 2020-01-14T21:43:24.208365Z 0 [ERROR] [MY-010022] [Server] DD cədvəlləri doldurmaqda uğursuz oldu. 2020-01-14T21:43:24.208658Z 0 [ERROR] [MY-010119] [Server] İptal edilir
Müxtəlif poçt göndərişləri arxivlərini Google-da araşdırmaq, bu cür problemi başa düşməklə gətirdi ki, bu, MySQL təsviri mysqlcheck mysqlsh və işləticiləri ilə bağlı bir problemdir. Görünür, MySQL ondalık sahələrin (int, tinyint və s.) təqdim etmə üsulunu dəyişdirdi, buna görə mysql-server daxilində onların saxlanılması üçün fərqli bir üsul istifadə edilir. Əgər məlumat bazanız.
ilk növbədə 5.5 və ya 5.1 versiyasında olub, sonra 5.7-ə yüksəldisinizsə, bəlkə də bəzi cədvəllər üçün OPTIMIZE işlətmək lazım olsa, MySQL məlumat fayllarını yenilərək onları müasir saxlanma formatına keçirəcək. Bunu
mysqlfrm mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm ... 'field_length': 8, 'field_type': 246, # sahə formatı 'field_type_name': 'decimal', 'flags': 3, 'flags_extra': 67, 'interval_nr': 0, 'name': 'you_deciaml_column', ...:
field_type WLAN cihazına qoşula bilməzsənsə, bu cür bir şey görəcəksiniz: sizin 0-dirsə, cədvəl köhnə tipi istifadə edir — bununla məşğul olmalısınız . Ancaq, əgər 246 dəyəri varsa — artıq yeni tip var. Tiplərlə daha ətraflı tanış ola bilərsiniz işlətmək lazım olsa, MySQL məlumat fayllarını yenilərək onları müasir saxlanma formatına keçirəcək.kodda .
bu müəyyən problemi İkinci mümkün səbəb, bizim tərəfimizdən gözardı edilmiş, InnoDB cədvəllərinin sistem cədvəlində olmamasıdır. INNODB_SYS_TABLESPACES, əgər həmin cədvəllər 5.1 versiyasında yaradılıbsa. Yenilənmə zamanı problemlərin yaranmaması üçün əlavə olunan .
Niyə dev mühitində belə problemlərimiz olmadı? Verilənlər bazası oraya periodik olaraq production-dan köçürülür — beləliklə, cədvəllər yenidən yaradılır..
Təəssüf ki, real çalışma mühitində olan böyük verilənlər bazasında sadəcə götürmək və genişmiqyaslı işlətmək lazım olsa, MySQL məlumat fayllarını yenilərək onları müasir saxlanma formatına keçirəcək.təhlükəsiz `percona-toolkit` kömək edə bilər: online OPTIMIZE əməliyyatı üçün pt-online-schema-change aləti mükəmməldir.
Yenilənmiş plan belə oldu:
- Bütün cədvəlləri optimallaşdırmaq.
- Verilənlər bazalarını yeniləmək.
Onu yoxlamaq və yenilənmə vaxtını öyrənmək üçün bir replikamızın əlaqəsini kəsdik, bütün cədvəllər üçün isə aşağıdakı komandaları işə saldıq:
pt-online-schema-change --critical-load Threads_running=150 --alter "ENGINE=InnoDB" --execute --chunk-size 100 --quiet --alter-foreign-keys-method auto h=127.0.0.1,u=root,p=${MYSQL_PASSWORD},D=db1,t=t1Cədvəllərin yenilənməsi uzunmüddətli bloklanmalar olmadan həyata keçirilir, çünki vasitə yeni müvəqqəti cədvəl yaradır, əsl cədvəldən məlumatları kopyalayır. Hər iki cədvəl eyni olduqda, ilkin cədvəl bloklanır və yeni ilə əvəz olunur. Bizim vəziyyətimizdə test işə salma göstərdi ki, bütün cədvəllərin yenilənməsi təxminən bir gün çəkəcək, amma məlumatların kopyalanması disklərdə çox böyük yük yaradır.
Bunun qarşısını almaq üçün production-da komandaya --sleep 10 dəyəri ilə bir parametr əlavə etdik — bu parametr yeni cədvələ məlumat dəstini köçürdükdən sonra gözləmə müddətini tənzimləyir. Beləliklə, əsl işə salınmış tətbiq zaman cavabına tələbkar olduqdan, yükü azalda bilərik.
Optimallaşdırma tamamlandıqdan sonra yeniləmə müvəffəqiyyətlə başa çatdı.
… amma tam deyil!
Yeniləmədən yarım saat sonra müştəri problem ilə geri döndü. Verilənlər bazası çox qəribə işləyirdi: arada bağlantıların sıfırlanması. Monitorinqdə bu necə görünürdü:

Ekran görüntüsündə, MySQL serverinin bəzi axınları səhv ilə aralı olaraq çökməsi ilə bağlı dişli xətti görmək mümkündür. Tətbiqdə səhvlər ortaya çıxdı:
[PDOException] SQLSTATE[HY000] [2002] Bağlantı rədd edildiQısa bir log müayinəsi ortaya qoydu ki, mysqld deminin əməliyyat sistemindən lazım olan resursları əldə edə bilmir. Səhvləri araşdırarkən sistemdə yeni qalmış apparmor siyasət fayllarını aşkar etdik.:
# 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 amd64Bu fayllar iki il əvvəl MySQL 5.7-ə yenilənmə zamanı yaradılıb və silinmiş pakətə aiddir. Faylların silinməsi və apparmor xidmətinin yenidən başlatılması problemi həll etdi:
systemctl stop apparmor
rm /etc/apparmor.d/cache/usr.sbin.mysqld
rm /etc/apparmor.d/local/usr.sbin.mysqld
rm /etc/apparmor.d/usr.sbin.mysqld
systemctl start apparmorNəticə olaraq
Hər hansı, hətta ən sadə əməliyyat gözlənilməz problemlərə səbəb ola bilər. Hətta mükəmməl düşünülmüş bir plan da həmişə gözlənilən nəticəni təmin etmir. İndi komandamızın hər hansı bir yeniləmə planına artıq ehtiyatsız faylların təmizlənməsi də daxildir, bu fayllar son əməliyyatların nəticəsində yaranmış ola bilər.
Və bu çox peşəkar olmayan qrafik yaradıcılığa görə Percona şirkətinə onların mükəmməl məhsulları üçün böyük təşəkkür edirəm!

P.S.
Blogumuzda oxuyun:
- «»;
- «»;
- «»;
- «»;
- «».
Mənbə: habr.com
