MySQL如何创建受限权限只读账号?

作者:技术拾光

时间:2026-07-15

浏览:646

MySQL创建只读账号:库表级别授予SELECT,并单独授予USAGE连接权限。库名含特殊字符用反引号,跨库JOIN需显式授权;MySQL8.0+需额外授权INFORMATION_SCHEMA;CREATEUSER与GRANT分两步;只读账号无法执行SELECT...FORUPDATE。

文章目录
MySQL的权限体系,本质上是一套白名单机制。创建只读账号的关键在于:不是限制用户不能写什么,而是明确允许他能读什么。一旦理解这个原则,许多问题便迎刃而解。

MySQL如何创建受限权限只读账号?

先说结论:`GRANT SELECT ON *.*`这种写法,表面上授予了整个实例的读权限,实际上却隐藏了风险——它会暴露`mysql`、`performance_schema`等系统库的结构。真正的只读权限必须精确到库表级别,即`GRANT SELECT ON mydb.*`。这是一个不能忽视的细节。

指定库表范围授予SELECT权限,不能仅靠“未授予写权限”来确保安全

以下几个看似简单却容易出错的陷阱值得警惕: - 库名若包含特殊字符,例如`my-db`,使用单引号包裹写为`'my-db'.*`会直接导致语法错误。正确做法是使用反引号:`my-db`.*,或者直接使用不含特殊字符的库名。 - 跨库JOIN查询是一个隐形陷阱。例如`SELECT * FROM db1.t1 JOIN db2.t2`,如果只授予了`db1`的读权限,而`db2`未授权,查询会报错。两个库都需要显式执行`GRANT SELECT`。 - 许多人认为`REVOKE INSERT`可以加固只读权限,但这其实是多余操作——未授予的权限本来就不存在,回收操作反而容易遗漏`TRUNCATE`、`LOCK TABLES`等隐式写操作。权限管理采用“做加法”比“做减法”更稳妥。

必须单独授予USAGE权限,否则用户无法连接

`GRANT SELECT`只控制“能做什么”,不控制“能否登录”。这就像给了你钥匙,却不告诉你门在哪里。 如果没有`USAGE`权限,密码验证通过后立即断开,报错`ERROR 1045 (28000): Access denied`。在MySQL 8.0及以上版本中,`USAGE`不会被自动附带,因此这一步绝对不能省略。 - 补授权语句:`GRANT USAGE ON *.* TO 'ro_user'@'192.168.10.%'` - `USAGE`是纯连接权限,不具备任何实际操作能力,必须与`SELECT`分开授予 - 主机名不要使用`'%'`放行所有IP,生产环境建议限定内网段,例如`'192.168.10.%'`

SHOW CREATE TABLE失败?需显式授权INFORMATION_SCHEMA

许多ORM框架、监控工具或DBA在查看表结构时会执行`SHOW CREATE TABLE t1`。该语句底层依赖`information_schema.TABLES`和`information_schema.COLUMNS`的`SELECT`权限。MySQL 5.7默认允许,但8.0及以上版本已彻底收紧。 如果只授予了业务库权限,执行`SHOW CREATE TABLE`就会报错:`ERROR 1142 (42000): SELECT command denied`。 - 解决方法很简单:`GRANT SELECT ON INFORMATION_SCHEMA.* TO 'ro_user'@'192.168.10.%'` - 不需要全量开放`performance_schema`或`sys`,除非明确需要其视图。

CREATE USER和GRANT必须分两步执行,不能合并为一条语句

从MySQL 5.7开始,`CREATE USER`不再支持同时附带`GRANT`。强行写在一起会直接报错:`ERROR 1064 (42000): You have an error in your SQL syntax`。 - 正确做法分两步:先执行`CREATE USER 'ro_user'@'192.168.10.%' IDENTIFIED BY 'strong-pass-2024';`,再执行`GRANT SELECT ON myapp_db.* TO 'ro_user'@'192.168.10.%';` - 密码必须用单引号包裹,且不能是纯数字或简单字符串。MySQL 8.0及以上版本默认校验密码强度,太弱会被拒绝创建。 - 执行完`GRANT`后,无需手动执行`FLUSH PRIVILEGES`——因为`GRANT`语句会自动刷新权限缓存,除非直接修改过`mysql.user`表。 最后,还有一个容易被忽略的点:只读账号能执行`SELECT ... FOR UPDATE`吗?答案是**不能**——它触发锁机制,相当于需要`SELECT` + `LOCK TABLES`权限,而只读账号没有后者,直接报错`ERROR 1142`。但值得警惕的是:如果用户拥有`EXECUTE`权限,或能访问`SQL SECURITY DEFINER`视图,仍可能间接触发写操作。权限的边界,远比想象中复杂。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章