由 John Doe 八月 1, 2025
你想要对配置参数的设置进行细粒度的权限管理吗?现在,PostgreSQL 可以做到这一点了。
特性提交日志
允许授予 GUC 参数的 SET 和 ALTER SYSTEM 权限。
此补丁允许非超级用户在获得明确授权的情况下设置 “PGC_SUSET” 参数。也可以授予针对特定参数执行 ALTER SYSTEM SET/RESET 的权限。
此类权限是实例级别的,而非按数据库划分。它们在新的全局系统表 pg_parameter_acl 中进行跟踪。
授予和撤销这些新权限的操作与预期一致。需要注意的是,PGC_USERSET 类型的 GUC 参数不受 SET 权限的影响,理论上可以通过向 PUBLIC 角色授予可撤销的权限来处理这类参数,但实际并未采用这种方式,因为对于扩展定义的 GUC 参数而言,这种方式无法保证足够的稳健性。
讨论:https://postgr.es/m/3D691E20-C1D5-4B80-8BA5-6BEB63AF3029@enterprisedb.com
示例
通过本次提交的特性,你可以控制谁被允许设置特定参数。这为你提供了更多灵活性,尤其是在为客户托管 PostgreSQL 实例时。你可以将更多控制权委托给可信用户或角色,当然,当不再需要时,你也可以在之后撤销该权限。这样做的一个目标是减少需要超级用户权限的任务数量。下面,让我们通过一个简单的示例来看看如何使用它。
首先,我们创建一个新用户,并以该用户身份连接:
postgres=# create user u with login password 'u';
CREATE ROLE
postgres=# \c postgres u
You are now connected to database "postgres" as user "u".
该用户被允许设置哪些参数呢?在实例和数据库级别,什么都不能设置:
alter system set work_mem='12MB';
ERROR: permission denied to set parameter "work_mem"
alter database postgres set work_mem='12MB';
ERROR: must be owner of database postgres
当然,该用户可以为自己设置新的参数值,这可以是永久设置,也可以是在会话中设置:
alter user u set work_mem='12MB';
set work_mem='10MB';
这适用于 pg_settings 中 context 为 “user” 的所有参数:
select name,context from pg_settings where context = 'user' order by 1;
name | context
-------------------------------------+---------
application_name | user
array_nulls | user
backend_flush_after | user
backslash_quote | user
bytea_output | user
check_function_bodies | user
client_connection_check_interval | user
client_encoding | user
client_min_messages | user
commit_siblings | user
constraint_exclusion | user
cpu_index_tuple_cost | user
cpu_operator_cost | user
cpu_tuple_cost | user
cursor_tuple_fraction | user
DateStyle | user
debug_pretty_print | user
debug_print_parse | user
...
vacuum_cost_limit | user
vacuum_cost_page_dirty | user
vacuum_cost_page_hit | user
vacuum_cost_page_miss | user
vacuum_failsafe_age | user
vacuum_freeze_min_age | user
vacuum_freeze_table_age | user
vacuum_multixact_failsafe_age | user
vacuum_multixact_freeze_min_age | user
vacuum_multixact_freeze_table_age | user
wal_sender_timeout | user
wal_skip_threshold | user
work_mem | user
xmlbinary | user
xmloption | user
(136 rows)
对于所有其他参数,该操作不起作用:
select name,context from pg_settings where context != 'user' order by 1;
name | context
----------------------------------------+-------------------
allow_in_place_tablespaces | superuser
allow_system_table_mods | superuser
archive_cleanup_command | sighup
archive_command | sighup
archive_library | sighup
archive_mode | postmaster
archive_timeout | sighup
authentication_timeout | sighup
...
wal_sync_method | sighup
wal_writer_delay | sighup
wal_writer_flush_after | sighup
zero_damaged_pages | superuser
(202 rows)
SET track_counts='on';
ERROR: permission denied to set parameter "track_counts"
上面的情况已经成为历史。从 PostgreSQL 新版本开始,你可以向用户或角色授予设置特定参数的权限:
postgres=# SELECT current_user;
current_user
--------------
postgres
(1 row)
postgres=# GRANT SET ON PARAMETER track_counts TO u;
GRANT
postgres=# \c postgres u
You are now connected to database "postgres" as user "u".
postgres=> SET track_counts = 'on';
SET
这在实例级别也适用:
postgres=# GRANT ALTER SYSTEM ON PARAMETER shared_buffers TO u;
GRANT
postgres=# \c postgres u
You are now connected to database "postgres" as user "u".
postgres=> ALTER SYSTEM SET shared_buffers = '129MB';
ALTER SYSTEM
本次提交的特性新增了一个系统表,它可以列出所有参数的授权:
postgres=> \c postgres
You are now connected to database "postgres" as user "u".
postgres=> select * from pg_parameter_acl;
oid | parname | paracl
-------+----------------+-------------------------------------
16392 | track_counts | {postgres=sA/postgres,u=s/postgres}
16393 | wal_level | {postgres=sA/postgres,u=s/postgres}
16394 | shared_buffers | {postgres=sA/postgres,u=A/postgres}
(3 rows)
非常不错的体验,感谢所有参与的社区人员。
参考
提交日志:https://git.postgresql.org/pg/commitdiff/a0ffa885e478f5eeacc4e250e35ce25a4740c487