讲解
MySQL 的账号由「用户名@主机」两部分组成:'alice'@'localhost' 和 'alice'@'%' 是两个完全独立的账号,可以有不同的密码和权限。主机部分支持 % 通配,'alice'@'192.168.1.%' 只允许该网段连接。这个设计是安全的第一道闸门——root 默认只有 'root'@'localhost',意味着 root 根本不能远程登录,请务必保持这样。
权限用 GRANT 授予、REVOKE 回收,层级从粗到细:全局(.)、库级(appdb.*)、表级(appdb.orders)、列级。常用权限有 SELECT、INSERT、UPDATE、DELETE、CREATE、DROP、ALTER、INDEX,管理类的有 REPLICATION SLAVE、SUPER 等。8.0 的重要变化:GRANT 不再能隐式创建用户,必须先 CREATE USER 再 GRANT;还引入了 ROLE(角色),可以把一组权限打包授予多个账号,适合人多的团队。
核心纪律是最小权限原则:应用账号只给它用到的库、用到的操作。一个只读写业务库的应用账号被注入攻击,损失也就是这个库;给了 GRANT ALL ON . 的账号,整个实例都完了。另外注意 GRANT/REVOKE 立即生效,不需要 FLUSH PRIVILEGES——只有直接改 mysql.user 系统表才需要它,而你不该那么做。
示例
先看看实例上有哪些账号、各用什么认证插件(8.0 默认 caching_sha2_password):
SELECT user, host, plugin FROM mysql.user;
创建一个只允许读业务库的应用账号:先建库建用户,再授予最小权限,最后 SHOW GRANTS 核对:
CREATE DATABASE IF NOT EXISTS appdb CHARACTER SET utf8mb4;
CREATE USER IF NOT EXISTS demo_alice@'%' IDENTIFIED BY 'Alice#Strong2026';
GRANT SELECT ON appdb.* TO demo_alice@'%';
SHOW GRANTS FOR demo_alice@'%';
权限回收、改密码、清理演示账号和库:
REVOKE SELECT ON appdb.* FROM demo_alice@'%';
ALTER USER demo_alice@'%' IDENTIFIED BY 'Alice#NewPass2026';
DROP USER IF EXISTS demo_alice@'%';
DROP DATABASE IF EXISTS appdb;
常见坑
- 图省事 GRANT ALL ON .:应用账号拿到 DROP、SUPER 权限,一次注入或一次程序 bug 就能毁掉整个实例。按库、按操作授最小集。
- 把 root 开放成 'root'@'%':远程 root 是入侵者的头号目标。管理操作用 SSH 跳板或专用管理账号,root 保持仅本机。
- 以为 % 包含 localhost:'alice'@'%' 不匹配来自本机的连接(localhost 走 socket)。两个来源都要就建两个账号。
- 直接 INSERT/UPDATE mysql.user 表:绕过了权限系统的内部维护,容易搞出不一致,还得手动 FLUSH PRIVILEGES。一切用 CREATE USER/GRANT/ALTER USER。
小结
账号是 user@host 的组合;先 CREATE USER 再 GRANT,权限按库按操作最小化;REVOKE 回收、SHOW GRANTS 核对,GRANT 立即生效。下一章看服务器的行为由什么决定:配置文件 my.cnf。