По работе возникла у меня необходимость восстановить дамп базы от Percona mysql версии 5.5 на сервере с Percona mysql 5.7. При восстановлении дампа в sql-файле никаких проблем я думаю не возникло бы, но база была большой, поэтому дамп был сделан с помощью xtrabackup'а.
После установки сервера новой версии и выкладывания дата файлов, сервер БД успешно запустился. Единственное, что мне пришлось в базу mysql заменить файлы таблицы User — мастер сервер админился не мной, и для доступ к БД мне нужен был мой пользователь.
А вот далее начались проблемы — на команду изменить/добавить пользователя, настроить подключение слейва к мастеру, mysql выдавал ошибку:
1 | ERROR 1728 (HY000): Cannot load from mysql.db. The table is probably corrupted |
Понятно почему возникла ошибка — я в новую версию БД подсунул системную БД mysql от старой версии. Для этого в общем-то есть решение — команда mysql_upgrade. Но, при её запуске она выдавала ошибку:
1 2 3 4 | ~#mysql_upgrade --upgrade-system-tables Checking if update is needed. Checking server version. Error occurred: The mysql.session exists but is not correctly configured. The mysql.session needs SELECT privileges in the performance_schema database and the mysql.db table and also SUPER privileges. |
При своём запуске, команда проверяет разные доступы, и если их нет — то отказывается запускаться. В общем-то всё, что ей требуется она выводит в сообщении. Теперь это надо проверить и добавить всё, что отсутствует.
Сначала необходимо проверить, что присутствует пользователь mysql.session, и он должен присутствовать в единственном числе, т.е. пользователь с разрешённым хостом localhost.
1 2 3 4 5 6 7 8 9 | mysql> SELECT user,host FROM user WHERE User='mysql.session'; +---------------+-----------+ | user | host | +---------------+-----------+ | mysql.session | localhost | +---------------+-----------+ 1 row in set (0,00 sec) mysql> |
Как видно выше — у меня это условие выполняется. Делаем проверки дальше.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | mysql> SELECT * FROM user WHERE Super_priv='Y' and User='mysql.session'\G *************************** 1. row *************************** Host: localhost User: mysql.session Select_priv: N Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N Reload_priv: N Shutdown_priv: N Process_priv: N File_priv: N Grant_priv: N References_priv: N Index_priv: N Alter_priv: N Show_db_priv: N Super_priv: Y Create_tmp_table_priv: N Lock_tables_priv: N Execute_priv: N Repl_slave_priv: N Repl_client_priv: N Create_view_priv: N Show_view_priv: N Create_routine_priv: N Alter_routine_priv: N Create_user_priv: N Event_priv: N Trigger_priv: N Create_tablespace_priv: N ssl_type: ssl_cipher: x509_issuer: x509_subject: max_questions: 0 max_updates: 0 max_connections: 0 max_user_connections: 0 plugin: mysql_native_password authentication_string: *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE password_expired: N password_last_changed: 2021-12-24 10:56:17 password_lifetime: NULL account_locked: Y 1 row in set (0,00 sec) mysql> |
Как видно выше — привилегия SUPER у пользователя mysql.session есть. Если запрос ничего не возвращает, тогда стоит попробовать выполнить его без условия Super_priv='Y' и проверить, есть ли запись в таблице для этого пользователя. Если её нет, то стоит попробовать её добавить с помощью команды:
1 | GRANT SUPER ON *.* TO 'mysql.session'@'localhost'; |
Если и на её выполнение будет ошибка — тогда стоит попробовать добавить запись с помощью простого insert into. У меня такая запись присутствует, делаю проверку дальше.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | mysql> SELECT * FROM db WHERE Select_priv='Y' and User='mysql.session' and Db='performance_schema'\G *************************** 1. row *************************** Host: localhost Db: performance_schema User: mysql.session Select_priv: Y Insert_priv: N Update_priv: N Delete_priv: N Create_priv: N Drop_priv: N Grant_priv: N References_priv: N Index_priv: N Alter_priv: N Create_tmp_table_priv: N Lock_tables_priv: N Create_view_priv: N Show_view_priv: N Create_routine_priv: N Alter_routine_priv: N Execute_priv: N Event_priv: N Trigger_priv: N 1 row in set (0,00 sec) mysql> |
Доступ на SELECT из базы performance_schema у меня присутствовал. Если его нет, то надо добавить с помощью команды:
1 | GRANT SELECT ON `performance_schema`.* TO 'mysql.session'@'localhost'; |
Или если она не работает — то с помоью ubsert into db.
Третьей проверкой смотрим, есть ли у пользователя mysql.session доступ к таблице User базы mysql:
1 | SELECT * FROM tables_priv WHERE Table_priv='Select' and User='mysql.session' and Db='mysql' and Table_name='user' |
И вот его то у меня в базе прописано не было. Попробовал его добавить с помощью команды
1 | GRANT SELECT ON `mysql`.`db` TO 'mysql.session'@'localhost'; |
И нифига — mysql отказался выполнять команду. Пришлось писать и выполнять SQL-запрос:
1 | INSERT INTO mysql.tables_priv (`Host`, `Db`, `User`, `Table_name`, `Grantor`, `Table_priv`) values ('localhost', 'mysql', 'mysql.session', 'user', CURRENT_USER, 'Select'); |
Запрос выпролнился успешно:
1 2 3 4 5 6 7 8 9 10 11 12 13 | mysql> SELECT * FROM tables_priv WHERE Table_priv='Select' and User='mysql.session' and Db='mysql' and Table_name='user'\G *************************** 1. row *************************** Host: localhost Db: mysql User: mysql.session Table_name: user Grantor: boot@connecting host Timestamp: 0000-00-00 00:00:00 Table_priv: Select Column_priv: 1 row in set (0,00 sec) mysql> |
Вот теперь можно пробовать выполнять mysql_upgrade --upgrade-system-tables и она должна отработать успешно.