به روز رسانی MySQL (سرور Percona) از 5.7 به 8.0

به روز رسانی MySQL (سرور Percona) از 5.7 به 8.0

پیشرفت ثابت نمی ماند، بنابراین دلایل ارتقاء به آخرین نسخه های MySQL به طور فزاینده ای قانع کننده می شوند. چندی پیش، در یکی از پروژه های ما، زمان به روز رسانی خوشه های دلپذیر Percona Server 5.7 به نسخه 8 فرا رسیده بود. همه اینها در پلتفرم Ubuntu Linux 16.04 اتفاق افتاد. چگونه می توان چنین عملیاتی را با حداقل خرابی انجام داد و در طول به روز رسانی با چه مشکلاتی مواجه شدیم - در این مقاله بخوانید.

پرورش

هر به روز رسانی سرور پایگاه داده به احتمال زیاد با پیکربندی مجدد پایگاه داده مرتبط است: تغییرات در الزامات محدودیت در منابع سیستم و اصلاح تنظیمات پایگاه داده که باید از دستورالعمل های قدیمی پاک شوند.

قبل از به روز رسانی، ما قطعا به اسناد رسمی مراجعه خواهیم کرد:

و بیایید یک برنامه عملیاتی ترسیم کنیم:

  1. فایل های پیکربندی را با حذف دستورالعمل های قدیمی تصحیح کنید.
  2. بررسی سازگاری با برنامه های کاربردی
  3. پایگاه داده های برده را با نصب بسته به روز کنید percona-server-server.
  4. Master را با همین پکیج آپدیت کنید.

بیایید به هر نقطه از طرح نگاه کنیم و ببینیم چه چیزی ممکن است اشتباه باشد.

مهم! روش به روز رسانی یک خوشه MySQL بر اساس Galera ظرافت های خاص خود را دارد که در مقاله توضیح داده نشده است. در این مورد نباید از این دستورالعمل استفاده کنید.

قسمت 1: بررسی تنظیمات

MySQL در نسخه 8 حذف شد 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و در کنار آن دایرکتوری هایی برای داده ها و گزارش ها ایجاد می کنیم. مثال تست پیکربندی سرور 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: بررسی تاسیسات کاری

اسناد به روز رسانی شامل 2 ابزار برای بررسی سازگاری پایگاه داده است. استفاده از آنها به مدیر کمک می کند تا سازگاری ساختار داده موجود را بررسی کند.

بیایید با ابزار کلاسیک mysqlcheck شروع کنیم. به سادگی اجرا کنید:

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

اگر مشکلی پیدا نشد، ابزار با کد 0 خارج می شود:

به روز رسانی MySQL (سرور Percona) از 5.7 به 8.0

علاوه بر این، یک ابزار در نسخه های مدرن MySQL موجود است mysql-shell (در مورد 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 (سرور Percona) از 5.7 به 8.0

به طور کلی، هیچ چیز مهمی نیست - فقط هشدارهایی در مورد رمزگذاری ها (پایین را ببینید). نتیجه اجرای کلی:

به روز رسانی MySQL (سرور Percona) از 5.7 به 8.0

ما تصمیم گرفتیم که به روز رسانی باید بدون مشکل انجام شود.

یادداشتی در مورد هشدارهای بالا که نشان دهنده مشکلات مربوط به رمزگذاری است. واقعیت این است که UTF-8 در MySQL تا همین اواخر UTF-8 "درست" نبوداز آنجایی که به جای 3 بایت فقط 4 بایت ذخیره می کرد. در MySQL 8 این در نهایت است تصمیم گرفت آن را تعمیر کند: نام مستعار utf8 به زودی به کدنویسی منجر خواهد شد utf8mb4، و ستون های قدیمی در جداول تبدیل می شوند utf8mb3. رمزگذاری بیشتر utf8mb3 حذف خواهد شد، اما نه در این نسخه. بنابراین، تصمیم گرفتیم پس از به‌روزرسانی، کدگذاری‌های موجود در نصب DBMS در حال اجرا را تصحیح کنیم.

بخش 3: به روز رسانی سرور

وقتی چنین طرح هوشمندی وجود دارد، چه اشتباهی ممکن است پیش بیاید؟... با درک کامل این موضوع که تفاوت های ظریف همیشه اتفاق می افتد، اولین آزمایش را بر روی یک خوشه توسعه دهنده MySQL انجام دادیم.

همانطور که قبلاً ذکر شد ، اسناد رسمی موضوع به روز رسانی سرورهای MySQL با کپی را پوشش می دهد. نکته اصلی این است که ابتدا باید همه کپی ها (برده ها) را به روز کنید، زیرا MySQL 8 می تواند از نسخه اصلی 5.7 کپی کند. برخی از مشکلات در این واقعیت نهفته است که ما از حالت استفاده می کنیم استاد استاد، هنگامی که کنترل از راه دور در حالت است فقط خواندنی. یعنی در واقع، ترافیک جنگی به یک مرکز داده می رود و مرکز دوم پشتیبان است.

توپولوژی به شکل زیر است:

به روز رسانی MySQL (سرور Percona) از 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. ذکر این نکته ضروری است که در 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

تحقیق در آرشیو لیست های پستی مختلف در گوگل به این درک منجر شد که این مشکل به دلیل اشکال 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 پیوست شده است.

چرا ما چنین مشکلاتی را در dev نداشتیم؟ پایگاه داده به صورت دوره ای از زمان تولید در آنجا کپی می شود - بنابراین، جداول بازسازی می شوند.

متأسفانه، در یک پایگاه داده بزرگ واقعاً کار می کند، شما نمی توانید فقط یک یونیورسال را بگیرید و اجرا کنید OPTIMIZE. percona-toolkit در اینجا کمک خواهد کرد: ابزار pt-online-schema-change برای عملیات بهینه سازی آنلاین بسیار عالی است.

طرح به روز شده به این شکل بود:

  1. بهینه سازی تمام جداول
  2. پایگاه های داده را به روز کنید.

برای بررسی آن و در عین حال اطلاع از زمان به روز رسانی، یکی از Replica ها را غیرفعال کردیم و دستور زیر را برای همه جداول اجرا کردیم:

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 (سرور Percona) از 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 ایجاد شدند و متعلق به یک بسته حذف شده هستند. با حذف فایل ها و راه اندازی مجدد سرویس 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

در نتیجه

هر گونه عملیات، حتی ساده ترین، می تواند منجر به مشکلات غیر منتظره شود. و حتی داشتن یک برنامه سنجیده همیشه نتیجه مورد انتظار را تضمین نمی کند. اکنون، هر برنامه به‌روزرسانی تیم ما شامل پاکسازی اجباری فایل‌های غیرضروری است که ممکن است در نتیجه اقدامات اخیر ظاهر شده باشند.

و با این خلاقیت گرافیکی نه چندان حرفه ای، می خواهم از پرکونا به خاطر محصولات عالیشان تشکر فراوان کنم!

به روز رسانی MySQL (سرور Percona) از 5.7 به 8.0

PS

در وبلاگ ما نیز بخوانید:

منبع: www.habr.com

اضافه کردن نظر