我需要一个功能来自动管理数据库中的分区。我发现一个函数每次创建2个月,并使其适用于具有不同主键和创建日期键的宿舍和多个表。
现在我需要改变它从删除最后一个分区的分区。相反,如果它们来自上一年,我只希望它放弃四分之一分区。我如何更改前几个季度的代码来做到这一点?删除管理分区的功能中的某些表
相关代码:
-- check if the partition for the previous quarter exists
v_date_from := date_trunc('quarter', v_current_date - '3 month'::interval);
v_partition_name := master_table || '_Q' || EXTRACT(QUARTER FROM v_date_from) || '_' || EXTRACT(YEAR FROM v_date_from);
v_rule_name := 'rule_' || master_table || '_Q' || EXTRACT(QUARTER FROM v_date_from) || '_' || EXTRACT(YEAR FROM v_date_from);
SELECT COUNT(*) = 1 INTO v_exists FROM pg_tables WHERE schemaname = 'public' AND tablename = v_partition_name;
IF (v_exists) THEN
EXECUTE 'DROP RULE ' || v_rule_name || ' ON ' || master_table;
EXECUTE 'DROP TABLE ' || v_partition_name;
END IF;
功能齐全:
CREATE OR REPLACE FUNCTION manage_partitions(timestamp without time zone, master_table character varying, prime_key character varying, prime_date character varying) RETURNS void AS
$BODY$
DECLARE
-- name of the next partition and rule (and interval boundaries)
v_partition_name VARCHAR(32);
v_rule_name VARCHAR(32);
v_date_from TIMESTAMP;
v_date_to TIMESTAMP;
-- current date (if NULL, a current timestamp is used)
v_date ALIAS FOR $1;
v_current_date TIMESTAMP;
-- used just for checking existence of the partitions
v_exists BOOLEAN;
BEGIN
IF (v_date IS NULL) THEN
v_current_date := current_timestamp;
ELSE
v_current_date := v_date;
END IF;
-- check if the partition for the previous quarter exists
v_date_from := date_trunc('quarter', v_current_date - '3 month'::interval);
v_partition_name := master_table || '_Q' || EXTRACT(QUARTER FROM v_date_from) || '_' || EXTRACT(YEAR FROM v_date_from);
v_rule_name := 'rule_' || master_table || '_Q' || EXTRACT(QUARTER FROM v_date_from) || '_' || EXTRACT(YEAR FROM v_date_from);
SELECT COUNT(*) = 1 INTO v_exists FROM pg_tables WHERE schemaname = 'public' AND tablename = v_partition_name;
IF (v_exists) THEN
EXECUTE 'DROP RULE ' || v_rule_name || ' ON ' || master_table;
EXECUTE 'DROP TABLE ' || v_partition_name;
END IF;
-- create a partition for this quarter
v_date_from := date_trunc('quarter', v_current_date);
v_date_to := v_date_from + '3 month';
v_partition_name := master_table || '_Q' || EXTRACT(QUARTER FROM v_date_from) || '_' || EXTRACT(YEAR FROM v_date_from);
v_rule_name := 'rule_' || master_table || '_Q' || EXTRACT(QUARTER FROM v_date_from) || '_' || EXTRACT(YEAR FROM v_date_from);
SELECT COUNT(*) = 1 INTO v_exists FROM pg_tables WHERE schemaname = 'public' AND tablename = v_partition_name;
IF (NOT v_exists) THEN
EXECUTE 'CREATE TABLE ' || v_partition_name || ' (PRIMARY KEY (' || prime_key || '), CHECK (' || prime_date || ' >= ''' || v_date_from || ''' AND ' || prime_date || ' < ''' || v_date_to || ''')) INHERITS (' || master_table || ')';
EXECUTE 'CREATE RULE ' || v_rule_name || ' AS ON INSERT TO ' || master_table || ' DO INSTEAD INSERT INTO ' || v_partition_name || ' VALUES (NEW.*)';
-- if you need to create indexes/foreign keys/whatever on the partition, you may do it here
END IF;
-- create a partition for next quarter
v_date_from := date_trunc('quarter', v_current_date + '3 month'::interval);
v_date_to := v_date_from + '3 month';
v_partition_name := master_table || '_Q' || EXTRACT(QUARTER FROM v_date_from) || '_' || EXTRACT(YEAR FROM v_date_from);
v_rule_name := 'rule_' || master_table || '_Q' || EXTRACT(QUARTER FROM v_date_from) || '_' || EXTRACT(YEAR FROM v_date_from);
SELECT COUNT(*) = 1 INTO v_exists FROM pg_tables WHERE schemaname = 'public' AND tablename = v_partition_name;
IF (NOT v_exists) THEN
EXECUTE 'CREATE TABLE ' || v_partition_name || ' (PRIMARY KEY (' || prime_key || '), CHECK (' || prime_date || ' >= ''' || v_date_from || ''' AND ' || prime_date || ' < ''' || v_date_to || ''')) INHERITS (' || master_table || ')';
EXECUTE 'CREATE RULE ' || v_rule_name || ' AS ON INSERT TO ' || master_table || ' DO INSTEAD INSERT INTO ' || v_partition_name || ' VALUES (NEW.*)';
-- if you need to create indexes/foreign keys/whatever on the partition, you may do it here
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
您应该提供您发现一次创建了2个月的函数的源代码,以及(一如既往!)您的Postgres版本。 –