Восстановление бэкапа от mysql 5.5 на mysql 5.7

По работе возникла у меня необходимость восстановить дамп базы от 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 и она должна отработать успешно.

Tags: linuxmysql
admin:
Related Post