ترقية MySQL (خادم بيركونا) من 5.7 إلى 8.0



التقدم لا يقف ساكنا ، لذلك تزداد أهمية الترقية إلى أحدث إصدارات MySQL. منذ وقت ليس ببعيد ، في أحد مشاريعنا ، حان الوقت لترقية مجموعات Percona Server 5.7 المريحة إلى الإصدار 8. حدث كل هذا على منصة Ubuntu Linux 16.04. كيفية إجراء عملية مماثلة بأقل وقت للتعطل والمشكلات التي واجهناها أثناء الترقية - اقرأ هذه المقالة.

تدريب


من المرجح أن يكون أي تحديث لخادم قاعدة البيانات مرتبطًا بترحيل قاعدة البيانات: التغييرات في متطلبات الحدود على موارد النظام وتصحيح تكوينات قاعدة البيانات ، والتي يجب محوها من التوجيهات القديمة.

قبل التحديث ، سننتقل بالتأكيد إلى الوثائق الرسمية:


ووضع خطة عمل:

  1. إصلاح ملفات التكوين عن طريق إزالة التوجيهات القديمة.
  2. تحقق من التوافق مع الأدوات المساعدة.
  3. تحديث قواعد بيانات الرقيق عن طريق تثبيت الحزمة percona-server-server.
  4. قم بتحديث المعالج بوضع نفس الحزمة.

سنقوم بتحليل كل عنصر في الخطة ونرى ما يمكن أن يحدث بشكل خاطئ.

مهم! يحتوي إجراء ترقية كتلة MySQL المستندة إلى Galera على التفاصيل الدقيقة الخاصة به التي لم يتم وصفها في المقالة. لا يجب استخدام هذه التعليمات في هذه الحالة.

الجزء 1: التحقق من Configs


في الإصدار 8 ، تمت إزالة MySQL query_cache. في الواقع ، تم الإعلان عن أنه عفا عليه الزمن في الإصدار 5.7 ، ولكن الآن تم حذفه بالكامل . وبالتالي ، من الضروري إزالة التوجيهات ذات الصلة. وللتخزين المؤقت للاستعلامات ، يمكنك الآن استخدام أدوات خارجية - على سبيل المثال ، ProxySQL .

تم العثور أيضًا على توجيهات احترافية قديمة في التهيئة innodb_file_format. إذا كان من الممكن في MySQL 5.7 تحديد تنسيق InnoDB ، فإن الإصدار الثامن يعمل بالفعل فقط مع تنسيق Barracuda .

نتيجتنا هي إزالة التوجيهات التالية:

  • query_cache_type، query_cache_limitو query_cache_size.
  • innodb_file_formatو innodb_file_format_max.

للتحقق سنستخدم صورة Docker لخادم Percona. سنضع تكوين الخادم في الدليل mysql_config_test، ثم ننشئ أدلة للبيانات والسجلات. مثال على اختبار تهيئة خادم بيركونا:

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

النتيجة: إما في سجلات 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: التحقق من عمليات التثبيت الجارية


هناك مساعدتان في وثائق التحديث للتحقق من توافق قاعدة البيانات. يساعد استخدامها المسؤول على التحقق من توافق بنية البيانات الموجودة.

لنبدأ مع الأداة المساعدة mysqlcheck الكلاسيكية. ببساطة قم بتشغيل:

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

إذا لم يتم الكشف عن أي مشاكل ، سيتم إنهاء الأداة برمز 0:



بالإضافة إلى ذلك ، تتوفر الأداة المساعدة mysql-shell في الإصدارات الحديثة من MySQL (في حالة Percona ، هذه حزمة percona-mysql-shell). وهو بديل لعميل mysql الكلاسيكي ويجمع بين وظائف العميل ومحرر SQL وأدوات إدارة MySQL. للتحقق من الخادم قبل التحديث ، يمكنك تشغيل الأوامر التالية من خلاله:

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

وإليك التعليقات التي تلقيناها:



بشكل عام ، لا شيء مهم - مجرد تحذيرات حول الترميزات (انظر أدناه) . النتيجة الإجمالية للتنفيذ:



قررنا أن التحديث يجب أن يمر دون مشاكل.

ملاحظة على التحذيرات أعلاه تشير إلى مشاكل الترميز. والحقيقة هي أن UTF-8 في MySQL حتى وقت قريب لم يكن UTF-8 "حقيقيًا" ، حيث تم تخزين 3 بايت فقط بدلاً من 4. في MySQL 8 ، قرروا أخيرًا إصلاحه : utf8سيؤدي الاسم المستعار قريبًا إلى التشفير utf8mb4، والأخرى القديمة ستصبح الأعمدة في الجداول utf8mb3. في المستقبل ، utf8mb3سيتم حذف الترميز ، ولكن ليس في هذا الإصدار. لذلك ، قررنا إصلاح الترميزات بالفعل على تثبيت عمل لنظام DBMS ، بعد تحديثه.

الجزء 3: تحديثات الخادم


ما الذي يمكن أن يحدث بشكل خاطئ عند وجود مثل هذه الخطة الأنيقة؟ .. ندرك جيدًا أن الفروق الدقيقة تحدث دائمًا ، فقد أجرينا أول تجربة على مجموعة تطوير MySQL.

كما ذكرنا من قبل ، فإن الوثائق الرسمية تسلط الضوء على مسألة تحديث خوادم MySQL مع النسخ المتماثلة. خلاصة القول هي أن الأمر يستحق في البداية تحديث جميع النسخ المتماثلة (العبيد) ، حيث يمكن لـ MySQL 8 النسخ المتماثل من معالج الإصدار 5.7. تكمن بعض الصعوبات في حقيقة أننا نستخدم الوضع الرئيسي <-> الرئيسي عندما يكون الرئيسي البعيد في وضع القراءة فقط . هذا ، في الواقع ، تدخل حركة المرور إلى مركز بيانات واحد ، والثاني هو النسخ الاحتياطي.

الطبولوجيا كما يلي:



يجب أن تبدأ الترقية مع النسخ المتماثلة الخلية 2 نسخة متماثلة، mysql master dc 2 and mysql replica dc 1، وينتهي الأمر بخادم mysql master dc 1. من أجل موثوقية أفضل ، أوقفنا الأجهزة الافتراضية ، وقمنا بعمل لقطات لها ، وأوقفنا النسخ المتماثل بالأمر قبل التحديث مباشرة STOP SLAVE. يبدو باقي التحديث كما يلي:

  1. يتم إعادة تشغيل كل نسخة متماثلة ، مع إضافة خيار التكوين 3: skip-networking، skip-slave-start، skip-log-bin. الحقيقة هي أن تحديث قاعدة البيانات يولد سجلات ثنائية مع تحديث جداول النظام. تضمن هذه التوجيهات أنه لن تكون هناك تغييرات على بيانات التطبيق في قاعدة البيانات ، ولن تدخل المعلومات المتعلقة بتحديث جداول النظام في السجلات الثنائية. سيؤدي هذا إلى تجنب المشاكل عند استئناف النسخ المتماثل.
  2. قم بتثبيت الحزمة percona-server-server. من المهم ملاحظة أنه في MySQL 8 ، لا تحتاج إلى تشغيل الأمر mysqlupgradeبعد تحديث الخادم.
  3. بعد بداية ناجحة ، أعد تشغيل الخادم مرة أخرى - بالفعل بدون المعلمات التي تمت إضافتها في الفقرة الأولى.
  4. نتأكد من عمل النسخ المتماثل بنجاح: نتحقق 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:

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',
...

إذا كان field_typeلديك 0 ، فسيتم استخدام النوع القديم في الجدول - يجب القيام به OPTIMIZE. ومع ذلك ، إذا كانت القيمة 246 ، فلديك بالفعل نوع جديد. يمكن العثور على مزيد من المعلومات حول الأنواع في التعليمات البرمجية .

علاوة على ذلك ، يعتبر هذا الخطأ السبب المحتمل الثاني الذي تجاوزنا - عدم وجود جداول InnoDB في جدول النظام INNODB_SYS_TABLESPACES، إذا تم إنشاؤها ، الجداول ، في الإصدار 5.1. لتجنب المشاكل أثناء الترقية ، يمكنك استخدام برنامج SQL النصي المرفق .

لماذا لم يكن لدينا مثل هذه المشاكل في ديف؟ يتم نسخ القاعدة بشكل دوري هناك من الإنتاج - وبالتالي ، يتم إعادة إنشاء الجداول .

لسوء الحظ ، في قاعدة بيانات كبيرة تعمل حقًا ، لن تعمل فقط لأخذ وأداء قاعدة البيانات الموجودة في كل مكان OPTIMIZE. ستساعد أداة Percona-toolkit هنا: تعتبر أداة pt-online-schema-change أداة ممتازة لتشغيل OPTIMIZE عبر الإنترنت.

كانت الخطة المحدثة على النحو التالي:

  1. تحسين جميع الجداول.
  2. قم بإجراء ترقية لقاعدة البيانات.

للتحقق من ذلك وفي نفس الوقت لمعرفة وقت التحديث ، قمنا بتعطيل إحدى النسخ المتماثلة ، وبالنسبة لجميع الجداول ، قمنا بتشغيل الأمر التالي:

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

يتم تحديث الجداول بدون أقفال طويلة نظرًا لأن الأداة تقوم بإنشاء جدول مؤقت جديد تقوم بنسخ البيانات من الجدول الرئيسي. في الوقت الذي يكون فيه كلا الجدولين متطابقين ، يتم تأمين الجدول الأصلي واستبداله بآخر جديد. في حالتنا ، أظهر التشغيل التجريبي أن تحديث جميع الجداول سيستغرق حوالي يوم ، ولكن نسخ البيانات تسبب في تحميل الكثير على الأقراص.

لتجنب ذلك ، أضفنا وسيطة --sleepبقيمة 10 إلى الأمر عند الإنتاج - تتحكم هذه المعلمة في طول الانتظار بعد نقل حزمة بيانات إلى جدول جديد. بهذه الطريقة يمكنك تقليل الحمل إذا كان التطبيق الذي يعمل بالفعل يطالب بوقت الاستجابة.

بعد إجراء التحسين ، كان التحديث ناجحًا.

... لكن ليس بالكامل!


بعد نصف ساعة من التحديث ، واجه العميل مشكلة. عملت القاعدة بشكل غريب للغاية: بشكل دوري ، بدأت قطرات الاتصال . إليك ما بدا عليه في المراقبة:



يظهر الرسم البياني المنشار في لقطة الشاشة ، ويرجع ذلك إلى حقيقة أن جزءًا من سلاسل خادم MySQL قد سقط بشكل دوري مع وجود خطأ. ظهرت أخطاء في التطبيق:

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

كشف فحص سريع للسجلات أن البرنامج الخفي لم يستطع الحصول على الموارد المطلوبة من نظام التشغيل. أثناء التعامل مع الأخطاء ، وجدنا في نظام ملفات النظام "اليتيم" :

# 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 حل المشكلة:

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

أخيرا


أي ، حتى أبسط عملية ، يمكن أن يؤدي إلى مشاكل غير متوقعة. وحتى وجود خطة مدروسة جيدًا لا يضمن دائمًا النتيجة المتوقعة. الآن ، في أي خطط تحديث ، يتضمن فريقنا أيضًا التنظيف الإلزامي للملفات الإضافية التي يمكن أن تظهر نتيجة الإجراءات الأخيرة.

ومع هذا العمل الرسومي غير المحترف ، أود أن أشكر بيركونا على منتجاتها الرائعة!



ملاحظة


اقرأ أيضا في مدونتنا:


All Articles