針對 MySQL 3.22.11 之前不支援 GRANT/REVOKE 的版本,本文詳細說明如何通過直接操作授權表(user、db、tables_priv、columns_priv)實現等效權限控制,並深度剖析匿名用戶導致的本地連接優先級陷阱及修復方案。
關鍵差異:GRANT 自動調用 PASSWORD() 加密,手動 INSERT 必須顯式調用。
GRANT ALL ON *.* TO anyname@localhost IDENTIFIED BY 'passwd' WITH GRANT OPTION;
-- 等效 INSERT(需根據實際 user 表列數調整)
INSERT INTO user VALUES ('localhost','anyname',PASSWORD('passwd'), 'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
GRANT RELOAD ON *.* TO flush@localhost IDENTIFIED BY 'flushpass';
-- 等效 INSERT 指定列
INSERT INTO user (Host, User, Password, Reload_priv) VALUES ('localhost','flush',PASSWORD('flushpass'),'Y');
GRANT ALL ON sample.* TO boris@localhost IDENTIFIED BY 'ruby';
-- user 表:僅建立連接記錄
INSERT INTO user (Host, User, Password) VALUES ('localhost','boris',PASSWORD('ruby'));
-- db 表:授予具體資料庫權限
INSERT INTO db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv, Create_priv, Drop_priv, Grant_priv, References_priv, Index_priv, Alter_priv)
VALUES ('localhost','sample_db','boris','Y','Y','Y','Y','Y','Y','N','Y','Y','Y');
操作 tables_priv.Table_priv 或 columns_priv.Column_priv(SET 類型),如 'Select,Insert'。修改權限用 UPDATE,刪除用戶需清理所有五張表記錄。
現象:創建用戶 fred@%.snake.net,但在 localhost 以 fred 連接報錯 Access denied for user: 'fred@localhost'。
根因:mysql_install_db 初始化留下兩條匿名記錄 ''@localhost、''@pit.snake.net。服務端啟動時按「Host 具體度優先,再 User 具體度」排序,匿名記錄排在 fred@%.snake.net 之前。本地連接優先匹配匿名記錄(密碼為空),導致密碼不匹配拒絕。
排序規則:字面值 > 通配符;IP 掩碼同理。localhost > %,root > ''。
DELETE FROM user WHERE User='';
DELETE FROM db WHERE User='';
DELETE FROM tables_priv WHERE User='';
DELETE FROM columns_priv WHERE User='';
FLUSH PRIVILEGES;
mysqladmin -u root password 'strongpass'
-- 或
UPDATE user SET Password=PASSWORD('strongpass') WHERE User='root'; FLUSH PRIVILEGES;
mysqladmin -u root status 若仍免密登入,執行 mysqladmin -u root reload。老版本手動維護授權表極易出錯,強烈建議升級至支援 GRANT/REVOKE 的版本,並建立自動化基線檢查機制。