PostgreSQL 给用户授予只读权限,推荐创建一个只读角色(role),再授权给用户。不要直接给用户逐个授权,方便后续管理
方案1:给已有用户授予指定数据库只读权限(推荐)
假设:
- 数据库:
mydb - 用户:
readonly_user - schema:
public
登录 PostgreSQL:
psql -U postgres -d mydb
1. 创建只读角色
CREATE ROLE readonly_role;
2. 授权连接数据库
GRANT CONNECT ON DATABASE mydb TO readonly_role;
3. 授权 schema 访问
GRANT USAGE ON SCHEMA public TO readonly_role;
4. 授权已有表只读
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_role;
5. 授权未来创建的表自动只读
非常重要:
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO readonly_role;
6. 把角色授权给用户
GRANT readonly_role TO readonly_user;
完成
验证权限
切换用户:
psql -U readonly_user -d mydb
测试查询:
SELECT * FROM users LIMIT 10;
应该成功
测试写入:
CREATE TABLE test(id int);
应该失败:
ERROR: permission denied for schema public
方案2:所有数据库所有 schema 只读
适合:
- BI平台
- 数据分析账号
- Grafana
- Superset
- 数据同步
进入 postgres:
psql -U postgres
执行:
GRANT CONNECT ON DATABASE mydb TO readonly_user;
进入数据库:
\c mydb
执行:
GRANT USAGE ON SCHEMA public TO readonly_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_user;
ALTER DEFAULT PRIVILEGES
GRANT SELECT ON TABLES TO readonly_user;
方案3:PostgreSQL 14/15/16 推荐写法
创建专用只读账号:
CREATE USER report_user
WITH PASSWORD 'StrongPassword';
创建角色:
CREATE ROLE pg_readonly;
授权:
GRANT CONNECT ON DATABASE mydb TO pg_readonly;
\c mydb
GRANT USAGE ON SCHEMA public TO pg_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO pg_readonly;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO pg_readonly;
ALTER DEFAULT PRIVILEGES
IN SCHEMA public
GRANT SELECT ON TABLES TO pg_readonly;
绑定:
GRANT pg_readonly TO report_user;
如果有多个 schema
例如:
\dn
看到:
public
sales
finance
执行:
GRANT USAGE ON SCHEMA sales, finance TO readonly_role;
GRANT SELECT ON ALL TABLES IN SCHEMA sales, finance TO readonly_role;
如果使用 RDS / 云数据库
通常还需要:
GRANT pg_read_all_data TO readonly_user;
PostgreSQL 14+ 内置只读角色:
pg_read_all_data
使用:
GRANT pg_read_all_data TO readonly_user;
它包含:
- 所有表 SELECT
- 所有 sequence SELECT
- 所有 schema USAGE
但是:
不包含:
- CONNECT
所以建议:
GRANT CONNECT ON DATABASE mydb TO readonly_user;
GRANT pg_read_all_data TO readonly_user;
查看用户权限
查看用户:
\du
查看表权限:
\dp
查看角色继承:
SELECT
member.rolname,
role.rolname
FROM pg_auth_members
JOIN pg_roles member
ON member.oid=member
JOIN pg_roles role
ON role.oid=roleid;
生产环境推荐(你的 PostgreSQL / 企业平台场景)
建议统一:
postgres
|
+-- pg_dba
|
+-- pg_rw_role
|
+-- pg_readonly_role
|
+-- grafana_user
+-- bi_user
+-- report_user
不要直接:
GRANT SELECT ON ALL TABLES TO user;
后期表扩展会不好维护