MySQL 5.7.6+ 必须用 ALTER USER 修改密码,SET PASSWORD 和 PASSWORD() 已弃用;需单引号包裹非空密码,用户存在且有权限;推荐配置文件传参、检查 password_expired/account_locked 状态,并用 -N -s -r 导出安全SQL。

mysql 5.7+ 用 ALTER USER 修改密码报错 ERROR 1064
MySQL 5.7.6 之后 SET PASSWORD 被弃用,直接写 ALTER USER 'user'@'host' IDENTIFIED BY 'newpass'; 才有效。老脚本里沿用 SET PASSWORD FOR 'u'@'h' = PASSWORD('p'); 会触发语法错误——ERROR 1064 (42000),因为 PASSWORD() 函数也从 8.0 起彻底移除。
实操建议:
- 统一用
ALTER USER语句,兼容 5.7.6+ 和 8.0+ - 密码必须用单引号包裹,且不能是空字符串(会报
ERROR 1819) - 如果用户不存在,
ALTER USER不报错但也不生效,得先CREATE USER或确认存在 - 执行前确保当前连接用户有
UPDATE权限在mysql.user表,或有SYSTEM_USER权限
Shell 脚本批量改密码时 mysql 命令连不上
常见现象是脚本跑着跑着卡住,或者报 ERROR 1045 (28000): Access denied,本质是 Shell 里没正确传参或权限不足。
实操建议:
- 不要把密码写死在命令行(如
mysql -uroot -p123456),会被ps看见;改用配置文件:mysql --defaults-extra-file=/tmp/.my.cnf -e "ALTER USER ..." -
/tmp/.my.cnf内容必须是:[client] user=root password=your_real_pass host=localhost
且权限设为chmod 600 /tmp/.my.cnf,否则 mysql 拒绝读取 - 如果目标用户是远程 host(如
'app'@'10.%.%.%'),注意host在配置文件里也要匹配,或显式加-h参数
批量改密码后应用连不上:忽略 password_expired 和 account_locked
改完密码,应用仍报 Access denied for user,不是密码错了,而是用户被锁或强制改密。MySQL 5.7+ 默认开启密码过期策略,老用户可能处于 password_expired 状态;8.0+ 还可能因多次失败登录被 account_locked。
实操建议:
- 查状态:运行
SELECT user,host,password_expired,account_locked FROM mysql.user WHERE user IN ('u1','u2'); - 重置时一并处理:在
ALTER USER后加PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK - 完整语句示例:
ALTER USER 'api'@'%' IDENTIFIED BY 'xYz9!' PASSWORD EXPIRE DEFAULT ACCOUNT UNLOCK; - 别漏掉
FLUSH PRIVILEGES;——其实 5.7.6+ 不需要,但低版本或某些部署环境仍要,加了不伤,不加可能失效
用 SELECT CONCAT 生成批量 SQL 时引号和转义翻车
想用 SELECT CONCAT('ALTER USER ''',user,'''@''',host,''' IDENTIFIED BY ''newpass'';') FROM mysql.user WHERE ... 导出一堆语句再执行,结果复制出来全是乱码或语法错,大概率是单引号没对齐、特殊字符没转义。
实操建议:
- 用
mysql -N -s -r参数导出纯文本:mysql -N -s -r -e "SELECT CONCAT(...)" > reset.sql,避免 tab/换行干扰 - 用户或 host 里含下划线、百分号(如
'report'@'192.168.1.%')不用额外转义,但含单引号(如用户名O'Reilly)必须用两个单引号写成O''Reilly - 导出后先人工扫一眼前 3 行,确认每条都是合法
ALTER USER语句,再mysql - 别信“全库用户都改一遍”,生产库里的
'mysql.infoschema'@'localhost'这类系统账户改了就崩,白名单过滤更稳


















