mysql如何配置只读用户_mysql最小权限应用示例

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

只读用户必须授予哪些权限

MySQL 的只读访问不是靠一个

READ ONLY
权限实现的,而是通过显式授予有限的、不带写能力的权限组合。核心是:只给
SELECT
,不给
INSERT
UPDATE
DELETE
DROP
CREATE
ALTER
等任何修改类权限。

常见错误是误加

SHOW VIEW
LOCK TABLES
——它们虽不直接写数据,但可能暴露结构或阻塞业务,生产环境应按需开启。

SELECT
是唯一必需的基础权限
如需查看表结构,额外加
SHOW CREATE TABLE
(注意:不是
SHOW DATABASES
如需执行
EXPLAIN
或查看执行计划,需
PROCESS
权限(仅限本地调试,线上慎开)
跨库 JOIN 查询时,目标库所有涉及的表都要单独授权
SELECT

创建最小权限只读用户的完整命令

假设数据库名为

app_db
,用户名为
ro_user
,密码为
'secure_ro_pass'
,只允许从内网
192.168.10.%
连接:

CREATE USER 'ro_user'@'192.168.10.%' IDENTIFIED BY 'secure_ro_pass';
GRANT SELECT ON app_db.* TO 'ro_user'@'192.168.10.%';
FLUSH PRIVILEGES;

关键点:

不要用
GRANT SELECT ON *.*
—— 这会暴露系统库(如
information_schema
),存在信息泄露风险
主机名尽量具体,避免用
'%'
;若必须通配,请确认网络层已限制访问源
FLUSH PRIVILEGES
在大多数情况下非必需(只要用
GRANT
语句就自动生效),但部分旧版本或特殊部署下建议保留

验证只读权限是否生效

用新用户登录后,执行以下检查:

能成功运行
SELECT COUNT(*) FROM app_db.users;
执行
INSERT INTO app_db.users (...) VALUES (...);
应报错:
ERROR 1142 (42000): INSERT command denied to user
执行
SHOW GRANTS FOR CURRENT_USER;
确认返回结果中只有
SELECT
权限,无其他 DML/DCL 权限
尝试
USE mysql;
后查
user
表——应因无权限拒绝,而非返回空结果(空结果说明有权限但没数据,是严重误配置)

应用连接池中要注意的兼容性问题

某些 ORM 或连接池(如 HikariCP、Druid)在初始化时会默认执行

SELECT 1
SELECT @@sql_mode
等探测语句。这些语句本身没问题,但若连接字符串中指定了
database=xxx
而该库未被授权,就会连接失败。

解决方案:

确保
GRANT SELECT ON <db_name>.*</db_name>
中的库名与应用配置完全一致(大小写敏感取决于 OS 和
lower_case_table_names
设置)
避免在 JDBC URL 中指定不存在或未授权的
database
参数;可改用
useSSL=false&serverTimezone=UTC
等纯连接参数
Spring Boot + MyBatis 场景下,
spring.sql.init.mode=never
必须显式设置,否则启动时可能尝试建表

最易忽略的是:MySQL 8.0+ 默认启用

caching_sha2_password
插件,而旧版客户端可能不支持——此时即使权限正确,也会卡在认证阶段,报错类似
Public Key Retrieval is not allowed
。需确认客户端驱动版本或改用
mysql_native_password
认证方式。

相关推荐