ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Windows 11下MySQL root密码忘记或修改的完整实操指南

Windows 11下MySQL root密码忘记或修改的完整实操指南 不知道你有没有遇到过这种场景新装的MySQL登录不上或者某天突然发现之前设置的root密码怎么都想不起来了再或者用Navicat连本地数据库的时候弹出一句error 1045 (28000): Access denied for user rootlocalhost瞬间整个人就有点慌。这篇文章就是干这个事的在Window 11环境下把MySQL的root账号密码修改这件事掰开揉碎讲清楚。不管你是还记得密码想换一个新的还是彻底忘了密码必须强制重置下面这套方法我都实测跑通过照着操作基本不会翻车。文章里每一步的命令、截图要点、容易踩的坑都会交代到适合刚接触MySQL的新手也适合给忘了密码的老手救急。在开始之前先说明一个前提我用的环境是Windows 11系统MySQL版本覆盖8.0系列和5.7系列。这两个大版本在改密码的命令上有一点点差异文中会单独指出千万不要搞混。1. 动手之前的三分钟判断场景、确认服务、找到命令行这一步很多人会跳过然后卡在半路其实这三件事直接决定了你该用哪种改密码方案以及后续命令能不能执行成功。1.1 先搞清楚自己属于哪种情况改root密码这件事表面上都是把密码换成新的但实际处理路径完全不同。场景A我还记得当前root密码只是出于安全考虑想换一个或者安装时随便设了个密码现在想改得复杂点。这种情况最简单直接登录然后执行一条修改命令就行。场景B我完全忘了root密码登录时报Access denied或者试了无数个常见密码都不对。这种情况需要走跳过授权表的重置流程比场景A复杂一些但也不难。场景CMySQL刚装完root有初始临时密码但我不知道在哪里看。这种情况先别急着改密码得先把初始密码找出来。判断好了场景后面的操作才不会做无用功。如果你连自己属于哪种情况都不确定建议先用场景B的思路处理因为重置流程兼容所有状态。1.2 确认MySQL服务到底有没有在运行命令行修改密码前提是MySQL服务要么正常运行场景A要么能被你手动停止场景B。在Windows下服务没起来的话你直接敲mysql -uroot -p会报ERROR 2003 (HY000): Cant connect to MySQL server on localhost (10061)这时候不是密码问题是服务问题。打开管理员权限的CMD或者PowerShell这一步很重要后面停止服务、启动mysqld都需要管理员权限执行net start | findstr /i mysql如果看到类似MySQL80、MySQL、MySQL57这样的服务名说明服务存在且正在运行。如果什么都没有输出说明服务没启动可以继续执行net start MySQL80这里有个坑服务名不一定是mysql。MySQL 8.0的Windows服务默认叫MySQL80MySQL 5.7叫MySQL57用MSI安装包自己改过名的话那就更不一定了。想确认准确的服务名用这个更稳的方法sc query state all | findstr /i mysql或者直接打开服务管理窗口WinR输入services.msc找到名字里带MySQL的记下那个服务名后面停止和启动都用它。1.3 命令行工具找得到吗MySQL装好之后命令行工具mysql.exe和mysqld.exe在安装目录的bin文件夹下。默认路径一般是MySQL 8.0C:\Program Files\MySQL\MySQL Server 8.0\binMySQL 5.7C:\Program Files\MySQL\MySQL Server 5.7\bin如果你的CMD里直接敲mysql -uroot -p能进入MySQL说明bin目录已经在PATH环境变量里了这步可以跳过。如果提示mysql 不是内部或外部命令那就需要每次先切换到bin目录再执行命令或者用全路径cd C:\Program Files\MySQL\MySQL Server 8.0\bin mysql -uroot -p记住修改密码的场景A要求能正常登录MySQL场景B要求能执行mysqld.exe所以这两个exe的位置必须心里有数。2. 场景A实操还记得密码用ALTER USER平滑换密这是最常规的操作MySQL从5.7.6开始实际上8.0更规范官方推荐用ALTER USER语句来修改密码替代已经过时的SET PASSWORD FOR语法。2.1 先登录MySQL确认登录身份信息在CMD里执行mysql -uroot -p回车后会提示Enter password:输入当前密码。登录成功后会看到类似Welcome to the MySQL monitor.的输出和mysql提示符。提醒一句输入密码时终端不显示任何字符这是正常的别以为键盘坏了直接输完回车即可。登录后先看一个信息SELECT USER(), CURRENT_USER();USER()返回的是你尝试登录时提供的用户名和主机名CURRENT_USER()返回的是MySQL实际匹配到的账号。对于本地root登录正常情况两者都是rootlocalhost。如果这里显示的rootlocalhost和你想改的账号不匹配后面执行ALTER USER的时候要格外注意主机名部分。2.2 查看当前的密码策略避免新密码被拒MySQL 8.0默认启用了validate_password组件5.7则可能是插件它对密码长度、数字、大小写、特殊字符有强制要求。如果你设置新密码太简单系统会直接拒绝。先执行SHOW VARIABLES LIKE validate_password%;以MySQL 8.0默认策略为例你可能会看到validate_password.length值为 8表示密码至少8位。validate_password.policy值为 MEDIUM或者STRONGMEDIUM要求至少包含1个数字、1个小写字母、1个大写字母、1个特殊字符。所以新密码最好一步到位设置成符合策略的复杂密码比如MyNewPass123这种形式。否则你会遇到ERROR 1819 (HY000): Your password does not satisfy the current policy requirements然后还得回头重新设置。2.3 执行修改命令冲刷权限确认无误后执行ALTER USER rootlocalhost IDENTIFIED BY MyNewPass123;执行成功后MySQL会返回Query OK, 0 rows affected看起来像是没变化其实密码已经写进去了。这里拆解一下这条命令的各个部分ALTER USERMySQL官方的账号修改语句可以改密码、改认证插件、改权限属性。rootlocalhost指定要修改的账号。root账号的主机部分不一定是localhost如果你平时用的是root127.0.0.1或者root%连接那就要对应改成root127.0.0.1或root%。不确定的话可以在修改前执行SELECT user, host FROM mysql.user WHERE userroot;把所有root账号列出来逐个确认。IDENTIFIED BY 新密码8.0里这是明文写法内部会自动加密存储。在5.7版本中同一语法也可用但8.0是唯一推荐写法。接下来执行FLUSH PRIVILEGES;关于这一步多说两句。在老版本里改完mysql.user表后必须FLUSH PRIVILEGES才能让权限缓存生效。但在使用ALTER USER/SET PASSWORD修改时MySQL会自动刷新相关缓存严格来说不是非要不可。不过实际操作时我还是建议顺手执行一下成本极低而且能避免某些5.7历史版本里的缓存残留问题。2.4 什么时候用SET PASSWORD什么时候用ALTER USER我知道有人习惯用SET PASSWORD FOR rootlocalhost PASSWORD(xxx);这个语法在MySQL 8.0已经彻底移除了执行会直接报语法错误。5.7里虽然还能用但PASSWORD()函数也已废弃。所以统一记住一条原则只要版本是5.7.6以上含8.0改密码一律用ALTER USER别碰SET PASSWORD FOR。验证修改是否成功也很简单执行quit退出MySQL然后重新用新密码登录mysql -uroot -p能进去就说明一切正常。到这里场景A的完整流程就走完了。3. 场景B完整重置忘记root密码时的跳过授权表路线场景B是这篇的重头戏也是搜索量最大的需求。核心思路就一句话让MySQL启动时不加载权限表然后以无密码状态进入系统再把密码改回来。听起来有点绕过安全机制的意思但这本来就是MySQL官方支持的救援手段。完整流程我拆成4步每一步都有要避开的坑。3.1 停掉MySQL服务别用任务管理器顺手杀进程这一步很多人会踩坑直接在任务管理器里把mysqld.exe结束掉。这样做不干净可能导致数据文件损坏或服务状态错乱而且进程可能会被服务控制管理器自动重启。正确做法是用net stop停掉服务。但有个细节服务名必须写对。上面1.2节已经确认过服务名了比如net stop MySQL80看到服务已成功停止的提示就没问题了。如果你不确定服务名的具体写法也可以直接执行sc stop MySQL80或者打开服务窗口右键MySQL相关服务选择停止。停完之后最好确认一下tasklist | findstr mysqld如果没有任何输出说明mysqld进程已经彻底退出可以进入下一步。如果输出里还有mysqld.exe需要先等几秒再查一次仍然存在就说明服务没停干净不要强行进行下一步。3.2 用安全模式启动mysqld跳过授权表打开一个新的CMD窗口直接用管理员权限那个即可先切换到MySQL的bin目录cd C:\Program Files\MySQL\MySQL Server 8.0\bin然后执行mysqld --skip-grant-tables --shared-memory这里有两个关键参数--skip-grant-tables这是核心告诉MySQL启动时不加载授权表也就是说所有用户凭密码校验的逻辑都被绕过了。--shared-memory这是Windows下的参数让MySQL使用共享内存方式监听本地连接。有些环境不加也能跑但加上更稳妥。注意执行完这条命令之后CMD窗口会一直卡住不动光标在闪烁没有任何输出。这是正常的说明mysqld正在前台运行占住了这个窗口。千万别以为是死机了然后CtrlC把它杀掉。另外注意一个小细节执行这条命令前确保你的当前目录确实是bin目录或者用全路径执行mysqld.exe否则Windows可能提示找不到命令。此时MySQL已经以无密码校验模式运行了。在另一个新的CMD窗口里执行mysql -uroot注意这里不需要-p参数因为授权表被跳过了密码校验直接被绕开。正常情况下你会直接进入mysql提示符不需要输入任何密码。如果你做到了这一步恭喜重置密码的核心障碍已经清除了。如果执行mysql -uroot时报错连接不上多半是mysqld没真正起来。回头检查一下有没有别的mysqld进程占着3306端口或者运行netstat -ano | findstr 3306看看端口是否被监听。3.3 在跳过授权表模式下完成密码重置进入mysql提示符后第一步不是直接改密码而是先让权限表重新生效。因为当前模式下权限系统是被绕过的直接执行ALTER USER可能不会生效或会报错。先在mysql执行FLUSH PRIVILEGES;这条命令会重新加载权限表并且强制让MySQL认为权限系统已经可用这样才能正常执行后续的用户修改语句。接下来分两条路线根据你的MySQL版本选择。MySQL 8.0路线先确认一下当前root账号的主机信息SELECT user, host FROM mysql.user WHERE userroot;然后执行ALTER USER rootlocalhost IDENTIFIED BY MyNewPass123;MySQL 5.7路线5.7同样可以使用ALTER USER但如果你的5.7版本较老或者遇到了权限不足的报错可以退回到UPDATE方式USE mysql; UPDATE user SET authentication_stringPASSWORD(MyNewPass123) WHERE userroot AND hostlocalhost;注意5.7用的是authentication_string字段而不是老掉牙的Password字段。PASSWORD()函数在5.7里还能用但也仅限5.78.0里直接不支持。如果你的5.7比较新建议直接试试ALTER USER能省不少事。看到一个常见的报错在跳过授权表模式下直接执行ALTER USER偶尔会遇到Table mysql.user doesnt exist或权限错误。这时候最好先执行一下USE mysql;或者干脆退出mysql客户端用mysql -uroot重新登录一次再操作。至于为什么偶尔会有这种怪问题我推测和8.0新增的序列化字典信息有关权限表缓存没刷新干净的时候容易出现怪毛病。3.4 收尾关闭安全模式恢复正常启动流程密码改完之后不能直接就这样用。现在的MySQL还处于跳过授权表模式必须恢复原样。第一步回到那个卡住的mysqld窗口按CtrlC终止mysqld进程或者关掉那个CMD窗口。等几秒确认mysqld真的退出了tasklist | findstr mysqld没有输出才算完。第二步重新启动MySQL服务net start MySQL80看到服务启动成功的提示说明服务已经回到正常模式。第三步用新密码登录验证mysql -uroot -p输入新密码之后能进入mysql说明整个重置流程成功了。这里我要特别强调一个容易反复踩的坑如果你在没有退出安全模式的情况下直接重启服务可能会遇到两个mysqld进程打架一个以跳过授权表模式占着3306端口另一个正常启动报端口被占用。到时候连net start都报错还得回头找进程杀掉很浪费时间。所以3.3的步骤一定不要跳先彻底关掉安全模式再启动服务。4. 图解实操中最容易翻车的四个细节这一节全是实战中高概率遇到的坑我把它们单独拿出来每个坑都附上排查思路和解决办法建议你在操作前从头到尾看一遍。4.1 服务名对不上net stop直接失败很多人照着教程敲net stop mysql结果Windows提示服务名无效。原因在1.2提过MySQL在Windows上的服务名默认带版本号MySQL80、MySQL57、MySQL848.4版本都有。而且用zip压缩包手动安装MySQL时服务名完全取决于当时注册命令里的名字可能是MySQL、mysql-local甚至自定义的名字。排查方法很简单执行sc query state all | findstr /i mysql或者打开服务管理器搜索mysql以服务管理器显示的服务名为准。记住命令里的服务名必须和这里完全一致包括大小写和数字后缀。还有一种更稳妥的思路如果服务窗口里能看到但命令行还是报错检查一下你是不是用管理员权限打开的CMD。net stop需要管理员权限普通权限下执行会拒绝访问。4.2 跳过授权表时mysqld窗口卡住有人以为死机了前面说了mysqld --skip-grant-tables --shared-memory执行后窗口不输出任何内容、光标持续闪烁这是正常工作状态。mysqld在8.0版本里默认日志输出到了error log文件不再往控制台打印所以窗口干干净净。有一个情况需要区分如果窗口里出现大量类似[ERROR] [MY-010584] No such file or directory的输出那才是有问题多半是my.ini配置文件中datadir路径不对或者basedir路径配错了。这时候按CtrlC终止去检查配置文件。另外提醒一下启动安全模式前先确认3306端口没有被占用netstat -ano | findstr 3306如果端口被其他进程占用mysqld会启动失败并报错。占用3306端口的通常就是一个已经运行的mysqld进程先停服务再启动安全模式。4.3 跳过授权表时改了密码但忘了FLUSH PRIVILEGES这个坑最容易在重置流程的3.3步出现。进入跳过授权表模式后你执行ALTER USER或UPDATE mysql.user时MySQL的权限系统还处于冻结状态。如果你改完密码后直接退出、重启服务有时会出现新密码死活登录不上的情况但也不是完全登不上——表现很诡异有时候能用新密码进有时候必须用空密码。原因就是权限缓存没有刷新。改完密码后执行FLUSH PRIVILEGES;让MySQL重新读取权限表。这道工序在8.0里也更重要因为8.0的权限管理引入了更多缓存层不刷新容易出现幽灵密码问题。如果你已经忘记了这步并且退出了别慌。重新走一遍3.1~3.2的安全模式流程进去先执行FLUSH PRIVILEGES再重新执行一次密码修改命令最后退出重启服务问题就解了。4.4 改完密码后仍然报error 1045到底哪里错了ERROR 1045 (28000): Access denied for user rootlocalhost (using password: YES)这个报错几乎天天有人遇到而且不一定是在改密码的时候。排在前面的是这几种情况密码没改成功或者说改的账号跟你登录用的账号不是同一个。前面提到过root账号可能有多个host记录rootlocalhost和root127.0.0.1是两条独立记录。你改了某个用另一个登录当然失败。新密码里有特殊字符在命令行里被解释掉了。比如密码是abc$123在CMD里直接敲mysql -uroot -pabc$123$和某些字符会被当成变量或分隔符。建议密码里不要用$、、%这类对命令行不友好的符号或者在password后面再提示输入时手动输入别写在命令行里。认证插件不匹配。特别是从老版本升级或迁移过来的MySQL账号的plugin字段可能是mysql_native_password而客户端默认尝试新的caching_sha2_password。判断方法是用空密码或正确密码都登不进去时试试指定插件ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY MyNewPass123;这条命令在跳过授权表模式下同样可用也可以作为8.0环境的一个备用手段。如果你的应用特别是老版本PHP、老Navicat连不上MySQL 8.0通常就是认证插件兼容性问题改成mysql_native_password基本能解决。遇到1045报错时排错顺序是先确认服务在跑再确认账号主机和密码没错再检查特殊字符最后考虑认证插件。5. 密码改完之后建议顺手做的几件事密码重置成功只是完成了第一步作为一个吃过亏的人我强烈建议你在收尾阶段多做几件事能帮你省掉后面很多麻烦事。5.1 验证除命令行之外的外围连接命令行能登录不代表其他客户端都能连。尤其是MySQL 8.0的caching_sha2_password认证插件老版本的Navicat、图形化工具、某些语言的数据库驱动可能不支持。改完密码后打开Navicat或DBeaver、DataGrip用新密码连一次能连上才算真正完成。如果连不上但命令行可以90%是认证插件问题用4.4节的IDENTIFIED WITH mysql_native_password BY再改一次。顺带提一句Navicat连接时如果报Authentication plugin caching_sha2_password cannot be loaded就是因为驱动不认新插件修改认证插件即可。5.2 检查密码过期策略MySQL 5.7和8.0默认的default_password_lifetime是0表示密码永不过期。但很多企业环境或某些一键部署脚本会把密码过期策略设成非零值导致密码到期后MySQL直接拒绝连接报错信息通常是ERROR 1862 (HY000): Your password has expired. To log in you must change it using a client that supports expired passwords.遇到这个报错同样可以用ALTER USER重置密码来解决。如果想彻底关闭过期机制SET GLOBAL default_password_lifetime 0;同时确保当前账号不过期ALTER USER rootlocalhost PASSWORD EXPIRE NEVER;我的经验是本地开发环境没必要让root密码过期给自己找麻烦生产环境倒是建议设置一个合理的过期周期并且配合定期改密流程。5.3 root账号权限收一收别裸奔改完密码后如果你当前MySQL处于裸奔状态默认root可以从任意位置登录、权限过大建议顺手做两件小事。看一下root账号有哪些hostSELECT user, host, plugin FROM mysql.user WHERE userroot;如果存在root%这样的记录而且你并不需要远程root登录建议删除DROP USER root%;经验之谈root账号只保留localhost一个入口远程连接一律用业务专用账号这是最稳的习惯。新建一个应用专用账号给最小权限CREATE USER app_userlocalhost IDENTIFIED BY AppPass123; GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO app_userlocalhost;这样即使某个应用因为配置泄露导致数据库账号被拿到损失也可控不至于一上来就是root全权限。5.4 备份一下修改后的账号表结构改密码过程中如果执行过DROP USER、CREATE USER、ALTER USER等操作建议导出一次权限表备份mysqldump -uroot -p --all-databases --no-data privileges_only.sql这不会备份具体表数据只备份权限、账号、事件等结构信息。万一以后改密码又改崩了用这份文件能快速恢复账号体系。我干过几次这种蠢事备份能救命。最后说两句亲身感受MySQL的root密码修改说难不难说简单也总有人卡在奇怪的地方。我自己从MySQL 5.6一路用到8.0密码重置这条路走过不下二十遍最大的体会是大部分翻车都出在跳过授权表之后的权限刷新和服务名搞错这两个点上。只要你把这篇文章里的坑提前看完操作的时候按步骤来基本能一遍过。最后再送一个小技巧改完密码后如果是在生产环境建议找一个业务低峰期操作并且在操作前先做一次全量备份或者至少把mysql库备份一下。密码这东西改之前是确定的改完那一刻开始所有依赖它的应用都得跟着更新所以行动之前列个清单改完立刻通知到相关的人。
返回列表