mysql中创建只读账号需用create user配合grant select显式授权,如create user 'rpt_readonly'@'192.168.10.%' identified by 'strong_pass_2024'; grant select on sales_db.* to 'rpt_readonly'@'192.168.10.%'; flush privileges;。
mysql 中如何创建只读账号并限制到指定数据库
报表系统不需要写权限,直接给开发账号或 root 权限等于埋雷。最稳妥的做法是用 create user 配合 grant select 显式授权,而不是靠角色继承或模糊匹配。
- 先用
CREATE USER 'rpt_readonly'@'192.168.10.%' IDENTIFIED BY 'strong_pass_2024';创建账号,注意主机段要精确——用%虽方便,但若报表服务固定在某网段,写成'192.168.10.%'更安全 - 执行
GRANT SELECT ON `sales_db`.* TO 'rpt_readonly'@'192.168.10.%';,必须用反引号包裹数据库名,否则遇到带中划线的库名(如bi-report)会报错ERROR 1064 (42000) - 别漏掉
FLUSH PRIVILEGES;,MySQL 8.0+ 在某些部署模式下(比如用 config-file 启动且未启用skip-grant-tables)仍需手动刷新,否则权限不生效
PostgreSQL 里避免误授 pg_read_all_data 角色
PostgreSQL 的 pg_read_all_data 看似方便,但它允许读取所有数据库里的所有表,包括 pg_catalog 和其他业务库——报表账号根本不需要查系统表或跨库数据,授这个角色等于绕过隔离。
- 正确做法是连库授权:
GRANT CONNECT ON DATABASE sales_db TO rpt_readonly;,再进库执行\c sales_db,然后GRANT USAGE ON SCHEMA public TO rpt_readonly;和GRANT SELECT ON ALL TABLES IN SCHEMA public TO rpt_readonly; - 如果后续新增表,记得补上
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO rpt_readonly;,否则新表默认无权限 - PostgreSQL 不支持通配符库名授权(如
GRANT SELECT ON DATABASE *),想覆盖多个库必须逐个操作
读写分离中间件(如 MyCat、ShardingSphere)对账号权限的隐性要求
这类中间件本身不校验权限,但会把客户端发来的 SQL 原样转发到后端节点。如果后端主库只给了 SELECT 权限,而中间件把 INSERT 请求也路由过去,就会直接报错 ERROR 1142 (42000): INSERT command denied——这不是中间件配置问题,是账号权限没对齐路由策略。
- 确认中间件的读写分离规则:比如 MyCat 的
schema.xml中<datanode></datanode>是否将报表账号的连接强制指向了readHost;如果不是,即使账号只有 SELECT 权,也可能因路由到写节点而被拒绝 - ShardingSphere 的
props.sql-show=true可以打印实际下发语句,用来验证“报表查询是否真走读库”,比单纯看账号权限更可靠 - 某些旧版中间件(如 MyCat 1.6)会复用连接池中的连接,若池中混入了带写权限的连接,可能让只读账号意外获得写能力——建议为报表单独配一个独立的数据源和连接池
权限变更后如何快速验证是否生效
别只依赖 SHOW GRANTS FOR 'rpt_readonly'@'%';,它只显示授权语句,不反映真实行为。得用报表服务的真实连接方式去测,尤其是带连接池或长连接的场景。
- 用报表系统使用的驱动和参数直连测试:例如用
mysql -u rpt_readonly -p -h db-proxy -P 3306 sales_db -e "SELECT COUNT(*) FROM orders LIMIT 1;",观察是否返回结果而非权限错误 - 故意执行写操作验证隔离性:
INSERT INTO tmp_test VALUES(1);应明确报错ERROR 1142 (42000): INSERT command denied,而不是静默失败或超时 - 如果报表工具支持连接测试(如 Tableau 的 “Test Connection” 按钮),务必点一下——有些工具会在后台自动执行
SELECT 1或SHOW TABLES,这些语句可能触发权限检查
权限配置真正麻烦的不是创建步骤,而是账号生命周期管理:应用下线后忘了回收权限、临时调试开了写权限却没关、中间件升级后路由逻辑变化导致权限失效……这些点往往在故障发生时才被发现。










