自动删除超过90天的表和索引

时间:2013-09-17 12:23:18

标签: postgresql

有没有办法根据创建日期自动删除/删除所有表及与之关联的索引?

我在Postgres中找不到记录表/索引创建日期的内置/本地列。我正在运行Postgres 8.4。我以为我可以做这样的事情(伪SQL):

select all from pg_tables where creation_date is older than 90 days;

然后删除该选择的结果(对于pg_indexes也是如此)。但是,我无法找到任何类型的表或索引创建日期。我可以自己装配一些创建日期跟踪器,但我确信Postgres中会有一些原生的东西已经存储了这些信息......是吗?

由于

2 个答案:

答案 0 :(得分:2)

您可以像这样获得创作时间

(假设表名t_benutzer

--select datname, datdba from pg_database;
--select relname, relfilenode from pg_class where relname ilike 't_benutzer';

    -- (select relfilenode::text from pg_class where relname ilike 't_benutzer')




SELECT 
    pg_ls_dir
    ,
    (
        SELECT creation
        FROM pg_stat_file('./base/'
            ||
            (
                    SELECT 
                        MAX(pg_ls_dir::int)::text 
                    FROM pg_ls_dir('./base') 
                    WHERE pg_ls_dir <> 'pgsql_tmp' 
                    AND  pg_ls_dir::int  <= (SELECT relfilenode FROM pg_class WHERE relname ILIKE 't_benutzer')
            )
            || '/' || pg_ls_dir
        )
    ) as createtime 
FROM pg_ls_dir(
    './base/' || 
    (
        SELECT 
            MAX(pg_ls_dir::int)::text 
        FROM pg_ls_dir('./base') 
        WHERE pg_ls_dir <> 'pgsql_tmp' 
        AND  pg_ls_dir::int  <= (SELECT relfilenode FROM pg_class WHERE relname ILIKE 't_benutzer') 
    ) 
) 

WHERE pg_ls_dir = (SELECT relfilenode::text FROM pg_class WHERE relname ILIKE 't_benutzer')

秘诀是在相应的表文件中使用pg_stat_file。

-- http://www.greenplumdba.com/greenplum-dba-faq/howtofindtablecreationdateingreenplum


select 
    pg_ls_dir
    , 
    (
        select 
            --size 
            --access
            --modification 
            --change
            creation 
            --isdir
        from pg_stat_file(pg_ls_dir)
    ) as createtime 
from pg_ls_dir('.'); 

根据这篇文章中的评论PostgreSQL: Table creation time 这不是100%可靠,因为表可能已在内部删除并由于对表的操作而重新创建,例如CLUSTER。

也是模式

/main/base/<database id>/<table filenode id> 

似乎是错误的,因为在我的机器上,来自不同数据库的所有表具有相同的数据库ID,并且看起来该文件夹已被替换为一些任意的inode编号,因此您需要找到其编号最接近的文件夹到你的表的inode id(max foldername,其中folderid&lt; = table_inode_id和foldername是数字)

简化版本如下:

SELECT creation 
FROM pg_stat_file(
    './base/'
    ||
    (
        SELECT 
        MAX(pg_ls_dir::int)::text 
        FROM pg_ls_dir('./base') 
        WHERE pg_ls_dir <> 'pgsql_tmp' 
        AND  pg_ls_dir::int  <= (SELECT relfilenode FROM pg_class WHERE relname ILIKE 't_benutzer')
    )
    || '/' || (SELECT relfilenode::text FROM pg_class WHERE relname ILIKE 't_benutzer')
)

然后你可以使用information_schema和cte来简化查询,或者创建你自己的视图:

;WITH CTE AS
(
    SELECT 
        table_name 

        ,
        (
            SELECT 
                MAX(pg_ls_dir::int)::text 
            FROM pg_ls_dir('./base') 
            WHERE pg_ls_dir <> 'pgsql_tmp' 
            AND  pg_ls_dir::int  <= (SELECT relfilenode FROM pg_class WHERE relname ILIKE table_name)
        ) as folder 


        ,(SELECT relfilenode FROM pg_class WHERE relname ILIKE table_name) filenode

    FROM information_schema.tables
    WHERE table_type = 'BASE TABLE'
    AND table_schema = 'public'
)

SELECT 
    table_name 
    ,(
        SELECT creation 
        FROM pg_stat_file(
            './base/' || folder || '/' || filenode 
        )
    ) as creation_time
FROM CTE 

Create Time PostGre

(使用nhibernate模式创建的所有表都创建,因此截图中所有表上的或多或少相同的时间都是正确的。)

对于风险和副作用,请使用您的大脑和/或询问您的医生或药剂师;)

答案 1 :(得分:0)

你确定你正确地接近这个吗?你没有解释你想要做什么,但听起来好像通过日期列和分区方案可以更好地解决。