
لقد قمنا مؤخرًا بترقية خوادمنا من MySQL 5.7 إلى 8.0.
دعونا نترك خارج نطاق هذا المقال لماذا وما هي الكعك الجديد الذي ظهر في MySQL 8.0 ، ولكن بدلاً من ذلك سنتحدث عن الصعوبات التي واجهناها أثناء عملية الترقية.
أولاً ، قبل التحديث ، يجدر النظر إلى
قائمة التغييرات وتصحيح ملف التكوين الخاص بك.
كحد أدنى ، تم حذف الخيارات التالية:
innodb_file_format ، innodb_file_format_check ، innodb_file_format_max ، innodb_large_prefix
query_cache_limit ، query_cache_min_res_unit ، query_cache_size ، query_cache_type ، query_cache_wlock_invalidate.
في المعلمة sql_mode ، على وجه الخصوص ، تم حذف NO_AUTO_CREATE_USER - وهو أمر مهم بشكل خاص ، لأن في MySQL 5.7 ، تم تشغيله افتراضيًا.
بيركونا لديه تعليمات للترقية في المكان. وفي الحالة العامة ، يمكنك متابعته ، ومع ذلك ، تمكنا من تحديث كتلة واحدة فقط بهذه الطريقة ؛ أما بالنسبة للباقي ، فشلت محاولة تحديث هذا بسبب خطأ مشابه:
2019-06-22T05:04:18.510888Z 1 [ERROR] [MY-011014] [Server] Found partially upgraded DD. Aborting upgrade and deleting all DD tables. Start the upgrade process again. 2019-06-22T05:04:23.115018Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed. 2019-06-22T05:04:23.115655Z 0 [ERROR] [MY-010119] [Server] Aborting
لذلك ، قمنا بتحديث الكتل المتبقية عن طريق رفع نسخة فارغة جديدة واستعادة تفريغ قاعدة البيانات من الإصدار السابق.
للقيام بذلك ، أولاً ، تحتاج إلى تفريغ قاعدة بيانات. وهنا الخطر # 1 ينتظر - تفريغ مصنوع بالطريقة القياسية:
mysqldump -u root -p --hex-blob --default-character-set=utf8mb4 --all-databases --triggers --routines --events > dump.sql
لا يسترد إعطاء خطأ:
ERROR 3554 (HY000) at line 15915: Access to system table 'mysql.innodb_index_stats' is rejected.
الوصف موجود
في MySQL bugtracker (مع الحالة Not a bug :) ، هناك أيضًا نصيحة حول كيفية التفريغ بحيث يمكن استعادته:
mysqldump -u root -p --hex-blob --default-character-set=utf8mb4 --all-databases --triggers --routines --events --ignore-table=mysql.innodb_index_stats --ignore-table=mysql.innodb_table_stats > dump.sql
ولكن عند محاولة استخدام مثل هذا التفريغ ، إذا كانت هناك مشغلات فيه (وكان لدينا) ، يمكن توقع الخطر رقم 2 ، في شكل مثل هذا الخطأ:
ERROR 1231 (42000) at line 54: Variable 'sql_mode' can't be set to the value of 'NO_AUTO_CREATE_USER'
سبب ذلك هو أن MySQL يستخدم sql_mode للمشغلات ، وهي: MySQL يحفظ قيمة sql_mode للمشغل في وقت إنشائه ثم ينفذها دائمًا بتلك القيمة. وبناء عليه ، يحفظ هذه القيمة في تفريغ.
وصف المساعدة لهذا:
dev.mysql.com/doc/refman/8.0/en/create-trigger.html
يقوم MySQL بتخزين إعداد متغير النظام sql_mode ساري المفعول عند إنشاء المشغل ، ويقوم دائمًا بتنفيذ نص المشغل مع هذا الإعداد المعمول به ، بصرف النظر عن وضع SQL للخادم الحالي عندما يبدأ المشغل في التنفيذ.
ماذا نفعل؟ لقد قمنا فقط بقص NO_AUTO_CREATE_USER من التفريغ النهائي. قيادة مماثلة:
sed "s/50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER/50003 SET sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO/g" dump.sql > dump2.sql
بعد ذلك ، يتم استعادة التفريغ بنجاح ، ولكن الخطر رقم 3 ينتظرنا (الحقيقة المتوقعة تمامًا) - تتم استعادة جداول النظام إلى الحالة من الإصدار 5.7 ولدينا الأخطاء التالية في السجلات:
[ERROR] [MY-013143] [Server] Column count of mysql.user is wrong. Expected 51, found 45. The table is probably corrupted
من تجربة الإصدارات السابقة ، يتم التعامل مع هذا عن طريق تشغيل mysql_upgrade - لكن منذ الإصدار 8.0.16 - هذا لا يعمل ، لأن أعلن mysql_upgrade إهمال ولا يفعل أي شيء.
الآن ، لكي يتم تحديث جداول النظام ، يجب عليك تشغيل MySQL مع
ترقية الخيار
= FORCE .
على أوبونتو الطازجة ، يمكن القيام بذلك على النحو التالي:
systemctl set-environment MYSQLD_OPTS="--upgrade=FORCE"
ثم أعد تشغيل MySQL. حسنًا ، بعد التحديث الناجح ، احذفه:
systemctl unset-environment MYSQLD_OPTS