Oracle的参数可以设置system和session级别,当设置了session级别的参数时,会覆盖值system级别。postgresql除了该两个级别外,还有database级别、user/role级别、user/role+database组合级别。
下面针对这几个级别的参数优先级问题,在postgresql-11.5进行测试验证,测试以参数client_min_messages为例子。
测试数据库用户:aken
测试database:akendb01
测试验证前,client_min_messages最初参数值:session默认继承当前system级别。
(postgres@[local]:5432)[postgres]#show client_min_messages ;client_min_messages---------------------warning <<<当user=postgres且database=postgres时,session最初继承的system级别的参数值(1 row)(aken@[local]:5432)[akendb01]#select name,context,setting from pg_settings where name like 'client_min%';name | context | setting---------------------+---------+---------client_min_messages | user | warning <<<当user=aken且database=akendb01时,session最初继承的system级别的参数值(1 row)(postgres@[local]:5432)[postgres]#
测试前,client_min_messages在user级别、database级别、user+database组合级别的参数值均未设置:
(postgres@[local]:5432)[postgres]#select usename,a.useconfig,c.setconfig from pg_user a, pg_db_role_setting c where a.usesysid=c.setrole and a.usename='aken';usename | useconfig | setconfig---------+-----------+-----------(0 rows)(postgres@[local]:5432)[postgres]#select datname,c.setconfig from pg_database b,pg_db_role_setting c where b.oid=c.setdatabase and b.datname like 'akendb%';datname | setconfig---------+-----------(0 rows)(postgres@[local]:5432)[postgres]#select usename,datname,a.useconfig,c.setconfig from pg_user a,pg_database b,pg_db_role_setting c where a.usesysid=c.setrole and b.oid=c.setdatabase and a.usename='aken' and b.datname like 'akendb%';usename | datname | useconfig | setconfig---------+---------+-----------+-----------(0 rows)
测试一:设置user级别参数,测试对比user级别和system级别的优先级。
(aken@[local]:5432)[postgres]#select name,context,setting from pg_settings where name like 'client_min%';name | context | setting---------------------+---------+---------client_min_messages | user | warning <<<设置前,当user=aken且database=postgres时,session最初继承的system级别的参数值(1 row)(postgres@192.168.1.108:5432)[postgres]#\c - postgresPassword for user postgres:You are now connected to database "postgres" as user "postgres".(postgres@[local]:5432)[postgres]#alter role aken set client_min_messages=ERROR;ALTER ROLE(postgres@[local]:5432)[postgres]#select usename,a.useconfig,c.setconfig from pg_user a, pg_db_role_setting c where a.usesysid=c.setrole and a.usename='aken';usename | useconfig | setconfig---------+-----------------------------+-----------------------------aken | {client_min_messages=error} | {client_min_messages=error}(1 row)(postgres@192.168.1.108:5432)[postgres]#\c - akenPassword for user aken:You are now connected to database "postgres" as user "aken".(aken@192.168.1.108:5432)[postgres]>select name,context,setting from pg_settings where name like 'client_min%';name | context | setting---------------------+---------+---------client_min_messages | user | error <<<设置后,当user=aken且database=postgres时,session继承user级别参数值,即user级别覆盖system级别(1 row)(aken@192.168.1.108:5432)[postgres]>
从上面的测试可以看出,用户aken登录akendb01的session参数client_min_messages继承了user级别的参数值:client_min_messages=error。
所以,user级别的优先于system级别。
测试二、设置database级别参数
对比database和system级别、database和user级别的参数优先级。
(aken@192.168.1.108:5432)[postgres]>\c - postgresPassword for user postgres:You are now connected to database "postgres" as user "postgres".(postgres@192.168.1.108:5432)[postgres]#(postgres@[local]:5432)[postgres]#select name,context,setting from pg_settings where name like 'client_min%';name | context | setting---------------------+---------+---------client_min_messages | user | warning <<<设置前,当user=postgres且database=postgres时,session最初继承的system级别参数值(1 row)(postgres@192.168.1.108:5432)[postgres]#alter database akendb01 set client_min_messages=log; <<<设置database级别ALTER DATABASE(postgres@192.168.1.108:5432)[postgres]#select datname,c.setconfig from pg_database b,pg_db_role_setting c where b.oid=c.setdatabase and b.datname like 'akendb%';datname | setconfig----------+---------------------------akendb01 | {client_min_messages=log}(1 row)(postgres@[local]:5432)[postgres]#(postgres@[local]:5432)[postgres]#\c akendb01You are now connected to database "akendb01" as user "postgres".(postgres@[local]:5432)[akendb01]#select name,context,setting from pg_settings where name like 'client_min%';name | context | setting---------------------+---------+---------client_min_messages | user | log <<<设置后,当user=postgres并且database=akendb01时,session继承了database级别的参数,即database级别覆盖system级别。(1 row)(postgres@[local]:5432)[akendb01]#(postgres@[local]:5432)[akendb01]#\c - akenYou are now connected to database "postgres" as user "aken".(aken@[local]:5432)[akendb01]>select name,context,setting from pg_settings where name like 'client_min%';name | context | setting---------------------+---------+---------client_min_messages | user | error <<<当user=aken且database=akendb01时,session继承了user级别的参数值,即user级别覆盖database级别(1 row)(aken@192.168.1.108:5432)[akendb01]>(aken@[local]:5432)[akendb01]>
上面的测试可以看出:
1.用户postgres在database=akendb01的session,参数client_min_messages继承了database级别的参数值,即client_min_messages=log。
2.用户aken登录akendb01的session,参数client_min_messages继承了user级别的参数值:client_min_messages=error。
所以,database级别优先于system级别,而user级别优先于database级别。
测试三、设置user+database级别参数
对比user级别、user+database级别的优先级。
这里说明一下,上面在设置user+database级别之前:
1.在database级别,数据库akendb01设置了client_min_messages=log;
2.在user/role级别,用户aken设置了client_min_messages=error;
3.在user=aken且database=akendb01的会话中,session继承了user级别的参数值,即user级别覆盖database和system级别。
(aken@[local]:5432)[akendb01]>select name,context,setting from pg_settings where name like 'client_min%';name | context | setting---------------------+---------+---------client_min_messages | user | error(1 row)(aken@192.168.1.108:5432)[akendb01]>
下面继续加入user+database组合的参数级别:
(aken@[local]:5432)[akendb01]>\c - postgresYou are now connected to database "akendb01" as user "postgres".(postgres@[local]:5432)[akendb01]#(postgres@[local]:5432)[akendb01]#alter role aken in database akendb01 set client_min_messages=notice;LOG: statement: alter role aken in database akendb01 set client_min_messages=notice;ALTER ROLE(postgres@[local]:5432)[akendb01]#select usename,datname,a.useconfig,c.setconfig from pg_user a,pg_database b,pg_db_role_setting c where a.usesysid=c.setrole and b.oid=c.setdatabase and a.usename='aken' and b.datname like 'akendb%';usename | datname | useconfig | setconfig---------+----------+-----------------------------+------------------------------aken | akendb01 | {client_min_messages=error} | {client_min_messages=notice}(1 row)(postgres@[local]:5432)[akendb01]#(postgres@[local]:5432)[akendb01]#\c - akenYou are now connected to database "akendb01" as user "aken".(aken@[local]:5432)[akendb01]>select name,context,setting from pg_settings where name like 'client_min%';name | context | setting---------------------+---------+---------client_min_messages | user | notice <<< user=aken并且database=akendb01时,session继承了user+database级别的参数值,user+database级别覆盖system、database、user级别。(1 row)(aken@[local]:5432)[akendb01]>
上面的测试可以看出:
1.用户aken登录akendb01的session,参数client_min_messages继承了user+database组合级别的参数值:client_min_messages=notice。
所以,user+database组合级别优先于user级别。
最后,在user+database组合级别的session中直接set参数值:
(aken@[local]:5432)[akendb01]>set client_min_messages=warning;SET(aken@[local]:5432)[akendb01]>(aken@[local]:5432)[akendb01]>show client_min_messages ;client_min_messages---------------------warning <<< 直接set session级别参数值,覆盖前面的所有级别(1 row)(aken@[local]:5432)[akendb01]>
综上,postgres参数级别的优先顺序为:
1.默认情况下,session会继承system级别参数值;
2.在设置了database级别参数的情况下,database级别的参数值优先于system级别;
3.在设置了user/role级别参数的情况下,user级别的参数值优先于database级别;
4.在设置了user+database级别参数的情况下,该组合级别的参数值优先于user级别;
5.在当前session给会话直接set parameter=value的情况下,该参数值最优先。





