PostgreSQL 给用户授予只读权限,推荐创建一个只读角色(role),再授权给用户。不要直接给用户逐个授权,方便后续管理
方案1:给已有用户授予指定数据库只读权限(推荐)
假设:
- 数据库:
mydb - 用户:
readonly_user - schema:
public
登录 PostgreSQL:
psql -U postgres -d mydb1. 创建只读角色
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;后期表扩展会不好维护
方案4:
PostgreSQL(包括你之前使用的 PolarDB PostgreSQL 15)创建只读用户,可以按下面步骤操作。
1. 创建只读账号
将readonly_user、StrongPassword123!和your_database替换成实际值。
-- 1. 创建用户 CREATE USER readonly_user WITH PASSWORD 'StrongPassword123!'; -- 2. 允许连接指定数据库 GRANT CONNECT ON DATABASE your_database TO readonly_user;2. 授予现有表的只读权限
先切换到目标数据库,再执行:
-- 允许使用 public schema GRANT USAGE ON SCHEMA public TO readonly_user; -- 授予现有表的查询权限 GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_user; -- 授予现有序列的读取权限(如需要) GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO readonly_user;如果数据库中还有其他 schema,例如app,也需要单独授权:
GRANT USAGE ON SCHEMA app TO readonly_user; GRANT SELECT ON ALL TABLES IN SCHEMA app TO readonly_user;3. 自动授权未来新建的表
如果以后会创建新表,需要给创建这些表的角色设置默认权限。例如,表由postgres用户创建:
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA public GRANT SELECT ON TABLES TO readonly_user;注意:默认权限只对指定创建角色未来新建的对象生效;如果还有其他角色创建表,也要分别设置。
4. 验证只读权限
使用readonly_user登录后执行:
SELECT * FROM public.your_table LIMIT 10;应当可以查询。再测试写入:
CREATE TABLE public.readonly_test (id int);预期会因权限不足而失败。
5. 可选:限制连接数
ALTER USER readonly_user CONNECTION LIMIT 10;