在MySQL数据库运维中,合理控制不同账号能访问哪些库、哪些表以及能执行什么操作,是安全管理的核心环节。MySQL采用基于权限表的访问控制模型,所有用户信息、库表权限都存放在系统库mysql的若干表中,服务端启动时会把这些表加载到内存,连接请求到来时按内存中的规则校验。因此给用户设置权限,本质上就是往这些权限表里写记录,并让实例感知到变更。

创建用户与host限制的基本逻辑
在授予权限之前,必须先存在对应的用户账号。MySQL的用户身份由用户名和host两部分共同决定,例如 'dev'@'localhost' 与 'dev'@'192.168.0.1' 是两个完全独立的账号。很多连接失败问题并不是权限没给,而是客户端所在IP与host不匹配,服务端认为该用户不存在。使用create user语句可以显式指定host,避免使用默认的模糊匹配带来的安全隐患。
下面示例创建一个只能从本地连接的普通账号,并设置密码:
CREATE USER 'dev'@'localhost' IDENTIFIED BY 'StrongPass@123';
如果希望该用户能从指定网段连接,可以写成 'dev'@'192.168.0.%',百分号代表任意字符。创建后该用户仅拥有最基础的usage权限,也就是能登录但不能看任何数据。此时若直接尝试查询业务库会被拒绝,必须进一步授权。
使用grant进行分级授权
grant是MySQL提供的权限分配语句,它比手工改表更安全直观。权限层级分为全局、库级、表级、列级甚至存储过程级。例如给dev用户授予test库下所有表的查询和写入权限,可执行:
GRANT SELECT, INSERT, UPDATE ON test.* TO 'dev'@'localhost';
若只需开放某张表的特定列,可写成列级授权,这样即使账号泄露也不会批漏敏感字段。grant执行成功后会自动将新规则写入mysql库对应表,并在多数版本中自动生效,无需手动flush。但如果是直接修改权限表的方式,则必须执行 FLUSH PRIVILEGES; 命令通知服务端重载。
授权完成后,用show grants命令核验是最稳妥的习惯:
SHOW GRANTS FOR 'dev'@'localhost';
该命令会列出此用户当前全部生效授权语句。需要留意的是,grant本身不会创建用户(在旧版本中带IDENTIFIED BY子句时可顺带创建,但新版本已废弃该用法),所以严格流程是先create user再grant。另外,with grant option参数可让用户将自己的权限转授他人,生产环境应谨慎开启,避免权限无序扩散。
权限回收与账号清理
当人员离职或业务下线时,要及时回收权限。revoke语句与grant对应,语法结构相似但方向相反。例如收回dev在test库上的更新权:
REVOKE UPDATE ON test.* FROM 'dev'@'localhost';
revoke只删权限不删账号,用户依然能登录。若要彻底移除账号,应使用drop user语句。很多误操作是执行了revoke all privileges却以为用户已消失,结果残留空账号成为连接入口。权限回收也要注意作用范围,列级授权需要用对应的列级revoke语法,否则会报权限不匹配错误。
从安全角度,建议遵循最小权限原则:业务程序账号只给所需库的DML,不给DDL;管理账号限定来源IP并开启SSL。定期用 SELECT * FROM mysql.user 排查是否有host为'%'的高权账号,能有效降低被拖库风险。掌握create user、grant、revoke、drop user这套组合,基本覆盖日常MySQL用户权限管理的全部场景。