MySQL 的權限系統基於「用戶+主機」雙重標識,權限粒度細至列級。本文系統梳理 MySQL 5.7/8.0 版本下用戶全生命周期管理:創建、授權、查看、修改、刪除,並對比不同方法優劣,給出生產環境最佳實踐建議。
'username'@'host'。% 通配符匹配任意主機,localhost 僅本地 Socket 連接,127.0.0.1 僅本地 TCP 連接。mysql.user (全局)、mysql.db (庫級)、mysql.tables_priv (表級)、mysql.columns_priv (列級)、mysql.procs_priv (存儲過程)。-- 創建用戶並設置密碼 (明文,MySQL 自動加密存儲)
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'StrongP@ssw0rd!';
-- MySQL 8.0 支持雙因子認證、密碼策略等高級選項
CREATE USER 'repl'@'%' IDENTIFIED WITH caching_sha2_password BY 'password'
REQUIRE SSL
PASSWORD EXPIRE INTERVAL 90 DAY
FAILED_LOGIN_ATTEMPTS 3
PASSWORD_LOCK_TIME 2;
優點:語法標準、安全、只創建用戶不授權(符合最小權限原則)、支持 8.0 新特性。
缺點:需額外執行 GRANT 授權。
NO_AUTO_CREATE_USER 兼容)-- 一條語句完成創建+授權
GRANT SELECT, INSERT, UPDATE ON `mydb`.* TO 'app_user'@'%' IDENTIFIED BY 'StrongP@ssw0rd!';
注意:MySQL 8.0 默認 不再支持 隱式創建用戶,會報錯 ERROR 1410 (42000): You are not allowed to create a user with GRANT。必須先 CREATE USER 再 GRANT。
INSERT INTO mysql.user (Host, User, authentication_string, ssl_cipher, x509_issuer, x509_subject)
VALUES ('%', 'legacy_user', PASSWORD('oldpass'), '', '', '');
FLUSH PRIVILEGES; -- 必須執行使生效
缺點:繞過權限系統檢查,易導致權限表不一致、密碼加密方式錯誤 (8.0 用 caching_sha2_password)、升級故障。**僅用於極端災難恢復**。
| 層級 | 語法示例 | 適用場景 |
|---|---|---|
| 全局 | GRANT ALL PRIVILEGES ON *.* TO 'admin'@'%' WITH GRANT OPTION; | DBA、監控、備賬號 |
| 庫級 | GRANT SELECT, INSERT, UPDATE, DELETE ON `business_db`.* TO 'app_rw'@'10.0.1.%'; | 應用讀寫賬號 |
| 表級 | GRANT SELECT ON `business_db`.`sensitive_log` TO 'audit'@'%'; | 審計、只讀報表 |
| 列級 | GRANT SELECT (id, name, email) ON `users` TO 'api_user'@'%'; | 敏感字段隔離(身份證、密碼哈希) |
| 存儲過程 | GRANT EXECUTE ON PROCEDURE `sp_export_data` TO 'etl_user'@'%'; | ETL、定時任務 |
GRANT OPTION 外所有權限。-- 1. 只讀報表賬號 (開發/分析師)
CREATE USER 'ro_analyst'@'10.0.%.%' IDENTIFIED BY 'ReadOnly#2024!';
GRANT SELECT ON `report_db`.* TO 'ro_analyst'@'10.0.%.%';
GRANT SELECT ON `business_db`.* TO 'ro_analyst'@'10.0.%.%';
-- 限制資源
ALTER USER 'ro_analyst'@'10.0.%.%' WITH MAX_QUERIES_PER_HOUR 1000 MAX_CONNECTIONS_PER_HOUR 10;
-- 2. 應用讀寫賬號 (Web 服務器 IP 段)
CREATE USER 'app_rw'@'10.0.2.%' IDENTIFIED BY 'AppRw@ComplexPass2024!';
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON `business_db`.* TO 'app_rw'@'10.0.2.%';
-- 禁止 DDL (防止應用誤執行 ALTER/DROP)
-- 需要 DDL 時由 DBA 手動執行或走變更流程
-- 3. 備份賬號
CREATE USER 'backup'@'10.0.3.10' IDENTIFIED BY 'BackupOnly#LongPass!';
GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION CLIENT, PROCESS ON *.* TO 'backup'@'10.0.3.10';
-- mysqldump --single-transaction 需 RELOAD(FLUSH TABLES), LOCK TABLES, REPLICATION CLIENT(獲取 GTID/Position)
FLUSH PRIVILEGES;
-- 查看指定用戶權限
SHOW GRANTS FOR 'app_rw'@'10.0.2.%';
-- 查看當前登錄用戶權限
SHOW GRANTS FOR CURRENT_USER();
-- 審計所有用戶 (排除系統用戶)
SELECT User, Host, plugin, authentication_string FROM mysql.user WHERE User NOT IN ('mysql.sys','mysql.session','root');
-- 查看全局權限
SELECT * FROM mysql.user WHERE User='app_rw'\G
-- 修改密碼 (推薦)
ALTER USER 'app_rw'@'10.0.2.%' IDENTIFIED BY 'NewComplexPass#2024!';
-- 修改密碼過期策略
ALTER USER 'app_rw'@'10.0.2.%' PASSWORD EXPIRE INTERVAL 180 DAY;
-- 鎖定/解鎖賬號 (8.0+)
ALTER USER 'app_rw'@'10.0.2.%' ACCOUNT LOCK;
ALTER USER 'app_rw'@'10.0.2.%' ACCOUNT UNLOCK;
-- 修改主機限制 (需刪除重建,或直接 UPDATE mysql.user 後 FLUSH PRIVILEGES)
-- 刪除單個用戶
DROP USER 'legacy_user'@'%';
-- 批量刪除
DROP USER 'test1'@'%', 'test2'@'localhost';
-- 8.0 支持 IF EXISTS 避免報錯
DROP USER IF EXISTS 'ghost_user'@'%';
效果:自動從所有權限表 (user, db, tables_priv, columns_priv, procs_priv, proxies_priv) 中清理相關記錄,**無需手動 FLUSH PRIVILEGES**。
'user'@'%' 用於生產核心業務,限定應用服務器 IP 段 (如 10.0.2.%)。validate_password 插件,強制複雜度、過期輪換、鎖定策略。SHOW GRANTS 對比基線,檢查異常授權。caching_sha2_password,舊驅動需指定 mysql_native_password 或升級驅動。