每晚执行PostgreSQL脚本

每晚执行PostgreSQL脚本,sql,postgresql,crontab,materialized-views,Sql,Postgresql,Crontab,Materialized Views,我正试图模仿快照物化视图,并创建了我需要的物化视图 我的下一个任务是在PostgreSQL中每晚执行刷新物化视图脚本。我正在使用pgAdmin,发现我需要在数据库服务器(Linux)上安装pgagent,并通过编写pgscript在pgAdmin中创建作业 这就是我需要的,还是有更好的方法每晚运行这个脚本 for all i in tables that begin with name 'mview_%' SELECT refresh_matview(i); end loop; 我刚

我正试图模仿快照物化视图,并创建了我需要的物化视图

我的下一个任务是在PostgreSQL中每晚执行刷新物化视图脚本。我正在使用pgAdmin,发现我需要在数据库服务器(Linux)上安装pgagent,并通过编写pgscript在pgAdmin中创建作业

这就是我需要的,还是有更好的方法每晚运行这个脚本

 for all i in tables that begin with name 'mview_%'
   SELECT refresh_matview(i);
 end loop;

我刚刚在我的crontab中放置了一个条目:

*/3 * * * * /scripts/matviewsRefresh.sh 
这将每三分钟调用一次脚本,您可以对此进行调优。 和内部
matviewsRefresh.sh

  echo 'select matview_refresh_all();' | su - postgres -c "psql MYDBNAME"
当然,
matview\u refresh\u all
是一个pl/pgsql函数,它循环遍历我所有的物化视图并刷新旧视图(我添加了一个辅助表,记录每个mview的上次刷新时间,每个视图都有不同的刷新频率)

Cron作业 leonbloy说了些什么

此外,您还可以将cronjob放置在postgres系统用户的crontab中,并简化调用:

psql mydb -c 'select maint.f_mv_update()' 
自动刷新物化视图 这是为一个环境设计的,在这个环境中,您可以在休息时间锁上一点桌子。如果您没有这样的优势,您可能希望并行地创建新表,然后删除原始表并重命名副本,以将阻塞保持在最低限度

我为mv模式中的所有对象保留一个单独的模式
maint

我的全部刷新功能:

CREATE OR REPLACE FUNCTION maint.f_mv_update()
  RETURNS void AS
$func$
DECLARE
   _r    record;
BEGIN

SET LOCAL work_mem='256MB';               -- more memory for sorting et al?
SET LOCAL client_min_messages=warning;    -- suppress index creation notices

-- With concurrent load you may need to lock some tables to avoid deadlocks
-- LOCK tbl1, tbl2;

FOR _r IN
   -- cast to regclass asserts table name is valid
   SELECT (mv_schema || '.' || mv_tab)::regclass AS tbl 
         ,drop_index
         ,mv_query
         ,create_index
   FROM   maint.mv
   WHERE  active
   ORDER  BY mv_id
LOOP
   IF _r.drop_index IS NOT NULL THEN      -- drop indexes (for performance!)
      EXECUTE _r.drop_index;
   END IF;

   EXECUTE 'TRUNCATE TABLE '   || _r.tbl;
   EXECUTE 'INSERT INTO '      || _r.tbl || ' ' || _r.mv_query;

   IF _r.create_index IS NOT NULL THEN    -- recreate Indexes (also CLUSTER?)
      EXECUTE _r.create_index;
   END IF;

   EXECUTE 'ANALYZE ' || _r.tbl;          -- ANALYZE to refresh statistics
END LOOP;

RESET client_min_messages;

UPDATE maint.mv
SET last_up = localtimestamp(0) WHERE active; -- remember update

END
$func$ LANGUAGE plpgsql VOLATILE SET search_path=maint,pg_temp;

REVOKE ALL ON FUNCTION maint.f_mv_update() FROM public;

COMMENT ON FUNCTION maint.f_mv_update() IS 'Update materialized Views.
Uses table maint.mv';
与此表结合使用,将注册所有要属于此机制的物化视图

CREATE TABLE maint.mv
(
  mv_id integer PRIMARY KEY, -- surrogate primary key...
  active boolean NOT NULL DEFAULT true,
  last_up timestamp(0) NOT NULL DEFAULT '2000-1-1 0:0'::timestamp, -- last update
  log_up timestamp(0) NOT NULL DEFAULT now()::timestamp(0), -- last change of row
  mv_schema text NOT NULL, -- Schema of mv table
  mv_tab text NOT NULL, -- Name of mv table
  mv_query text NOT NULL, -- SQL-query to fill mv
  drop_index text, -- SQL to drop indexes before refill
  create_index text, -- SQL to recreate indexes after refill
  note text
);
REVOKE ALL ON TABLE maint.mv FROM public;
示例行:

INSERT INTO maint.mv
       (mv_id, mv_schema, mv_tab, mv_query, drop_index, create_index)
VALUES ( 17, 'mv', 'mytbl'
       ,'SELECT mytbl_id, count(*) FROM mytbl GROUP BY 1;'
       ,'DROP INDEX IF EXISTS mv.mytbl_mytbl_id_idx;'
       ,'CREATE INDEX mytbl_mytbl_id_idx ON mv.mytbl (my_tbl_id);');
电话:


谢谢你,莱昂布洛伊。。这和我要找的一样简单..非常感谢您的帮助。+1但是请注意,就并发性而言,TRUNCATE比DELETE更快,但不太安全。我不确定这种方法是否会导致某些并发事务看到一个空的物化视图。
SELECT maint.f_mv_update();