panelarrow

Сайт обо всём по-немногу

Сайт обо всём по-немногу

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

| 0 comments

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

Leave a comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *