MySQL root密碼忘記,原來還有更優(yōu)雅的解法!
一直以來,對(duì)于MySQL root密碼的忘記,以為只有一種解法-skip-grant-tables。
問了下群里的大咖,***反應(yīng)也是skip-grant-tables。通過搜索引擎簡(jiǎn)單搜索了下,無論是百度,抑或Google,只要是用中文搜索,首頁都是這種解法。可見這種解法在某種程度上已經(jīng)占據(jù)了使用者的心智。下面具體來看看。
skip-grant-tables的解法
首先,關(guān)閉實(shí)例
這里,只能通過kill mysqld進(jìn)程的方式。
注意:不是mysqld_safe進(jìn)程,也切忌使用kill -9。
- # ps -ef |grep mysqld
- root 6220 6171 0 08:14 pts/0 00:00:00 /bin/sh bin/mysqld_safe --defaults-file=my.cnf
- mysql 6347 6220 0 08:14 pts/0 00: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=3307
- root 6418 6171 0 08:17 pts/0 00:00:00 grep --color=auto mysqld
- # kill 6347
使用--skip-grant-tables參數(shù),重啟實(shí)例
- # bin/mysqld_safe --defaults-file=my.cnf --skip-grant-tables --skip-networking &
設(shè)置了該參數(shù),則實(shí)例在啟動(dòng)過程中會(huì)跳過權(quán)限表的加載,這就意味著任何用戶都能登錄進(jìn)來,并進(jìn)行任何操作,相當(dāng)不安全。
建議同時(shí)添加--skip-networking參數(shù)。其會(huì)讓實(shí)例關(guān)閉監(jiān)聽端口,自然也就無法建立TCP連接,而只能通過本地socket進(jìn)行連接。
MySQL8.0就是這么做的,在設(shè)置了--skip-grant-tables參數(shù)的同時(shí)會(huì)自動(dòng)開啟--skip-networking。
修改密碼
- # mysql -S /usr/local/mysql57/data/mysql.sock
- mysql> update mysql.user set authentication_string=password('123456') where host='localhost' and user='root';
- Query OK, 0 rows affected, 1 warning (0.00 sec)
- Rows matched: 1 Changed: 0 Warnings: 1
- mysql> flush privileges;
- Query OK, 0 rows affected (0.00 sec)
注意:
這里的update語句針對(duì)的是MySQL 5.7的操作,如果是在5.6版本,修改的應(yīng)該是password字段,而不是authentication_string。
- update mysql.user set password=password('123456') where host='localhost' and user='root';
而在MySQL 8.0.11版本中,這種方式基本不可行,因?yàn)槠湟岩瞥薖ASSWORD()函數(shù)及不再支持SET PASSWORD … = PASSWORD ('auth_string')語法。
不難發(fā)現(xiàn),這種方式的可移植性實(shí)在太差,三個(gè)不同的版本,就先后經(jīng)歷了列名的改變,及命令的不可用。
下面,介紹另外一種更通用的做法,還是在skip-grant-tables的基礎(chǔ)上。
與上面不同的是,其會(huì)先通過flush privileges操作觸發(fā)權(quán)限表的加載,再使用alter user語句修改root用戶的密碼,如:
- # bin/mysql -S /usr/local/mysql57/data/mysql.sock
- mysql> alter user 'root'@'localhost' identified by '123';
- ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement
- mysql> flush privileges;
- Query OK, 0 rows affected (0.00 sec)
- mysql> alter user 'root'@'localhost' identified by '123';
- Query OK, 0 rows affected (0.00 sec)
免密碼登錄進(jìn)來后,直接執(zhí)行alter user操作是不行的,因?yàn)榇藭r(shí)的權(quán)限表還沒加載。可先通過flush privileges操作觸發(fā)權(quán)限表的加載,再執(zhí)行alter user操作。
需要注意的是,通過alter user修改密碼只適用于MySQL5.7和8.0,如果是MySQL 5.6,此處可寫成
- update mysql.user set passwordpassword=password('123456') where host='localhost' and user='root';
***重啟實(shí)例
- mysql> shutdown;
- # bin/mysqld_safe --defaults-file=my.cnf &
需要注意的是,如果在啟動(dòng)的過程中沒有指定--skip-networking參數(shù),無需重啟實(shí)例。但在網(wǎng)上看到的絕大多數(shù)方案,都是沒有指定該參數(shù),但重啟了實(shí)例,實(shí)在沒有必要。
下面對(duì)這個(gè)方案做個(gè)總結(jié):
如果只添加了--skip-grant-tables,修改完密碼后,其實(shí)無需重啟,執(zhí)行flush privileges即可。
從安全角度出發(fā),建議加上--skip-networking。但因其是靜態(tài)參數(shù),將其剔除掉需要重啟實(shí)例。
加上--skip-networking,雖然可以屏蔽掉TCP連接,但對(duì)于本地其它用戶,只要有socket文件的可讀權(quán)限,都能無密碼登錄。還是存在安全隱患。
不建議通過update的方式修改密碼,更通用的其實(shí)是alter user。
更優(yōu)雅的解法
相對(duì)于skip-grant-tables方案,我們來看看另外一種更優(yōu)雅的解法,其只會(huì)重啟一次,且基本上不存在安全隱患。
首先,依舊是關(guān)閉實(shí)例
其次,創(chuàng)建一個(gè)sql文件
寫上密碼修改語句
- # vim init.sql
- alter user 'root'@'localhost' identified by '123456';
***,使用--init-file參數(shù),啟動(dòng)實(shí)例
- # bin/mysqld_safe --defaults-file=my.cnf --init-file=/usr/local/mysql57/init.sql &
實(shí)例啟動(dòng)成功后,密碼即修改完畢~
如果mysql實(shí)例是通過服務(wù)腳本來管理的,除了創(chuàng)建sql文件,整個(gè)操作可簡(jiǎn)化為一步。
- # service mysqld restart --init-file=/usr/local/mysql57/init.sql
注意:該操作只適用于/etc/init.d/mysqld這種服務(wù)管理方式,不適用于RHEL 7新推出的systemd。
原文鏈接:https://www.cnblogs.com/ivictor/p/9243259.html