| 方案 | 需重啟 | 適用場景 | 風險等級 |
|---|---|---|---|
| skip-grant-tables + 修改 user 表 | 是(2次) | 忘記 root 密碼、無其他管理帳號 | 中(需修改配置、短暫無認證) |
| mysqld_safe --init-file | 是(1次) | 忘記 root 密碼、腳本化自動化 | 低(官方推薦,無免認證窗口) |
| 複製 user 表至測試庫修改再覆蓋 + SIGHUP | 否 | 擁有低權限帳號、極高可用性要求 | 高(直接操作系統表檔案,極易損壞) |
# 1. 編輯 my.cnf
[mysqld]
skip-grant-tables
skip-networking # 安全起見,禁用 TCP 連線
# 2. 重啟 MySQL
systemctl restart mysqld
# 3. 免密登入修改密碼
mysql -u root
mysql> UPDATE mysql.user SET authentication_string = PASSWORD('newpwd') WHERE User = 'root';
mysql> FLUSH PRIVILEGES;
# 4. 移除配置並再次重啟
# 註釋 skip-grant-tables / skip-networking
systemctl restart mysqld
缺點:啟用 `skip-grant-tables` 期間**任何人可免密登入**,生產環境極度危險;需兩次重啟影響可用性。
# 1. 建立初始化 SQL 檔
echo "ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpwd';" > /tmp/mysql-init.sql
# 5.7 以下用:UPDATE mysql.user SET Password=PASSWORD('newpwd') WHERE User='root'; FLUSH PRIVILEGES;
# 2. 停止服務
systemctl stop mysqld
# 3. 以 init-file 啟動(後台執行)
mysqld_safe --init-file=/tmp/mysql-init.sql &
# 4. 驗證新密碼
mysql -u root -p'newpwd'
優點:無免認證窗口、單次重啟、適合自動化腳本。MySQL 5.7+ 建議用 `ALTER USER` 而非直接 UPDATE 系統表。
前提條件:擁有一個可連線的低權限帳號(如 `test`),且該帳號有 `test` 庫寫入權限。
# 1. 複製 user 表檔案到 test 庫(需 root 系統權限)
cp /var/lib/mysql/mysql/user.* /var/lib/mysql/test/
chown mysql:mysql /var/lib/mysql/test/user.*
# 2. 低權限帳號登入修改 test.user
mysql -u test -p12345
mysql> USE test;
mysql> UPDATE user SET authentication_string = PASSWORD('yayun') WHERE User = 'root';
# 或 5.6:UPDATE user SET Password = PASSWORD('yayun') WHERE User = 'root';
# 3. 覆蓋回 mysql 庫(備份舊檔)
mv /var/lib/mysql/mysql/user.MYD /var/lib/mysql/mysql/user.MYD.bak
mv /var/lib/mysql/mysql/user.MYI /var/lib/mysql/mysql/user.MYI.bak
cp /var/lib/mysql/test/user.MY* /var/lib/mysql/mysql/
chown mysql:mysql /var/lib/mysql/mysql/user.*
# 4. 發送 SIGHUP 重新載入授權表
pgrep -n mysqld
kill -SIGHUP
# 5. 驗證
mysql -u root -p'yayun'
MySQL 5.7+ 修改 root 密碼**完全不需要重啟**,`ALTER USER` 即時生效。只有「忘記密碼且無其他管理帳號」才需走 `init-file` 流程。網上流傳的「複製 user 表檔案 + SIGHUP」是早期 MyISAM 時代的駭客技巧,**在 InnoDB 系統表時代已徹底失效且極度危險**,請勿在生產環境嘗試。