讲解

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。