介绍
每个 PostgreSQL参数都有自己的功能和关联的上下文,它定义了可以更改参数的上下文级别。可能的上下文值是(从最低到最高级别):internal、postmaster、sighup、backend、superuser-backend、superuser 和 user(更多详细信息可以在文档中找到)。本文将重点介绍这些设置用户上下文,即任何用户都可以在其会话中更改的所有设置。
这个选项非常有用,尤其是如果用户需要修改他的会话的行为来改变一些特定的参数以从中受益,但它也可能是一把双刃剑,因为一些“聪明”的用户可以改变一些不计后果地为自己“窃取”资源。通过这种方式,它可以阻止其他进程/用户使用它,有时他们可以破坏 postgres 服务,例如导致 OOM 问题。一些示例案例:设置超高的work_mem,减少其他进程可用的内存,或为自己占用更多的 CPU 资源在他的会话中更改 max_parallel_worker_per_gather等。
目前PostgreSQL没有办法避免这种情况,但是利用PostgreSQL的可扩展性,我们开发了一个使用PostgreSQL的hook机制的扩展,以避免非超级用户鲁莽地通过SET命令更改参数。实用的方式。
noset扩展
该noset扩展是由OnGres团队开发,它是通过一个可加载模块shared_preload_libraries阻止了SET/RESET对用户的会话命令。该扩展支持版本 12 和 13,并计划支持较新的版本。
安装与设置
安装需要开发 PostgreSQL 的软件包和下载代码的扩展。
make
make install
复制
必须通过将 noset 模块添加到shared_preload_libraries来加载它,并且需要重新启动服务。
shared_preload_libraries = 'noset'
复制
该扩展有一个名为 noset.enabled 的变量,它定义是否禁止角色/用户运行 SET/RESET 命令并更改其会话中的参数(默认为 false)
例子
创建用户并设置noset.enabled选项
psql -d db -U postgres
db=# create user appuser password 'mypass';
CREATE ROLE
db=# alter user appuser set noset.enabled = true;
ALTER ROLE
复制
使用先前创建的用户并尝试通过SET命令更改参数
psql -d db -U appuser
--login as appuser
db=> select current_user;
current_user
--------------
Appuser
(1 row)
db=> show noset.enabled ;
noset.enabled
---------------
On
(1 row)
db=> set work_mem ='1GB';
ERROR: permission denied to set/reset parameter 'set work_mem = '1GB';
复制
可以通过查询PostgreSQL的目录来验证禁止通过SET更改参数的用户。
db=# select usename, useconfig from pg_user where useconfig is not null and array['noset.enabled=on'] <@ useconfig;
usename | useconfig
---------+--------------------
appuser | {noset.enabled=on}
(1 row)
复制
结论
使用 noset 扩展可以提供一种简单的方法来避免“聪明”用户不加选择地更改会话中的参数,并再次展示了 PostgreSQL 出色的扩展能力。