mysql grant命令如何使用_mysql授权实战方法

来源:这里教程网 时间:2026-02-28 20:47:27 作者:

grant 命令的基本语法和权限粒度

MySQL 的

GRANT
不是“一键授权”,它严格区分权限层级:全局(
*
)、数据库(
db_name.*
)、表(
db_name.table_name
)、列(
(col1,col2)
)甚至存储过程。用错层级会导致权限不生效或过度开放。

最常用的是数据库级授权,例如给用户

'appuser'@'192.168.1.%'
myapp_db
的全部操作权限:

GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO 'appuser'@'192.168.1.%';
必须显式指定主机名(不能只写
'appuser'
),否则默认为
'appuser'@'localhost'
,远程连不上
权限列表不支持通配符如
CRUD
,必须写全或用
ALL PRIVILEGES
(慎用)
执行后需运行
FLUSH PRIVILEGES;
才能立即生效(仅在直接改系统表后才必需;正常
GRANT
会自动刷新)

常见错误:Access denied 但账号明明存在

典型现象是创建了用户、执行了

GRANT
,应用仍报
Access denied for user 'xxx'@'yyy'
。根本原因往往是主机名匹配失败:

客户端连接时用的是 IP,但
GRANT
给的是
'user'@'%.example.com'
→ DNS 解析失败或反向解析未配置,MySQL 按 IP 匹配,找不到对应账户
用户从本地连却授权给了
'user'@'127.0.0.1'
,而 MySQL 把
localhost
视为 socket 连接,走的是
'user'@'localhost'
这条记录(二者权限独立)
GRANT
后忘了
IDENTIFIED BY
设置密码,或密码策略不兼容(如 MySQL 8.0 默认用
caching_sha2_password
插件,旧客户端不支持)

MySQL 8.0+ 的角色(ROLE)替代重复授权

频繁给多个用户授相同权限(如所有运维人员都要有

SELECT
权限),硬写
GRANT
易出错且难维护。MySQL 8.0 引入角色机制,可先建角色再批量赋予:

CREATE ROLE 'readonly_role';<br>GRANT SELECT ON *.* TO 'readonly_role';<br>GRANT 'readonly_role' TO 'dev1'@'%', 'dev2'@'%';<br>SET DEFAULT ROLE 'readonly_role' TO 'dev1'@'%';
角色本身不带密码,也不可直接登录,纯粹是权限容器 用户被赋予角色后,需执行
SET ROLE
或设为默认角色才真正启用权限
回收权限只需
DROP ROLE
REVOKE ... FROM role_name
,比逐个用户操作安全

最小权限原则下的实用授权组合

生产环境绝不该用

GRANT ALL PRIVILEGES
。以下是几个真实场景的推荐组合:

Web 应用后端(PHP/Java):
GRANT SELECT, INSERT, UPDATE, DELETE, EXECUTE ON app_db.* TO 'webapp'@'10.0.2.%';
—— 禁用
DROP
CREATE
ALTER
,防止误删表或注入建库
备份账号(mysqldump):
GRANT SELECT, LOCK TABLES, RELOAD ON *.* TO 'backup'@'10.0.1.5';
——
RELOAD
是为了
FLUSH LOGS
LOCK TABLES
保证一致性,不需要写权限
监控账号(Prometheus exporter):
GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'monitor'@'10.0.3.%';
—— 只读状态信息,禁用任何数据访问权限

权限缩放不是靠直觉,得看具体命令需要什么权限。比如

SHOW CREATE VIEW
需要
SHOW VIEW
权限,而不仅是
SELECT
;调用函数需要
EXECUTE
,哪怕函数内部只做
SELECT

相关推荐