MySQL 透過 mysql 系統庫中的五張權限表(user、db、table_priv、columns_priv、host)實現細粒度存取控制。本文以實戰案例串聯建立用戶、分層授權、密碼管理、權限回收、帳號清理全生命週期,並整理權限分層模型與常用指令速查表,助你建立安全合規的資料庫存取體系。
| 表名 | 層級 | 說明 |
|---|---|---|
| user | 全域 | 記錄可連線的帳號與全域權限 |
| db | 資料庫 | 各帳號在各資料庫的操作權限 |
| table_priv | 資料表 | 表級操作權限 |
| columns_priv | 欄位 | 欄位級操作權限 |
| host | 主機+資料庫 | 輔助 db 表,針對特定主機細化資料庫權限(不受 GRANT/REVOKE 影響) |
mysql -u root -p mysql> GRANT ALL ON prod.* TO 'tom'@'%' IDENTIFIED BY 'tom' WITH GRANT OPTION;
WITH GRANT OPTION 讓 tom 可將自己擁有的權限轉授他人。
mysql> CREATE USER 'tom1' IDENTIFIED BY 'tom1', 'tom2' IDENTIFIED BY 'tom2';
# tom 本地登入失敗?見「匿名用戶遮蔽問題」章節 mysql -u tom -ptom -h localhost prod mysql> GRANT SELECT ON prod.* TO 'tom1'@'%'; mysql> GRANT SELECT, INSERT, UPDATE ON prod.* TO 'tom2'@'%';
C:\> mysql -h 192.168.8.240 -u tom2 -ptom2 mysql> USE prod; mysql> INSERT INTO t1 VALUES (40, 'john'); -- 成功 mysql> UPDATE t1 SET name='ellen' WHERE id=40; -- 成功 mysql> DELETE FROM t1; -- ERROR 1142: DELETE command denied
mysql> REVOKE UPDATE ON prod.* FROM 'tom2'@'%';
重新登入後 UPDATE 即被拒絕。
現象:帳號 'tom'@'%' 遠程正常,本地 mysql -u tom -ptom 報 Access denied for user 'tom'@'localhost'。
原因:MySQL 認證排序規則——Host 匹配精確度優先,再比 User 非空優先。mysql_install_db 預設建立匿名用戶 ''@'localhost',Host 精確匹配 localhost,優先級高於 'tom'@'%',導致本地登入實際走匿名用戶驗證(無密碼)。
解決:
GRANT ALL ON prod.* TO 'tom'@'localhost' IDENTIFIED BY 'tom';DROP USER ''@'localhost'; FLUSH PRIVILEGES;(兼顧安全)| 方法 | 指令範例 | 適用對象 |
|---|---|---|
| SET PASSWORD | SET PASSWORD FOR 'tom1'@'%' = PASSWORD('oracle'); | Root 改他人密碼 |
| mysqladmin | mysqladmin -u tom1 -poldpass password newpass | 命令列自助改密 |
| UPDATE user 表 | UPDATE mysql.user SET Password=PASSWORD('new') WHERE user='tom1'; FLUSH PRIVILEGES; | 批次/腳本修改 |
普通用戶自改密碼:SET PASSWORD = PASSWORD('newpass');(無需指定用戶名)。
-- 1. 回收所有權限 REVOKE ALL ON prod.* FROM 'tom2'@'%'; -- 2. 刪除帳號 DROP USER 'tom2'@'%'; -- 3. 刷新生效 FLUSH PRIVILEGES;
MySQL 權限可作用於 5 個層次:
GRANT ALL ON *.* TO 'dba'@'localhost';GRANT SELECT ON testdb.* TO 'dev'@'%';GRANT SELECT, INSERT ON testdb.orders TO 'app'@'%';GRANT SELECT(id, name) ON testdb.users TO 'report'@'%';GRANT EXECUTE ON PROCEDURE testdb.proc TO 'dev'@'%';-- 唯讀報表帳號
GRANT SELECT ON prod.* TO 'report'@'%' IDENTIFIED BY 'pass';
-- 開發人員(DDL + DML)
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX, CREATE VIEW, SHOW VIEW,
CREATE ROUTINE, ALTER ROUTINE, EXECUTE, CREATE TEMPORARY TABLES
ON devdb.* TO 'dev'@'192.168.0.%' IDENTIFIED BY 'pass';
-- DBA(單庫全權)
GRANT ALL PRIVILEGES ON testdb.* TO 'dba'@'localhost' IDENTIFIED BY 'pass';
-- 超級 DBA(全例項全權)
GRANT ALL ON *.* TO 'root'@'localhost' IDENTIFIED BY 'pass' WITH GRANT OPTION;
%:匹配所有主機(某版本不含 localhost,建議雙建)localhost:Unix Socket 連線,不解析 IP127.0.0.1:TCP/IP 回環,僅本機::1:IPv6 回環192.168.1.%、%.example.com:IP 段 / 域名通配任何直接操作 mysql.user、mysql.db 等權限表(INSERT/UPDATE/DELETE)後,或為確保 GRANT/REVOKE 即時生效,務必執行:
FLUSH PRIVILEGES;
建立「最小權限、分層授權、定期審計、及時清理」的權限治理閉環,是資料庫安全的基石。