Постоянно возникали нюансы при изменении рабочей директории MySQL на отличную от /var/lib/mysql, поэтому решил описать все подводные камни, с которыми сталкивался. Обычно всё возникало после переноса БД с одного сервера на другой.
После установки MySQL (использовал версию 5.7), понадобилось сменить рабочую директорию на /home/mysql, алгоритм таков:
1 ) Остановить процесс:
systemctl stop mysqld
2) Создать новую директорию под файлы, задать права и владельца:
mkdir /home/mysql && chown mysql:mysql /home/mysql && chmod 755 /home/mysql
3) Перенести файлы в новую директорию (проверить права на директорию после копирования):
rsync -av /var/lib/mysql /home/mysql
4) В конфиге MySQL поправить строки вида, указав новый путь:
datadir=/home/mysql
socket=/home/mysql/mysql.sock
5) Запустить сервис. По идее должно подхватить и корректно запуститься, но в моём случае были не совсем понятные ошибки, из лога /var/log/mysqld.log было понятно лишь, что pid-file=/var/run/mysqld/mysqld.pid отсутствовал, а он должен там создаваться при запуске, ну и сокет, соответственно, тоже отсутствовал. Плюс было предложение запустить mysql_update, но выдавало access denied для рута при запуске.
Но если пути вернуть на исходные, то сервис MySQL стартовал.
6) Данный пункт родился после следующей последовательности действий:
– тормозим сервис
– в конфиг добавляем исходные пути к /var/lib/mysql, а также:
skip-grant-tables
в раздел mysqld, чтобы иметь доступ к базе без проверки привилегий,
7) Теперь нужно ввести команду mysql_update, и повторить пункты с 1 по 5, то есть снова меняем пути на новые и стартуем сервис – должно помочь.
Но после этого в лог посыпались ошибки типа Table mysql.user doesn’t exist. Сервер стартовал, но стоит нам убрать skip-grant-tables из конфига, как всё ломается и не стартует – и правильно, т.к. данная строчка пропускает таблицы (которых у нас нет), и дает зацепиться к консоли MySQL.
Причина этому, что MySQL не видит нужные таблицы, т.к. они просто отсутствуют. Для исправления нужно провести инициализацию. Тормозим сервис, очищаем папку /home/mysql, если в my.cnf прописаны data_dir и путь к сокету, то сразу запускаем:
/usr/sbin/mysqld --defaults-file=/etc/my.cnf \
--initialize --user=mysql
Если директория с mysql не будет пустая, то на выходе получите ошибку
[ERROR] --initialize specified but the data directory exists. Aborting.
Можно также запустить инициализацию так:
/usr/sbin/mysqld --defaults-file=/etc/my.cnf \
--initialize-insecure --user=mysql
и тогда получим пароль новой созданной учётки рута в незащищенном виде.
Также в случаях поломки БД, есть мануалы с командой mysql_install_db, но она устарела и на сайте MySQL можно почитать подробно про опцию –initialize, которая интегрирована уже в сервер MySQL. Собственно, она всё и починила, создав новую правильную структуру таблиц.
9) Теперь сервис успешно стартовал, в логах нет ошибок, и в /etc/my.cnf также нужно добавить:
[client]
port = 3306
socket = /home/mysql/mysql.sock
чтобы клиент mysql знал, что сокет лежит теперь по новому пути.
10) Если была использована опция –initialize, то необходимо создать пароль рута, вводим команду mysql и далее:
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY '8aA41JiZ9k';
В /etc/my.cnf нужно убрать skip-grant-tables, и проверить, что вход теперь по паролю успешен:
mysql -uroot -p
Для удобства можно прописать в /root/.my.cnf строки:
[client]
password=your_pass
и пароль не будет запрашиваться каждый раз, а командой
mysql --defaults-file=/root/.my.cnf
можно указывать расположение файла.