1

我正在编写从 pg_stat_activity 系统视图(PostgreSQL 13)收集行的函数。

在这个函数中,我有一个简单的循环将 pg_stat_activity 数据插入到日志表中。

问题是当我运行该函数时,它会在第一秒插入实际的行并稍后复制它们。似乎函数作为单个事务工作,并从第一次运行时的行快照中获取数据。如何在多个单独的事务中运行函数“body”以获得每秒的结果,或者我可以有什么解决方法?

CREATE OR REPLACE FUNCTION public.fn_activity(
    integer)
    RETURNS void 
    LANGUAGE 'plpgsql'
    --COST 100
    --VOLATILE PARALLEL UNSAFE
AS $BODY$
declare counter integer := 0;
begin
    while counter < $1 loop
        raise notice 'Counter %', counter;
        counter := counter + 1;
        
        insert into public.pg_stat_activity_log("time",datid,datname,pid,leader_pid,usesysid,usename,application_name,client_addr,client_hostname,
        client_port,backend_start,xact_start,query_start,state_change,wait_event_type,wait_event,state,backend_xid,backend_xmin,query,backend_type)
        SELECT now()::time(0),datid,datname,pid,leader_pid,usesysid,usename,application_name,client_addr,client_hostname,client_port,backend_start,xact_start,query_start,
        state_change,wait_event_type,wait_event,state,backend_xid,backend_xmin,query,backend_type
        from pg_stat_activity;
        
        raise notice '-------';
        
        PERFORM pg_sleep(1);
   
        end loop;
        return;
END;
$BODY$;

truncate table public.pg_stat_activity_log;
select public.fn_activity(60);

目前我只有 14:53:15 的结果,但需要: 14:53:15 14:53:16 14:53:17 14:53:18

谢谢!

4

1 回答 1

0

pg_stat_activity只要您在事务中,in 中的值就不会改变,因为数据只读取一次,然后缓存在数据库会话的私有内存中。

由于一个函数总是在单个事务中运行,它总是会在 中看到相同的值pg_stat_activity,无论这是否仍然与现实相符。

pgstat_read_current_status请参阅in 中的函数注释src/backend/utils/activity/backend_status.c,该注释复制数据:

/* ----------
 * pgstat_read_current_status() -
 *
 *  Copy the current contents of the PgBackendStatus array to local memory,
 *  if not already done in this transaction.
 * ----------
 */
于 2021-10-28T12:21:04.720 回答