MySQL 權限系統基於 mysql 系統庫中的五張授權表,實現連接驗證與請求授權的兩階段控制。理解其結構與邏輯,是解決「連不上、查不了、改不了」權限疑難雜癥的鑰匙。
| 表名 | 作用域 | 關鍵範圍列 | 典型權限列 |
|---|---|---|---|
user | 全局(服務器級) | Host, User | Select_priv, Insert_priv, ..., Grant_priv, Shutdown_priv, File_priv |
db | 數據庫級 | Host, Db, User | Select_priv, Insert_priv, ..., Grant_priv |
host | 主機-數據庫級(輔助 db) | Host, Db | Select_priv, Insert_priv, ..., Grant_priv |
tables_priv | 表級 | Host, Db, User, Table_name | Table_priv (SET: Select,Insert,Update,Delete,Create,Drop,Grant,References,Index,Alter) |
columns_priv | 列級 | Host, Db, User, Table_name, Column_name | Column_priv (SET: Select,Insert,Update,References) |
user 表)
Host、User、Password(或插件驗證)user 表中全局權限作為「基線權限」Access denieddb → host → tables_priv → columns_priv)
user 表授予的權限作用於 所有庫所有表,含 mysql 系統庫。除 root 外,**嚴禁** 在 user 表授予任何 Y。新建用戶默認全 N,登錄後「什麼也幹不了」,極其安全。
Password / authentication_string 存儲的是 PASSWORD() / 插件加密後的雜湊值,**無逆運算**。手工修改必須使用加密函數:
-- 5.7 前
UPDATE user SET Password=PASSWORD('newpass') WHERE User='app' AND Host='%';
-- 5.7+ / 8.0
ALTER USER 'app'@'%' IDENTIFIED BY 'newpass'; -- 推薦,自動處理插件與刷新
root@localhost 僅允許本地 Unix Socket 連接root@192.168.1.% 僅允許特定網段root@%(任意主機)FLUSH PRIVILEGES;
GRANT/REVOKE 會自動刷新,無需手動執行。
CREATE USER 'app_user'@'10.0.0.%' IDENTIFIED BY 'StrongPass123!';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON `biz_db`.* TO 'app_user'@'10.0.0.%';
-- 不授 GRANT OPTION、DROP、ALTER、CREATE、FILE、SHUTDOWN、PROCESS
CREATE USER 'ro_report'@'10.0.1.%' IDENTIFIED BY 'ReadOnlyPass!';
GRANT SELECT ON `biz_db`.* TO 'ro_report'@'10.0.1.%';
GRANT SELECT ON `mysql`.`help_*` TO 'ro_report'@'10.0.1.%'; -- 如需查幫助
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'old_user'@'%';
DROP USER 'old_user'@'%';
user.Host(通配符 %、具體 IP、CIDR 192.168.1.0/255.255.255.0)user.Password / authentication_string 非空、插件匹配(caching_sha2_password vs mysql_native_password)FLUSH PRIVILEGES 已執行(手工改表後)telnet host 3306、防火牆、bind-address、skip-networkingtail -f /var/log/mysql/error.log權限系統看似複雜,實則邏輯嚴密。掌握「兩階段、五張表、聯集授權、最小權限」核心模型,即可從容應對所有權限場景。