MySQL'i (Percona Sunucusu) 5.7'den 8.0'a güncelleme

MySQL'i (Percona Sunucusu) 5.7'den 8.0'a güncelleme

İlerleme durmuyor, bu nedenle MySQL'in en son sürümlerine yükseltme nedenleri giderek daha zorlayıcı hale geliyor. Kısa bir süre önce projelerimizden birinde rahat Percona Server 5.7 kümelerini sürüm 8'e güncelleme zamanı gelmişti. Bütün bunlar Ubuntu Linux 16.04 platformunda gerçekleşti. Minimum kesinti süresiyle böyle bir işlemin nasıl gerçekleştirileceği ve güncelleme sırasında hangi sorunlarla karşılaştığımız - bu makaleyi okuyun.

Eğitim

Veritabanı sunucusundaki herhangi bir güncelleme büyük olasılıkla veritabanının yeniden yapılandırılmasıyla ilişkilidir: sistem kaynakları üzerindeki sınırlara ilişkin gereksinimlerdeki değişiklikler ve güncelliğini yitirmiş yönergelerden arındırılması gereken veritabanı yapılandırmalarının düzeltilmesi.

Güncellemeden önce kesinlikle resmi belgelere başvuracağız:

Ve bir eylem planı hazırlayalım:

  1. Güncelliğini yitirmiş yönergeleri kaldırarak yapılandırma dosyalarını düzeltin.
  2. Yardımcı programlarla uyumluluğu kontrol edin.
  3. Paketi yükleyerek bağımlı veritabanlarını güncelleyin percona-server-server.
  4. Master'ı aynı paketle güncelleyin.

Planın her noktasına bakalım ve neyin yanlış gidebileceğini görelim.

ÖNEMLİ! Galera'ya dayalı bir MySQL kümesini güncelleme prosedürünün, makalede açıklanmayan kendi incelikleri vardır. Bu durumda bu talimatı kullanmamalısınız.

Bölüm 1: Yapılandırmaları kontrol etme

MySQL sürüm 8'de kaldırıldı query_cache. Aslında öyleydi eski ilan edildi 5.7 sürümüne geri döndüm, ancak şimdi tamamen silindi. Buna göre ilgili direktiflerin kaldırılması gerekmektedir. İstekleri önbelleğe almak için artık harici araçları kullanabilirsiniz; örneğin, Proxy SQL.

Ayrıca yapılandırmada şu konularda güncel olmayan yönergeler vardı: innodb_file_format. MySQL 5.7'de InnoDB formatını seçmek mümkünse, 8. sürüm zaten çalışıyor demektir yalnızca Barracuda formatıyla.

Sonuç olarak aşağıdaki direktiflerin kaldırılmasıdır:

  • query_cache_type, query_cache_limit и query_cache_size;
  • innodb_file_format и innodb_file_format_max.

Kontrol etmek için Percona Server'ın Docker imajını kullanacağız. Sunucu yapılandırmasını dizine yerleştireceğiz mysql_config_test, ve onun yanında veriler ve günlükler için dizinler oluşturacağız. Percona-sunucu yapılandırma testi örneği:

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-centos

Sonuç olarak: Docker günlüklerinde veya günlüklerin bulunduğu dizinde (yapılandırmalarınıza bağlı olarak) sorunlu yönergelerin açıklanacağı bir dosya görünecektir.

İşte elimizde olanlar:

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.

Bu nedenle hâlâ kodlamaları çözmemiz ve güncelliğini yitirmiş yönergeyi değiştirmemiz gerekiyordu. expire-logs-days.

Bölüm 2: Çalışan kurulumların kontrol edilmesi

Güncelleme belgeleri, veritabanının uyumluluğunu kontrol etmek için 2 yardımcı program içerir. Bunların kullanımı yöneticinin mevcut veri yapısının uyumluluğunu kontrol etmesine yardımcı olur.

Klasik mysqlcheck yardımcı programıyla başlayalım. Basitçe çalıştırın:

mysqlcheck -u root -p --all-databases --check-upgrade

Herhangi bir sorun bulunmazsa yardımcı program 0 koduyla çıkacaktır:

MySQL'i (Percona Sunucusu) 5.7'den 8.0'a güncelleme

Ayrıca MySQL'in modern sürümlerinde bir yardımcı program mevcuttur mysql-kabuk (Percona durumunda bu pakettir) percona-mysql-shell). Klasik MySQL istemcisinin yerine geçer ve istemcinin, SQL kod düzenleyicisinin ve MySQL yönetim araçlarının işlevlerini birleştirir. Güncellemeden önce sunucuyu kontrol etmek için aşağıdaki komutları çalıştırabilirsiniz:

mysqlsh -- util check-for-server-upgrade { --user=root --host=1.1.1.1 --port=3306 } --config-path=/etc/mysql/my.cnf

İşte aldığımız yorumlar:

MySQL'i (Percona Sunucusu) 5.7'den 8.0'a güncelleme

Genel olarak kritik bir şey yok - yalnızca kodlamalarla ilgili uyarılar (aşağıya bakınız). Genel yürütme sonucu:

MySQL'i (Percona Sunucusu) 5.7'den 8.0'a güncelleme

Güncellemenin sorunsuz geçmesi gerektiğine karar verdik.

Kodlamalarla ilgili sorunları belirten yukarıdaki uyarılarla ilgili bir not. Gerçek şu ki yakın zamana kadar MySQL'de UTF-8 "doğru" UTF-8 değildi, çünkü 3 yerine yalnızca 4 bayt depoladı. MySQL 8'de bu nihayet düzeltmeye karar verdim: takma ad utf8 yakında kodlamaya yol açacak utf8mb4ve tablolardaki eski sütunlar şu şekilde olacaktır: utf8mb3. Daha fazla kodlama utf8mb3 kaldırılacak ancak bu sürümde kaldırılmayacak. Bu nedenle, çalışan DBMS kurulumunda mevcut olan kodlamaları güncelledikten sonra düzeltmeye karar verdik.

Bölüm 3: Sunucu Güncellemeleri

Bu kadar akıllı bir plan varken ne ters gidebilir ki?.. Nüansların her zaman meydana geldiğini çok iyi anlayarak, ilk deneyi MySQL geliştirici kümesi üzerinde gerçekleştirdik.

Daha önce de belirtildiği gibi, resmi belgeler MySQL sunucularının kopyalarla güncellenmesi konusunu kapsar. Sonuç olarak, MySQL 8 ana sürüm 5.7'den kopyalayabildiğinden, öncelikle tüm kopyaları (bağımlıları) güncellemeniz gerekir. Modu kullanmamızdan kaynaklanan bazı zorluklar var. usta <-> ustaUzak ana ünite modunda olduğunda salt okunur. Yani aslında savaş trafiği bir veri merkezine gidiyor, ikincisi ise yedek merkez.

Topoloji şuna benzer:

MySQL'i (Percona Sunucusu) 5.7'den 8.0'a güncelleme

Güncelleme kopyalarla başlamalıdır MySQL çoğaltma DC 2, mysql ana dc2 и mysql replica dc 1, ve mysql master dc 1 sunucusu ile sonlandırıyoruz.Daha güvenilir olması açısından sanal makineleri durdurup anlık görüntülerini aldık ve güncellemeden hemen önce komutuyla replikasyonu durdurduk. STOP SLAVE. Güncellemenin geri kalanı şöyle görünüyor:

  1. Yapılandırmalara 3 seçenek ekleyerek her kopyayı yeniden başlatıyoruz: skip-networking, skip-slave-start, skip-log-bin. Gerçek şu ki, veritabanını güncellemek, sistem tablolarındaki güncellemeleri içeren ikili günlükler oluşturur. Bu direktifler veritabanındaki uygulama verilerinde herhangi bir değişiklik olmayacağını ve sistem tablolarının güncellenmesine ilişkin bilgilerin ikili günlüklere dahil edilmeyeceğini garanti eder. Bu, çoğaltmaya devam ederken sorunları önleyecektir.
  2. Paketin kurulumu percona-server-server. MySQL sürüm 8'de şunu unutmamak önemlidir: hayır komutunu çalıştırmanız gerekiyor mysqlupgrade sunucu güncellemesinden sonra.
  3. Başarılı bir başlangıçtan sonra, ilk paragrafta eklenen parametreler olmadan sunucuyu yeniden başlatıyoruz.
  4. Çoğaltma işleminin başarılı bir şekilde çalıştığından emin oluyoruz: kontrol edin SHOW SLAVE STATUS ve uygulama veritabanındaki sayaçların bulunduğu tabloların güncellendiğini görün.

Her şey oldukça basit görünüyor: geliştirici güncellemesi başarılı oldu. Tamam, üretim için gecelik bir güncellemeyi güvenli bir şekilde planlayabilirsiniz.

Üzüntü yoktu - ürünü güncelledik

Ancak başarılı geliştirme deneyiminin üretime aktarılması sürprizsiz değildi.

Neyse ki güncelleme sürecinin kendisi replikalarla başlıyor, bu nedenle zorluklarla karşılaştığımızda işi durdurduk ve replikayı anlık görüntüden geri yükledik. Sorunların araştırılması ertesi sabaha ertelendi. Günlükler aşağıdaki girişleri içeriyordu:

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'da çeşitli e-posta listelerinin arşivlerinin araştırılması, bu sorunun şu nedenlerden kaynaklandığının anlaşılmasına yol açtı: MySQL hatası. Her ne kadar bu daha muhtemel bir yardımcı program hatası olsa da mysqlcheck и mysqlsh.

MySQL'in ondalık alanlar (int, Tinyint, vb.) için verileri temsil etme biçimini değiştirdiği ortaya çıktı, bu nedenle mysql-server bunları depolamak için farklı bir yol kullanıyor. Eğer veritabanınız başlangıçta 5.5 veya 5.1 sürümündeyseniz ve ardından 5.7'ye güncellediyseniz, yapmanız gerekebilir OPTIMIZE bazı tablolar için. Daha sonra MySQL veri dosyalarını güncelleyerek bunları mevcut depolama formatına aktaracaktır.

Bunu yardımcı programla da kontrol edebilirsiniz. mysqlfrm:

mysqlfrm --diagnostic -vv /var/lib/mysql/db/table.frm
...
 'field_length': 8,
  'field_type': 246, # формат поля
  'field_type_name': 'decimal',
  'flags': 3,
  'flags_extra': 67,
  'interval_nr': 0,
 'name': 'you_deciaml_column',
...

Eğer field_type 0'a eşitse, tabloda eski tür kullanılır - yapmanız gerekir OPTIMIZE. Ancak değer 246 ise zaten yeni bir türünüz var demektir. Türler hakkında daha fazla bilgiyi burada bulabilirsiniz. kod.

Ayrıca, içinde bu hata Bizi atlayan ikinci olası nedeni düşünüyoruz: sistem tablosunda InnoDB tablolarının bulunmaması INNODB_SYS_TABLESPACES, eğer tablolar 5.1 sürümünde oluşturulmuşsa. Güncelleme sırasında sorun yaşamamak için şunları kullanabilirsiniz: ekli SQL betiği.

Geliştiricide neden böyle sorunlar yaşamadık? Veritabanı üretimden periyodik olarak buraya kopyalanır; böylece tablolar yeniden yaratıldı.

Ne yazık ki, gerçekten çalışan büyük bir veritabanında, evrensel bir veri tabanını alıp çalıştıramayacaksınız. OPTIMIZE. percona-toolkit burada yardımcı olacaktır: pt-online-schema-change yardımcı programı çevrimiçi OPTIMIZE işlemi için mükemmeldir.

Güncellenen plan şuna benziyordu:

  1. Tüm tabloları optimize edin.
  2. Veritabanlarını güncelleyin.

Bunu kontrol etmek ve aynı zamanda güncelleme zamanını öğrenmek için kopyalardan birini devre dışı bıraktık ve tüm tablolar için aşağıdaki komutu çalıştırdık:

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=t1

Yardımcı programın ana tablodan verileri kopyaladığı yeni bir geçici tablo oluşturması nedeniyle tablolar uzun kilitlenmeler olmadan güncellenir. Her iki tablonun aynı olduğu anda orijinal tablo kilitlenir ve yenisi ile değiştirilir. Bizim durumumuzda, bir test çalışması tüm tabloların güncellenmesinin yaklaşık bir gün alacağını gösterdi, ancak verilerin kopyalanması disklerde çok fazla yük oluşmasına neden oldu.

Bunu önlemek için üretimde argümanı komuta ekledik. --sleep 10 değeriyle - bu parametre, bir veri kümesini yeni bir tabloya aktardıktan sonra bekleme süresini ayarlar. Bu şekilde, çalışan gerçek uygulamanın yanıt süresi gerektirmesi durumunda yükü azaltabilirsiniz.

Optimizasyon gerçekleştirildikten sonra güncelleme başarılı oldu.

... ama tamamen değil!

Güncellemeden yarım saat sonra istemci bir sorunla geldi. Veritabanı çok tuhaf çalıştı: periyodik olarak başlatıldılar bağlantı sıfırlanır. İzlemede şöyle görünüyordu:

MySQL'i (Percona Sunucusu) 5.7'den 8.0'a güncelleme

Ekran görüntüsünde, bazı MySQL sunucusu iş parçacıklarının periyodik olarak bir hatayla çökmesi nedeniyle testere dişi grafiği görülüyor. Uygulamada hatalar ortaya çıktı:

[PDOException] SQLSTATE[HY000] [2002] Connection refused

Günlüklerin hızlı bir şekilde incelenmesi, mysqld arka plan programının işletim sisteminden gerekli kaynakları alamadığını ortaya çıkardı. Sistemdeki hataları ayıklarken keşfettik "yetim" apparmor politika dosyaları:

# 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

Bu dosyalar birkaç yıl önce MySQL 5.7'ye yükseltme yapılırken oluşturuldu ve kaldırılan bir pakete ait. Dosyaları silmek ve apparmor hizmetini yeniden başlatmak sorunu çözdü:

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 apparmor

Sonuç olarak

En basit işlem bile beklenmedik sorunlara yol açabilir. Ve iyi düşünülmüş bir plana sahip olmak bile her zaman beklenen sonucu garanti etmez. Artık ekibimizin sunduğu güncelleme planları, son eylemler sonucunda ortaya çıkabilecek gereksiz dosyaların zorunlu olarak temizlenmesini de içeriyor.

Pek de profesyonel olmayan bu grafik yaratıcılığıyla, mükemmel ürünleri için Percona'ya çok teşekkür etmek istiyorum!

MySQL'i (Percona Sunucusu) 5.7'den 8.0'a güncelleme

PS

Blogumuzda da okuyun:

Kaynak: habr.com

Yorum ekle