postgresql 9.6 普通用戶查詢 pg_stat_activity、pg_stat_statements 的方法

postgresql 9.6 普通用戶查詢 pg_stat_activity、pg_stat_statements 時部分列顯示 insufficient privilege,有兩種方法可以解決。

postgres=> select pid,client_addr,query from pg_stat_activity;
 pid  | client_addr |                        query                        
------+-------------+-----------------------------------------------------
 3078 |             | select pid,client_addr,query from pg_stat_activity;
 2954 |             | <insufficient privilege>
 2955 |             | <insufficient privilege>
 2964 |             | <insufficient privilege>
 2976 |             | <insufficient privilege>
 2987 |             | <insufficient privilege>
(6 rows)

postgres=> select dbid,queryid,query  from pg_stat_statements order by query;
 dbid  |  queryid   |          query                                                                                                                                                                                                                                                
-------+------------+---------------------------------------------------------------------------------------------------------
 13325 |            | <insufficient privilege>
 13325 |            | <insufficient privilege>
 13325 |            | <insufficient privilege>
 13325 |            | <insufficient privilege>
 

授予 superuser 權限

這個雖然可行,但是把普通用戶的權限提升到 superuser,帶來相當高的風險

postgres=# alter user testuser1 with superuser;
ALTER ROLE
postgres=# \du
                                   List of roles
 Role name |                         Attributes                         | Member of 
-----------+------------------------------------------------------------+-----------
 testuser  | Superuser                                                  | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
 

創建 SECURITY DEFINER 函數

CREATE OR REPLACE FUNCTION pg_catalog.f_pg_stat_activity() RETURNS setof pg_catalog.pg_stat_activity AS 
$body$ 
DECLARE 
    result record; 
BEGIN 
	for result in select * from pg_catalog.pg_stat_activity
	loop 
	   return next result; 
	end loop; 
	return; 
	END; 
$body$ 
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY DEFINER; 

CREATE OR REPLACE FUNCTION pg_catalog.f_pg_stat_statements() RETURNS setof public.pg_stat_statements AS 
$body$ 
DECLARE 
    result record; 
BEGIN 
	for result in select * from public.pg_stat_statements
	loop 
	   return next result; 
	end loop; 
	return; 
	END; 
$body$ 
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY DEFINER

REVOKE ALL ON FUNCTION pg_catalog.f_pg_stat_activity() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION pg_catalog.f_pg_stat_activity() TO testuser1;

REVOKE ALL ON FUNCTION pg_catalog.f_pg_stat_statements() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION pg_catalog.f_pg_stat_statements() TO testuser1;

可以通過查詢這兩個函數獲取數據。

select * from pg_catalog.f_pg_stat_activity();

select * from pg_catalog.f_pg_stat_statements();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章