问题
I'm new at Postgresql and do not exactly know how to manage partition tables.
I have partition table based on day. Before inserting data, trigger checks date and put into corresponding child table.
eg.
11.15.2014 - insert into table named 11-15-2014_log.
11.16.2014 - insert into table named 11-16-2014_log.
Now I want to create function that will drop old child tables, for example, tables older than 90 days.
Should I find and drop child table according its tablename (cause it consists date of creation) OR should I find records older than 90 days in master table??
Any suggestion or hint will be appreciated. Thanks.
回答1:
regarding dropping a partition, The example that follows deletes a partition of the sales table. Use the following command to create the sales table:
CREATE TABLE sales
(
dept_no number,
part_no varchar2,
country varchar2(20),
date date,
amount number
)
PARTITION BY LIST(country)
(
PARTITION europe VALUES('FRANCE', 'ITALY'),
PARTITION asia VALUES('INDIA', 'PAKISTAN'),
PARTITION americas VALUES('US', 'CANADA')
);
Querying the ALL_TAB_PARTITIONS
view displays the partition names:
acctg=# SELECT partition_name, server_name, high_value FROM ALL_TAB_PARTITIONS;
partition_name | server_name | high_value
----------------+-------------+---------------------
europe | seattle | 'FRANCE', 'ITALY'
asia | chicago | 'INDIA', 'PAKISTAN'
americas | boston | 'US', 'CANADA'
(3 rows)
To delete the americas partition from the sales table, invoke the following command:
ALTER TABLE sales DROP PARTITION americas;
Querying the ALL_TAB_PARTITIONS
view demonstrates that the partition has been successfully deleted:
acctg=# SELECT partition_name, server_name, high_value FROM ALL_TAB_PARTITIONS;
partition_name | high_value
----------------+---------------------
asia | 'INDIA', 'PAKISTAN'
europe | 'FRANCE', 'ITALY'
(2 rows)
回答2:
I will just delete the records that are older from the master table, something like:
DELETE FROM master_table WHERE creation_date < 'today' - INTERVAL '90 days';
However my advice is to time this query to run at the most sleepy time for the server, like say 5:00am
回答3:
For anyone who ends up here looking for how to delete the table partitions in PostgreSQL, here is the modern answer.
The solution is not to use a DELETE statement because that will delete the data without dropping the corresponding table partitions that held the data. The OP asked about managing partition tables, not deleting records, so any solution using DELETE statements adds unnecessary database overhead of deleting records, leaves empty partition tables in place, and completely ignores one of the primary benefits of using partitioning; DROPing the table when it is no longer useful.
In this case the solution must be to DROP the no longer needed partition table. I have written a solution to resolve this issue in my production environment, the answer is here.
To resolve the OP's issue, the function I wrote can be used with two slight revisions to modify the fullTablename variable and the date format. The fullTablename variable line must be changed from
fullTablename := base_table_name || '_' || to_char(startTime, dateFormat);
to the YYYY-MM-DD_log format like this
fullTablename := to_char(startTime, dateFormat) || '_' || base_table_name;
Then the date format needs to be slightly modified from
WHEN partition_plan='day' THEN 'YYYYDDD'
to the stated table naming convention
WHEN partition_plan='day' THEN 'YYYY-MM-DD'
Then the SQL query that calls the function to perform the cleanup can be called from a daily maintenance script like this:
SELECT public.drop_partitions(current_date-180, 'public', 'log', 5, 'day');
Which will DROP the YYYY-MM-DD_log tables that are 5 days older than 180 days ago. For an initial run to delete dozens or hundreds of old table partitions, the 5 can be set to a much higher value that achieves the desired effect.
来源:https://stackoverflow.com/questions/27053499/postgresql-delete-partition-tables