傳統 --skip-grant-tables 重置密碼需兩次重啟(啟動跳過授權 → 修改密碼 → 正常重啟)。本文介紹 --init-file 參數實現**單次重啟**重置,並結合 --skip-networking 確保安全窗口期零外部連接風險。
| 方案 | 重啟次數 | 安全窗口 | 適用場景 |
|---|---|---|---|
--skip-grant-tables (傳統) | 2 次 | 臨時實例無授權、可被任意連接 | 緊急、舊版本 |
--skip-grant-tables --skip-networking | 2 次 | 僅本地 Socket 可連,較安全 | 生產環境傳統法 |
--init-file (推薦) | 1 次 | 啟動即執行 SQL、無無授權窗口 | 標準化運維、自動化腳本 |
-- 必須以分號結尾,無註釋
ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewStrongPass123';
FLUSH PRIVILEGES;
⚠️ MySQL 5.7 用 UPDATE mysql.user SET authentication_string=PASSWORD('...') WHERE User='root';
systemctl stop mysqld
mysqld_safe --init-file=/root/reset_root.sql --user=mysql &
實例啟動過程中自動執行文件內 SQL,完成密碼重置。
# 等待幾秒後測試
mysql -u root -p'NewStrongPass123' -e "SELECT 1;"
# 立即刪除/清空 SQL 文件,防洩露
shred -u /root/reset_root.sql
# 或
echo "" > /root/reset_root.sql
# Ctrl+C 停止前台 mysqld_safe
systemctl start mysqld # 啟動系統服務
# 或直接用 systemctl restart mysqld (若 init-file 已在配置文件中臨時添加)
systemctl edit mysqld
# 編輯器中添加:
[Service]
ExecStartPre=/bin/sh -c 'echo "ALTER USER '\''root'\''@'\''localhost'\'' IDENTIFIED BY '\''NewStrongPass123'\''; FLUSH PRIVILEGES;" > /var/lib/mysql/init_reset.sql'
ExecStart=/usr/sbin/mysqld --init-file=/var/lib/mysql/init_reset.sql $@
# 保存退出
systemctl daemon-reload
systemctl restart mysqld
systemctl edit mysqld
# 刪除剛添加的內容,保存
systemctl daemon-reload
systemctl restart mysqld
chmod 600 /root/reset_root.sql、屬主 mysql:mysql。--skip-networking,僅本地 Socket 可連。--init-file 重置密碼:**單次重啟、無無授權窗口、可系統服務化、可自動化腳本化**,是現代 MySQL 運維的標準姿勢。將上述流程封裝為 Ansible Playbook / Shell 函數,納入應急預案庫,關鍵時刻一鍵執行。