mysql 5.7 安全重置 root 密码需停服务后以 --skip-grant-tables --skip-networking 启动,本地连接执行 update mysql.user set authentication_string=password('新密码') where user='root',再 flush privileges;mysql 8.0+ 必须用 alter user 'root'@'localhost' identified by '新密码',且需注意认证插件与配置冲突。

不能直接用 mysqld_safe --skip-grant-tables 在生产环境试,会绕过所有权限校验,且 MySQL 8.0+ 已弃用该方式;找回 root 密码必须停服务、进单用户模式、跳过权限表加载,但操作前得确认 mysqld 启动配置没锁死 skip-grant-tables 或 secure-file-priv 等限制。
MySQL 5.7 怎么安全重置 root 密码(不丢权限表)
本质是让 mysqld 启动时不加载权限系统,再用本地 socket 连上去强制更新 mysql.user 表。关键不是“跳过验证”,而是“跳过权限表加载”——验证逻辑还在,只是没数据可查。
- 停掉 MySQL:
systemctl stop mysql(或service mysqld stop,看发行版) - 手动启动并跳过权限表:
mysqld --skip-grant-tables --skip-networking --user=mysql &;--skip-networking必加,否则远程连接能直接写库 - 本地连:
mysql -u root(此时密码任意输,甚至空着也行) - 重置密码(5.7 用
password()函数):UPDATE mysql.user SET authentication_string=PASSWORD('新密码') WHERE User='root'; - 刷新权限:
FLUSH PRIVILEGES;,然后exit,再kill掉刚才的手动进程,正常启服务
MySQL 8.0+ 必须用 ALTER USER,PASSWORD() 函数已失效
8.0 默认认证插件是 caching_sha2_password,authentication_string 字段存的是 SHA256 哈希,不能手算也不能用老函数赋值;硬改字段会导致登录报错 Plugin caching_sha2_password could not be loaded。
- 同样走
--skip-grant-tables启动(注意:8.0 仍支持,但官方文档已标记为“deprecated”,实际还能用) - 连上后不能用
UPDATE mysql.user,必须用:ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码'; - 如果提示
User 'root'@'localhost' does not exist,说明 host 是'root'@'%'或其他,先查:SELECT User,Host FROM mysql.user; - 改完立刻
FLUSH PRIVILEGES;,否则新密码不生效
systemd 环境下 --skip-grant-tables 启动失败的常见卡点
很多生产机用 systemd 管理 mysqld,直接后台跑 mysqld --skip-grant-tables 会和 systemd 冲突,进程被 kill,或者 pid 文件残留导致后续启动报 Another MySQL daemon already running。
- 先关 systemd 服务:
systemctl stop mysqld,再确认没残留:ps aux | grep mysqld,杀干净 - 删掉 pid 文件:
rm -f /var/run/mysqld/mysqld.pid(路径以my.cnf里pid-file配置为准) - 临时注释掉
my.cnf里的bind-address和skip-networking(如果有),避免端口冲突 - 启动时加
--socket=/tmp/mysql.sock指定 socket 路径,避免和原实例抢/var/lib/mysql/mysql.sock
真正麻烦的不是命令记不住,是重启后发现 max_connections 变了、innodb_buffer_pool_size 回退到默认值——因为跳过权限表启动时,mysqld 会忽略部分配置项,只读最小化配置。动手前最好 mysqld --print-defaults 看一眼实际生效的配置路径和参数。











