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

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

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

تدريب

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

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

لنضع خطة عمل:

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

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

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

الجزء 1: التحقق من التكوينات

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

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

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

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

للتحقق ، سوف نستخدم صورة Percona Server Docker. سيتم وضع تكوين الخادم في الدليل mysql_config_test، وبعد ذلك سننشئ أدلة للبيانات والسجلات. مثال على اختبار تكوين خادم 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

خلاصة القول: إما في سجلات 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 (خادم بيركونا) من 5.7 إلى 8.0

بالإضافة إلى ذلك ، تتوفر الأداة المساعدة في الإصدارات الحديثة من MySQL. قذيفة 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

هذه هي التعليقات التي تلقيناها:

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

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

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

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

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

الجزء 3: ترقية الخوادم

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

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

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

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

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

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

يبدو كل شيء بسيطًا بدرجة كافية: لقد نجح تحديث dev. حسنًا ، يمكنك بأمان جدولة تحديث ليلي للإنتاج.

لم يكن هناك حزن - قمنا بتحديث المنتج

ومع ذلك ، لم يكن نقل تجربة التطوير الناجحة إلى الإنتاج بدون مفاجآت.

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

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 مفيدة: بالنسبة لعملية OPTIMIZE عبر الإنترنت ، تعد الأداة المساعدة لتغيير المخطط pt-online-schema رائعة.

الخطة المحدثة هي كما يلي:

  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 (خادم بيركونا) من 5.7 إلى 8.0

تُظهر لقطة الشاشة رسمًا بيانيًا مسننًا نظرًا لحقيقة أن بعض سلاسل عمليات خادم MySQL تتعطل بشكل دوري مع وجود خطأ. التطبيق به أخطاء:

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

كشفت نظرة سريعة على السجلات أن البرنامج الخفي mysqld لم يتمكن من الحصول على الموارد المطلوبة من نظام التشغيل. التعامل مع الأخطاء وجدنا في النظام ملفات سياسة 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 قبل عامين وتنتمي إلى حزمة تمت إزالتها. أدى حذف الملفات وإعادة تشغيل خدمة التطبيقات إلى حل المشكلة:

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

في الختام

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

ومع هذا التصميم الجرافيكي غير الاحترافي للغاية ، أود أن أقول شكراً جزيلاً لشركة Percona على منتجاتها الممتازة!

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

PS

اقرأ أيضًا على مدونتنا:

المصدر: www.habr.com

إضافة تعليق