MySQL创建只读应用账号需显式授予SELECT权限,限定IP网段如'192.168.1.%',禁用通配符主机名;执行FLUSH PRIVILEGES生效;避免GRANT ALL后回收,并定期核查DBA最小权限与高危权限。

MySQL里怎么创建只读应用账号
应用账号不该有DROP、CREATE或ALTER权限,更不能碰mysql系统库。最稳妥的做法是显式授予SELECT,而不是用GRANT ALL再回收——MySQL的权限回收机制不保证完全覆盖。
- 先用管理账号登录:
mysql -u root -p - 创建应用用户:
CREATE USER 'app_reader'@'192.168.1.%' IDENTIFIED BY 'strong_pass_2024'; - 只授指定库的读权限:
GRANT SELECT ON myapp_db.* TO 'app_reader'@'192.168.1.%'; - 立刻执行:
FLUSH PRIVILEGES;(否则权限不生效)
别用'app_reader'@'%'——通配符主机名会允许任意IP连接,增加爆破风险;生产环境必须限定网段或具体IP。
管理账号该保留哪些最小权限
DBA账号不是越全能越好。比如日常备份不需要FILE权限,而误开这个权限会让攻击者通过SELECT ... INTO OUTFILE写入Web目录下的PHP木马。
- 必要权限:
SELECT、INSERT、UPDATE、DELETE、CREATE、DROP、ALTER、INDEX、CREATE VIEW、SHOW VIEW - 高危权限慎开:
FILE、PROCESS、SUPER、REPLICATION CLIENT(除非真在做主从诊断) - 绝对禁止:
GRANT OPTION(避免权限被二次扩散)、SHUTDOWN、CREATE USER(除非是专职账号管理员)
用SHOW GRANTS FOR 'dba_admin'@'localhost';定期核对,你会发现很多老账号悄悄继承了当年调试时加的冗余权限。
应用账号连不上?检查这三处常见断点
权限配置完连不上,90%不是SQL语法错,而是网络层或认证插件卡住了。
- 确认用户host匹配:应用服务器IP是
192.168.1.45,但账号建的是'app_reader'@'192.168.1.0/24'?不行——MySQL不支持CIDR写法,得用'app_reader'@'192.168.1.%' - 检查认证插件:
SELECT host, user, plugin FROM mysql.user WHERE user = 'app_reader';如果plugin是caching_sha2_password,而客户端是旧版MySQL Connector/J 5.1,就会静默拒绝——降级为mysql_native_password:ALTER USER 'app_reader'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY 'xxx'; - 防火墙没放行3306端口,或者云厂商安全组规则没更新(比MySQL配置更容易被忽略)
权限变更后为什么应用还是报错Access denied
不是权限没生效,而是MySQL缓存了旧的权限映射。它不会自动监听mysql.user表变化,必须手动刷新。
-
FLUSH PRIVILEGES;是必须步骤,且要在执行GRANT/REVOKE之后立即运行 - 如果用
mysqldump恢复过mysql库,权限表会被覆盖,FLUSH PRIVILEGES;就更不能省 - 某些容器化部署中,MySQL重启后权限丢失——说明你把用户数据存在了临时卷,得把
/var/lib/mysql/mysql持久化
权限分级不是设一次就完事的事。应用迭代会新增表,DBA轮岗会改密码,中间任何一环漏掉GRANT或FLUSH,故障就藏在下次上线后的第一个慢查询里。











