Прежде чем сбрасывать пароль root, проверьте, нужен ли он вообще. В Debian, Ubuntu и AlmaLinux пользователь root в MariaDB 10.4+ по умолчанию входит через сокет, без пароля: достаточно выполнить sudo mysql или sudo mariadb. В MySQL 8 из репозиториев Ubuntu root настроен так же, через плагин auth_socket. Если этот вход работает, пароль меняется одной командой ALTER USER, без остановки сервера.
Если сокетный вход отключён, а пароль потерян, используется классический способ. Сервер запускают с --skip-grant-tables --skip-networking, подключаются без пароля, выполняют FLUSH PRIVILEGES, затем ALTER USER, и возвращают обычный запуск. На системах с systemd опции передают через drop-in файл или переменную MYSQLD_OPTS, а не через mysqld_safe.
Старый рецепт UPDATE user SET password=PASSWORD(...) на MySQL 8 и MariaDB 10.4+ не работает. Ниже — порядок действий для MySQL 8.0/8.4 и MariaDB 10.11/11.x на Debian 12/13, Ubuntu 24.04 и AlmaLinux / Rocky Linux 9 и 10.
Шаг 0. Как у вас входит root
Попробуйте зайти от системного root:
sudo mysql # MySQL или MariaDB
sudo mariadb # MariaDB 10.11 и 11.x
Если появилось приглашение mysql> или MariaDB [(none)]>, сбрасывать ничего не нужно. Посмотрите, как настроен root:
-- MySQL 8
SELECT user, host, plugin FROM mysql.user WHERE user = 'root';
-- MariaDB 10.4+
SHOW CREATE USER root@localhost;
Примерно так выглядит ответ в MariaDB на Debian:
CREATE USER `root`@`localhost` IDENTIFIED VIA mysql_native_password
USING 'invalid' OR unix_socket
Это значит: пароль для root фактически не задан (invalid не совпадёт ни с одним хешем), а войти можно через сокет.
| Система и СУБД | Как root входит по умолчанию | Как попасть в базу |
|---|---|---|
| Debian 12/13, MariaDB 10.11 / 11.8 | unix_socket | sudo mariadb |
| Ubuntu 24.04, MariaDB 10.11 | unix_socket | sudo mariadb |
| Ubuntu 24.04, MySQL 8.0 | auth_socket | sudo mysql |
| AlmaLinux / Rocky 9 и 10, MariaDB | unix_socket | sudo mysql |
| AlmaLinux / Rocky, MySQL из AppStream | пароль пустой, пока его не задали | mysql -u root |
| MySQL из репозитория Oracle (RPM) | временный пароль | sudo grep 'temporary password' /var/log/mysqld.log |
Почему root входит без пароля и это безопасно
Плагины unix_socket в MariaDB и auth_socket в MySQL проверяют не пароль, а того, кто подключился к сокету. Ядро сообщает серверу UID процесса на другом конце сокета. Если системный пользователь называется так же, как пользователь базы, вход разрешён. Подделать это из-под непривилегированного пользователя нельзя.
Получается, что доступ к root в базе есть только у того, кто уже root в системе. А тот, кто root в системе, и так может остановить сервер и прочитать файлы данных. Пароль здесь защиты не добавляет, зато появляется лишний секрет, который можно потерять или засветить в скрипте.
Отсюда практичная схема: root оставить на сокете, а для phpMyAdmin, бэкапов по сети и приложений создать отдельных пользователей с паролями и минимальными правами. Что ещё проверить после установки, описано в статье Настройка минимальной безопасности MySQL после установки.
В Ubuntu с MySQL есть ещё служебная учётка debian-sys-maint. Её пароль лежит в /etc/mysql/debian.cnf, файл читает только root. Если сокетный вход для root сломан, можно попробовать войти через неё:
sudo mysql --defaults-file=/etc/mysql/debian.cnf
Если у этой учётки есть права на управление пользователями, пароль root меняется без перезапуска сервера.
Смена пароля, когда доступ есть
Если вы вошли через сокет и всё-таки хотите задать root пароль, сохраните при этом сокетный вход.
MariaDB 10.4 и новее:
ALTER USER root@localhost
IDENTIFIED VIA unix_socket
OR mysql_native_password USING PASSWORD('Новый_Сложный_Пароль');
MySQL 8.0 и 8.4. Один пользователь в MySQL имеет один основной способ входа, поэтому при смене на пароль вход через сокет пропадёт: дальше только mysql -u root -p.
ALTER USER 'root'@'localhost'
IDENTIFIED WITH caching_sha2_password BY 'Новый_Сложный_Пароль';
Не используйте на MySQL 8.4 IDENTIFIED WITH mysql_native_password. В 8.4 этот плагин по умолчанию отключён, и вы получите ошибку о незагруженном плагине. caching_sha2_password — плагин по умолчанию в MySQL 8, его поддерживают актуальные клиенты и PHP-расширения mysqli и pdo_mysql.
FLUSH PRIVILEGES после ALTER USER не нужен. Эта команда нужна только после прямой правки системных таблиц через UPDATE или INSERT, а так делать не стоит.
Полный сброс через —skip-grant-tables
Этот способ нужен, если сокетный вход отключён, а пароль никто не помнит. Пока сервер работает в таком режиме, любой локальный пользователь может войти в базу с полными правами. Поэтому сеть отключаем, а сам режим держим минимальное время.
1. Узнайте имя службы и строку запуска
systemctl list-units --type=service | grep -Ei 'mysql|mariadb'
systemctl cat mariadb | grep ^ExecStart # или mysql / mysqld
Имя службы: mariadb для MariaDB везде, mysql для MySQL в Debian и Ubuntu, mysqld для MySQL в AlmaLinux. Если в строке ExecStart есть $MYSQLD_OPTS, подойдёт вариант с переменной. Так устроена служба MariaDB и MySQL из пакетов Oracle. В Ubuntu строка MySQL выглядит просто как ExecStart=/usr/sbin/mysqld, переменную она не читает, и нужен drop-in файл.
2а. Вариант с MYSQLD_OPTS (MariaDB)
sudo systemctl stop mariadb
sudo systemctl set-environment MYSQLD_OPTS="--skip-grant-tables --skip-networking"
sudo systemctl start mariadb
2б. Вариант с drop-in файлом (MySQL в Ubuntu и всё остальное)
sudo systemctl stop mysql
sudo systemctl edit mysql
В открывшемся редакторе впишите строки. Путь к бинарнику возьмите из вывода systemctl cat:
[Service]
ExecStart=
ExecStart=/usr/sbin/mysqld --skip-grant-tables --skip-networking
Пустая строка ExecStart= обязательна: она сбрасывает исходную команду, иначе systemd откажется запускать службу с двумя командами. Сохраните файл и запустите службу:
sudo systemctl start mysql
sudo systemctl status mysql --no-pager
systemctl edit сам выполнит daemon-reload. Если создаёте файл /etc/systemd/system/mysql.service.d/override.conf руками, выполните sudo systemctl daemon-reload перед запуском.
3. Подключитесь и задайте пароль
sudo mysql # пароль не спросит
Порядок команд важен. В режиме --skip-grant-tables таблицы привилегий не загружены, и команды управления пользователями отключены. Если сразу выполнить ALTER USER, получите ошибку:
ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables
option so it cannot execute this statement
Сначала FLUSH PRIVILEGES загружает таблицы, затем ALTER USER работает:
FLUSH PRIVILEGES;
-- MySQL 8.0 / 8.4
ALTER USER 'root'@'localhost'
IDENTIFIED WITH caching_sha2_password BY 'Новый_Сложный_Пароль';
-- MariaDB 10.4+: пароль плюс сокет
ALTER USER root@localhost
IDENTIFIED VIA unix_socket
OR mysql_native_password USING PASSWORD('Новый_Сложный_Пароль');
Если пароль root вам не нужен, а нужно вернуть вход через сокет, хватит одной строки:
-- MariaDB
ALTER USER root@localhost IDENTIFIED VIA unix_socket;
-- MySQL в Ubuntu
ALTER USER 'root'@'localhost' IDENTIFIED WITH auth_socket;
Если FLUSH PRIVILEGES падает с ошибкой Table 'mysql.servers' doesn't exist, повреждены системные таблицы. Это отдельная проблема, она разобрана в статье Ошибка ERROR 1146 (42S02): Table ‘mysql.servers’ doesn’t exist.
4. Верните обычный запуск
Для варианта с переменной:
sudo systemctl stop mariadb
sudo systemctl unset-environment MYSQLD_OPTS
sudo systemctl start mariadb
Для drop-in файла:
sudo systemctl revert mysql
sudo systemctl restart mysql
systemctl revert удаляет все drop-in файлы службы в /etc/systemd/system. Если там были ваши собственные постоянные настройки, удалите только временный файл и выполните daemon-reload.
5. Проверьте
mysql -u root -p -e "SELECT CURRENT_USER(), @@skip_networking;"
Вход должен пройти с новым паролем, @@skip_networking — вернуться к прежнему значению. Обычно это 0; на серверах, где база слушает только сокет, — 1. Убедитесь, что без пароля посторонний пользователь не входит:
mysql -u root # от обычного пользователя: должно быть Access denied
Почему старый способ не работает
В старых статьях, включая прежнюю версию этой, пароль меняли прямой правкой таблицы:
UPDATE mysql.user SET password = PASSWORD('...') WHERE user = 'root';
- В MySQL 5.7 столбец
passwordпереименовали вauthentication_string. - В MySQL 8.0 удалена функция
PASSWORD(). Запрос даст синтаксическую ошибку. - В MariaDB 10.4+
mysql.user— представление (view) поверх таблицыmysql.global_priv. Менять пароль через UPDATE этой view нельзя.
Правильный инструмент во всех актуальных версиях — ALTER USER. Он сам выбирает плагин, считает хеш и обновляет привилегии в памяти.
Второй устаревший элемент — запуск mysqld_safe --skip-grant-tables вручную. На системах с systemd сервер управляется службой, а в пакетах MySQL для RPM-систем mysqld_safe вообще не входит. Ручной запуск в обход службы легко оставляет процесс от другого пользователя или без каталога для сокета /run/mysqld. Вариант через systemd надёжнее.
Безопасность
- Сеть отключена. MySQL 8 сам включает
skip_networkingпри--skip-grant-tables. Для MariaDB указывайте--skip-networkingявно. Без этого любой, кто достучится до порта 3306, войдёт в базу без пароля. - Короткое окно. Режим без проверки прав держите несколько минут. Не уходите, не вернув обычный запуск.
- Пароль не в командной строке.
mysql -p'пароль'оставляет пароль в истории shell и в списке процессов. Используйте-pбез значения: клиент спросит пароль сам. - История клиента. Клиент MySQL по умолчанию не пишет в
~/.mysql_historyстроки сIDENTIFIEDиPASSWORD. Про клиент MariaDB этого не предполагайте: проверьте~/.mysql_historyи~/.mariadb_historyи удалите строку с паролем. - Файл с паролем. Если пароль нужен скриптам, храните его в
~/.my.cnfс правами600, а не в cron-строке. - Root только локально. Учётки
'root'@'%'быть не должно. Для удалённого администрирования — отдельный пользователь, доступ через SSH-туннель или VPN.
Симптомы и решения
| Симптом | Причина | Решение |
|---|---|---|
ERROR 1698 (28000): Access denied for user 'root'@'localhost' | Root входит через сокет, а вы запускаете клиент не от root | sudo mysql; для приложений создать отдельного пользователя |
ERROR 1045 (28000): Access denied ... (using password: YES) | Неверный пароль или вход идёт под другим host (127.0.0.1 вместо localhost) | Проверить SELECT user, host FROM mysql.user; при потере пароля — сброс |
ERROR 1290 ... --skip-grant-tables | ALTER USER до загрузки таблиц привилегий | Сначала FLUSH PRIVILEGES |
Синтаксическая ошибка у PASSWORD('...') | Функции нет в MySQL 8 | ALTER USER ... IDENTIFIED BY |
Ошибка о незагруженном плагине mysql_native_password | MySQL 8.4, плагин отключён | IDENTIFIED WITH caching_sha2_password |
| После правки службы пароль всё равно спрашивают | Drop-in не применился | systemctl daemon-reload, проверить пустую строку ExecStart=, systemctl cat |
| Служба не стартует после сброса | Остался drop-in с неверной строкой запуска | systemctl revert, journalctl -u mysql -n 50 |
Частые вопросы
Почему в Debian можно войти в MariaDB как root без пароля?
Root настроен на плагин unix_socket: сервер проверяет системного пользователя, подключившегося к сокету, а не пароль. Войти так может только тот, кто уже root в системе. Это не дыра, а штатная схема с MariaDB 10.4. Из обычной учётки или по сети такой вход не сработает.
Нужен ли FLUSH PRIVILEGES после ALTER USER?
В обычном режиме нет: ALTER USER, CREATE USER и GRANT сами обновляют привилегии в памяти. FLUSH PRIVILEGES нужен в двух случаях: в режиме --skip-grant-tables перед ALTER USER и после прямой правки системных таблиц.
phpMyAdmin не пускает под root, а в консоли sudo mysql работает. Что делать?
phpMyAdmin подключается с паролем, а root настроен на сокет. Не переводите root на пароль ради панели. Создайте отдельного пользователя с паролем и нужными правами, и используйте его.
Как сбросить пароль обычного пользователя базы?
Зайдите как root через sudo mysql и выполните ALTER USER 'user'@'localhost' IDENTIFIED BY 'новый_пароль';. Host должен совпадать с тем, что в mysql.user. Перезапуск и --skip-grant-tables не нужны.
Можно ли сбросить пароль без остановки сервера?
Да, если есть любой вход с правом управления пользователями: root через сокет, debian-sys-maint в Ubuntu или другой администратор. Без такого входа остаётся только перезапуск с --skip-grant-tables, а это несколько минут простоя.