Mengemas kini MySQL (Percona Server) daripada 5.7 kepada 8.0

Mengemas kini MySQL (Percona Server) daripada 5.7 kepada 8.0

Kemajuan tidak berhenti, jadi sebab untuk menaik taraf kepada versi terkini MySQL menjadi semakin menarik. Tidak lama dahulu, dalam salah satu projek kami, sudah tiba masanya untuk mengemas kini kluster Percona Server 5.7 yang selesa kepada versi 8. Semua ini berlaku pada platform Ubuntu Linux 16.04. Bagaimana untuk melakukan operasi sedemikian dengan masa henti yang minimum dan masalah yang kami hadapi semasa kemas kini - baca dalam artikel ini.

Latihan

Sebarang kemas kini pelayan pangkalan data berkemungkinan besar dikaitkan dengan konfigurasi semula pangkalan data: perubahan dalam keperluan untuk had pada sumber sistem dan pembetulan konfigurasi pangkalan data yang perlu dibersihkan daripada arahan lapuk.

Sebelum mengemas kini, kami pasti akan merujuk kepada dokumentasi rasmi:

Dan mari kita buat pelan tindakan:

  1. Betulkan fail konfigurasi dengan mengalih keluar arahan yang sudah lapuk.
  2. Semak keserasian dengan utiliti.
  3. Kemas kini pangkalan data hamba dengan memasang pakej percona-server-server.
  4. Kemas kini induk dengan pakej yang sama.

Mari kita lihat setiap titik rancangan dan lihat apa yang boleh berlaku.

PENTING! Prosedur untuk mengemas kini kluster MySQL berdasarkan Galera mempunyai kehalusan tersendiri yang tidak diterangkan dalam artikel. Anda tidak sepatutnya menggunakan arahan ini dalam kes ini.

Bahagian 1: Menyemak konfigurasi

MySQL telah dialih keluar dalam versi 8 query_cache. Sebenarnya dia diisytiharkan usang kembali dalam versi 5.7, tetapi sekarang dipadam sepenuhnya. Sehubungan itu, adalah perlu untuk mengalih keluar arahan yang berkaitan. Dan untuk permintaan cache kini anda boleh menggunakan alat luaran - contohnya, ProxySQL.

Juga dalam konfigurasi terdapat arahan usang tentang innodb_file_format. Jika dalam MySQL 5.7 adalah mungkin untuk memilih format InnoDB, maka versi ke-8 sudah berfungsi hanya dengan format Barracuda.

Keputusan kami ialah mengalih keluar arahan berikut:

  • query_cache_type, query_cache_limit ΠΈ query_cache_size;
  • innodb_file_format ΠΈ innodb_file_format_max.

Untuk menyemak, kami akan menggunakan imej Docker Server Percona. Kami akan meletakkan konfigurasi pelayan dalam direktori mysql_config_test, dan di sebelahnya kami akan membuat direktori untuk data dan log. Contoh ujian konfigurasi pelayan Percona:

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

Intinya: sama ada dalam log Docker atau dalam direktori dengan log - bergantung pada konfigurasi anda - fail akan muncul di mana arahan bermasalah akan diterangkan.

Inilah yang kami ada:

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.

Oleh itu, kami masih perlu memikirkan pengekodan dan menggantikan arahan yang sudah lapuk expire-logs-days.

Bahagian 2: Memeriksa pemasangan yang berfungsi

Dokumentasi kemas kini mengandungi 2 utiliti untuk menyemak pangkalan data untuk keserasian. Penggunaannya membantu pentadbir menyemak keserasian struktur data sedia ada.

Mari kita mulakan dengan utiliti mysqlcheck klasik. Jalankan sahaja:

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

Jika tiada masalah ditemui, utiliti akan keluar dengan kod 0:

Mengemas kini MySQL (Percona Server) daripada 5.7 kepada 8.0

Di samping itu, utiliti tersedia dalam versi moden MySQL mysql-shell (dalam kes Percona ini adalah pakejnya percona-mysql-shell). Ia adalah pengganti untuk klien mysql klasik dan menggabungkan fungsi klien, editor kod SQL dan alat pentadbiran MySQL. Untuk menyemak pelayan sebelum mengemas kini, anda boleh menjalankan arahan berikut melaluinya:

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

Berikut adalah komen yang kami terima:

Mengemas kini MySQL (Percona Server) daripada 5.7 kepada 8.0

Secara umum, tiada yang kritikal - hanya amaran tentang pengekodan (lihat di bawah). Keputusan pelaksanaan keseluruhan:

Mengemas kini MySQL (Percona Server) daripada 5.7 kepada 8.0

Kami memutuskan bahawa kemas kini harus berjalan tanpa masalah.

Nota tentang amaran di atas yang menunjukkan masalah dengan pengekodan. Hakikatnya ialah UTF-8 dalam MySQL sehingga baru-baru ini bukan "benar" UTF-8, kerana ia hanya menyimpan 3 bait dan bukannya 4. Dalam MySQL 8 ini akhirnya boleh dilakukan memutuskan untuk memperbaikinya: alias utf8 tidak lama lagi akan membawa kepada pengekodan utf8mb4, dan lajur lama dalam jadual akan menjadi utf8mb3. Pengekodan lanjut utf8mb3 akan dialih keluar, tetapi tidak dalam keluaran ini. Oleh itu, kami memutuskan untuk membetulkan pengekodan yang sudah ada pada pemasangan DBMS yang sedang berjalan, selepas mengemas kininya.

Bahagian 3: Kemas Kini Pelayan

Apa yang boleh menjadi salah apabila terdapat rancangan pintar sedemikian?.. Memahami sepenuhnya bahawa nuansa sentiasa berlaku, kami menjalankan percubaan pertama pada kumpulan pembangun MySQL.

Seperti yang telah disebutkan, dokumentasi rasmi merangkumi isu mengemas kini pelayan MySQL dengan replika. Intinya ialah anda harus mengemas kini semua replika (hamba) terlebih dahulu, kerana MySQL 8 boleh mereplikasi daripada versi induk 5.7. Beberapa kesukaran terletak pada hakikat bahawa kami menggunakan mod tuan <-> tuan, apabila induk jauh berada dalam mod baca sahaja. Iaitu, sebenarnya, trafik pertempuran pergi ke satu pusat data, dan yang kedua adalah sandaran.

Topologi kelihatan seperti ini:

Mengemas kini MySQL (Percona Server) daripada 5.7 kepada 8.0

Kemas kini mesti bermula dengan replika mysql replika dc 2, mysql master dc 2 ΠΈ mysql replica dc 1, dan berakhir dengan pelayan mysql master dc 1. Untuk menjadi lebih dipercayai, kami menghentikan mesin maya, mengambil syot kilatnya dan sejurus sebelum kemas kini menghentikan replikasi dengan arahan STOP SLAVE. Kemas kini selebihnya kelihatan seperti ini:

  1. Kami memulakan semula setiap replika dengan menambah 3 pilihan pada konfigurasi: skip-networking, skip-slave-start, skip-log-bin. Hakikatnya ialah mengemas kini pangkalan data menjana log binari dengan kemas kini kepada jadual sistem. Arahan ini menjamin bahawa tidak akan ada perubahan pada data aplikasi dalam pangkalan data, dan maklumat tentang mengemas kini jadual sistem tidak akan disertakan dalam log binari. Ini akan mengelakkan masalah apabila menyambung semula replikasi.
  2. Memasang pakej percona-server-server. Adalah penting untuk diperhatikan bahawa dalam MySQL versi 8 tiada anda perlu menjalankan arahan mysqlupgrade selepas kemas kini pelayan.
  3. Selepas permulaan yang berjaya, kami memulakan semula pelayan sekali lagi - tanpa parameter yang ditambahkan dalam perenggan pertama.
  4. Kami memastikan replikasi berfungsi dengan jayanya: semak SHOW SLAVE STATUS dan lihat bahawa jadual dengan pembilang dalam pangkalan data aplikasi dikemas kini.

Semuanya kelihatan agak mudah: kemas kini dev berjaya. Ok, anda boleh menjadualkan kemas kini setiap malam untuk pengeluaran dengan selamat.

Tidak ada kesedihan - kami mengemas kini prod

Walau bagaimanapun, pemindahan pengalaman pembangun yang berjaya kepada pengeluaran bukan tanpa kejutan.

Nasib baik, proses kemas kini itu sendiri bermula dengan replika, jadi apabila kami menghadapi kesukaran, kami menghentikan kerja dan memulihkan replika dari syot kilat. Siasatan masalah itu ditangguhkan sehingga keesokan paginya. Log mengandungi entri berikut:

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

Menyelidik arkib pelbagai senarai mel di Google membawa kepada pemahaman bahawa masalah ini berlaku disebabkan oleh pepijat MySQL. Walaupun ini lebih berkemungkinan pepijat utiliti mysqlcheck ΠΈ mysqlsh.

Ternyata MySQL mengubah cara mereka mewakili data untuk medan perpuluhan (int, tinyint, dll.), jadi mysql-server menggunakan cara yang berbeza untuk menyimpannya. Jika pangkalan data anda pada mulanya berada dalam versi 5.5 atau 5.1, dan kemudian anda mengemas kini kepada 5.7, maka anda mungkin perlu melakukannya OPTIMIZE untuk beberapa meja. Kemudian MySQL akan mengemas kini fail data, memindahkannya ke format storan semasa.

Anda juga boleh menyemak ini dengan utiliti 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',
...

Jika field_type Sekiranya anda mempunyainya sama dengan 0, maka jenis lama digunakan dalam jadual - anda perlu menjalankannya OPTIMIZE. Walau bagaimanapun, jika nilainya ialah 246, anda sudah mempunyai jenis baharu. Maklumat lanjut tentang jenis boleh didapati dalam kod.

Lebih-lebih lagi, di pepijat ini Kami sedang mempertimbangkan kemungkinan sebab kedua, yang memintas kami: ketiadaan jadual InnoDB dalam jadual sistem INNODB_SYS_TABLESPACES, jika ia, jadual, dicipta dalam versi 5.1. Untuk mengelakkan masalah semasa mengemas kini, anda boleh menggunakan skrip SQL yang dilampirkan.

Mengapa kami tidak mengalami masalah sedemikian pada dev? Pangkalan data disalin secara berkala di sana daripada pengeluaran - oleh itu, meja dicipta semula.

Malangnya, pada pangkalan data besar yang benar-benar berfungsi, anda tidak akan dapat mengambil dan melaksanakan universal OPTIMIZE. percona-toolkit akan membantu di sini: utiliti pt-online-schema-change sangat baik untuk operasi OPTIMIZE dalam talian.

Pelan yang dikemas kini kelihatan seperti ini:

  1. Optimumkan semua jadual.
  2. Kemas kini pangkalan data.

Untuk menyemaknya dan pada masa yang sama mengetahui masa kemas kini, kami melumpuhkan salah satu replika dan menjalankan arahan berikut untuk semua jadual:

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

Jadual dikemas kini tanpa kunci yang panjang disebabkan oleh fakta bahawa utiliti mencipta jadual sementara baharu di mana ia menyalin data daripada jadual utama. Pada masa kedua-dua jadual adalah sama, jadual asal dikunci dan digantikan dengan yang baharu. Dalam kes kami, ujian dijalankan menunjukkan bahawa ia akan mengambil masa kira-kira sehari untuk mengemas kini semua jadual, tetapi menyalin data menyebabkan terlalu banyak beban pada cakera.

Untuk mengelakkan ini, dalam pengeluaran kami menambah hujah pada arahan --sleep dengan nilai 10 - parameter ini melaraskan tempoh menunggu selepas memindahkan kumpulan data ke jadual baharu. Dengan cara ini anda boleh mengurangkan beban jika aplikasi berjalan sebenar menuntut masa tindak balas.

Selepas melakukan pengoptimuman, kemas kini telah berjaya.

... tetapi tidak sepenuhnya!

Dalam masa setengah jam selepas kemas kini, pelanggan datang dengan masalah. Pangkalan data berfungsi dengan sangat pelik: secara berkala mereka bermula sambungan ditetapkan semula. Ini adalah rupa dalam pemantauan:

Mengemas kini MySQL (Percona Server) daripada 5.7 kepada 8.0

Tangkapan skrin menunjukkan graf gigi gergaji disebabkan fakta bahawa beberapa utas pelayan MySQL ranap secara berkala dengan ralat. Ralat muncul dalam aplikasi:

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

Pemeriksaan pantas terhadap log mendedahkan bahawa daemon mysqld tidak dapat memperoleh sumber yang diperlukan daripada sistem pengendalian. Semasa menyusun ralat, kami dapati dalam sistem fail dasar perisai "yatim piatu".:

# 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

Fail ini dicipta semasa menaik taraf kepada MySQL 5.7 beberapa tahun yang lalu dan tergolong dalam pakej yang dialih keluar. Memadamkan fail dan memulakan semula perkhidmatan apparmor menyelesaikan masalah:

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

Kesimpulannya

Mana-mana, walaupun operasi yang paling mudah, boleh membawa kepada masalah yang tidak dijangka. Dan walaupun mempunyai rancangan yang difikirkan dengan baik tidak selalu menjamin hasil yang diharapkan. Kini, sebarang rancangan kemas kini yang pasukan kami turut menyertakan pembersihan mandatori fail yang tidak diperlukan yang mungkin muncul akibat tindakan baru-baru ini.

Dan dengan kreativiti grafik yang tidak begitu profesional ini, saya ingin mengucapkan terima kasih yang tidak terhingga kepada Percona untuk produk cemerlang mereka!

Mengemas kini MySQL (Percona Server) daripada 5.7 kepada 8.0

PS

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komen