今天业务同事想让我帮写一个按天自动创建分区和保留30个分区的函数,本来为了偷懒想去网上找一个改一下就算了,后来找了半天发现全是通过表继承实现自动创建和删除分区的,都不靠谱,还是自己写一个吧,不会废话上代码:
CREATE OR REPLACE FUNCTION public.auto_create_delete_tbl_partition(part_time timestamp without time zone, part_column_name character varying, part_table_name character varying)
RETURNS integer
LANGUAGE plpgsql
AS $function$
DECLARE
PARTMM varchar(8);
--RELNAME varchar(200);
PAELNAME varchar(200);
PELNAME varchar(200);
NewisExist boolean;
OldisExist boolean;
startTime text;
endTime text;
oldTime text;
strSQL text;
return_value int;
BEGIN
--RELNAME := part_table_name;
PAELNAME := part_table_name;
PELNAME := part_table_name||'_';
-- 判断对应分区表 是否已经存在?
PARTMM := to_char(part_time::timestamp , 'YYYYMMDD' );
select count(*) INTO NewisExist from pg_class where pg_class.relname = PELNAME||PARTMM;
--RAISE NOTICE 'value %',NewisExist;
-- 若不存在, 创建分区
IF ( NewisExist = false ) THEN
-- 创建分区表
startTime := PARTMM||' 00:00:00.000';
endTime := to_char( startTime::timestamp + interval '1 day', 'YYYY-MM-DD HH24:MI:SS.MS');
strSQL :='CREATE TABLE '||PELNAME||PARTMM||' PARTITION OF '||PAELNAME||' FOR VALUES FROM ('||''''||startTime||''''||') TO ('||''''||endTime||''''||')';
--RAISE NOTICE 'value %',strSQL;
EXECUTE strSQL;
--使用分区字段创建索引
strSQL := 'CREATE INDEX '||PELNAME||PARTMM||'_INDEX_'||part_column_name||' ON '
||PELNAME||PARTMM||' ('||part_column_name||');' ;
EXECUTE strSQL;
--删除历史分区(30天前的分区)
oldTime := to_char( startTime::timestamp - interval '30 day', 'YYYY-MM-DD HH24:MI:SS.MS');
strSQL := 'drop table '||PELNAME||to_char(oldTime::timestamp , 'YYYYMMDD');
EXECUTE strSQL;
return_value := 0;
return return_value;
END IF;
END
$function$
调用前效果:

调用函数

调用后效果

可以看到通过调用函数创建了新的分区并删除了旧的分区,如果想每天执行可以添加系统定时任务也可以在业务中定时调用。




