很长一段时间,我认为忘记MySQLroot密码的解决方案只有一个——skip-grant-tables。问了隔壁群里的大咖,反应也是skip-grant-tables。通过搜索引擎简单搜索一下,不管是百度,还是谷歌,只要是中文搜索,首页都有这个解决方案。可见,该方案在一定程度上已经占据了用户的心智。让我们详细看一下。skip-grant-tables的解决办法首先,关闭这里的实例,只能杀掉mysqld进程。注意:不是mysqld_safe进程,不要用kill-9。#ps-ef|grepmysqldroot62206171008:14pts/000:00:00/bin/shbin/mysqld_safe--defaults-file=my.cnfmysql63476220008:14pts/000:00:01/usr/local/mysql57/bin/mysqld--defaults-file=my.cnf--basedir=/usr/local/mysql57--datadir=/usr/local/mysql57/data--plugin-dir=/usr/local/mysql57/lib/plugin--user=mysql--log-error=slowtech.err--pid-file=slowtech.pid--socket=/usr/local/mysql57/data/mysql.sock--port=3307root64186171008:17pts/000:00:00grep--color=automysqld#kill6347使用--skip-grant-tables参数重启实例#bin/mysqld_safe--defaults-file=my.cnf--skip-grant-tables--skip-networking&设置该参数,实例在启动过程会跳过权限表的加载,这意味着任何用户都可以登录并执行任何操作,这是非常不安全的。建议同时加上--skip-networking参数。会导致实例关闭监听端口,自然无法建立TCP连接,只能通过本地socket连接。这就是MySQL8.0所做的。设置--skip-grant-tables参数后,--skip-networking将自动启用。修改密码#mysql-S/usr/local/mysql57/data/mysql.sockmysql>updatemysql.usersetauthentication_string=password('123456')wherehost='localhost'anduser='root';QueryOK,0rowsaffected,1warning(0.00sec)Rowsmatched:1Changed:0Warnings:1mysql>flushprivileges;QueryOK,0rowsaffected(0.00sec)注意:这里的update语句是针对MySQL5.7的运行。如果是5.6版本,应该修改password字段,而不是authentication_string。updatemysql.usersetpassword=password('123456')wherehost='localhost'anduser='root';在MySQL8.0.11中,这种方法基本不可行,因为去掉了PASSWORD()函数,不再支持SETPASSWORD...=PASSWORD('auth_string')语法。不难发现,这种方式的可移植性确实很差。三个不同的版本先后出现了列名变化、命令不可用等问题。接下来介绍另一种更通用的方法,基于skip-grant-tables。与上面不同的是,它会先通过flushprivileges操作触发加载权限表,然后使用alteruser语句修改root用户的密码,如:#bin/mysql-S/usr/local/mysql57/data/mysql.sockmysql>alteruser'root'@'localhost'identifiedby'123';ERROR1290(HY000):TheMySQLserverisrunningwiththe--skip-grant-tablesoptionssoitcannotexecutethisstatementmysql>flushprivileges;QueryOK,0rowsaffected(0.00sec)mysql>alteruser'root'@'localhost'identifiedby'123';QueryOK,0rowsaffected(0.00sec)无密码登录后,不能直接执行alteruser操作,因为此时还没有加载权限表。可以先通过flushprivileges操作触发加载权限表,再执行alteruser操作。需要注意的是,通过alteruser修改密码只适用于MySQL5.7和8.0。如果是MySQL5.6,可以写成updatemysql.usersetpasswordpassword=password('123456')wherehost='localhost'anduser='root';***重启实例mysql>shutdown;#bin/mysqld_safe--defaults-file=my.cnf&需要注意的是,如果在启动过程中没有指定--skip-networking参数,则不需要重启实例。但是网上看到的大部分解决方案都没有指定这个参数,但是重启实例确实没有必要。下面是这个方案的总结:如果只加--skip-grant-tables,修改密码后不需要重启,执行flushprivileges即可。从安全角度考虑,建议加上--skip-networking。但是因为它是一个静态参数,删除它需要重启实例。加上--skip-networking,虽然可以阻断TCP连接,但其他本地用户只要有socket文件的可读权限,就可以不用密码登录。仍然存在安全隐患。不建议通过update修改密码。更常见的方法其实是alteruser。更优雅的方案与skip-grant-tables方案相比,我们再来看看另一个更优雅的方案,只重启一次,基本没有安全隐患。首先,实例仍然关闭。二、创建sql文件,写入密码修改语句#viminit.sqlalteruser'root'@'localhost'identifiedby'123456';***,使用--init-file参数启动实例#bin/mysqld_safe--defaults-file=my.cnf--init-file=/usr/local/mysql57/init.sql&实例启动成功后修改密码~如果mysql实例是通过服务脚本管理的,除了创建sql文件,整个操作可以简化为一步。#servicemysqldrestart--init-file=/usr/local/mysql57/init.sql注意:该操作只适用于/etc/init.d/mysqld的服务管理方式,不适用于RHEL7新推出的systemd。原文链接:https://www.cnblogs.com/ivictor/p/9243259.html
