Автоматическое удаление таблиц и индексов старше 90 дней

Есть ли способ автоматически удалить/удалить все таблицы и связанные с ними индексы на основе даты создания?

Я не могу найти встроенный/собственный столбец в Postgres, который записывает дату создания таблицы/индекса. Я запускаю Postgres 8.4. Я предположил, что смогу сделать что-то вроде этого (псевдо SQL):

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

Затем отбросьте результаты этого выбора (то же самое для pg_indexes). Однако я не могу найти какую-либо дату создания таблицы или индекса. Я могу придумать какой-то трюк для создания даты, но я точно думал, что в Postgres будет что-то, что уже хранит эту информацию... есть?

Спасибо

Ответ 1

Вы можете получить время создания, подобное этому

(Предполагая имя таблицы 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: время создания таблицы это не на 100% надежнее, потому что таблица, возможно, была внутренне сброшена и воссоздана из-за операций на столе, таких как CLUSTER.

Также шаблон

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

кажется неправильным, так как на моей машине все таблицы из разных баз данных имеют одинаковый идентификатор базы данных, и кажется, что папка была заменена каким-то произвольным номером inode, поэтому вам нужно найти папку, число которой ближе всего к вашему идентификатору inode таблицы (максимальное имя папки, где folderid <= table_inode_id и имя папки являются числовыми)

Упрощенная версия выглядит следующим образом:

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, создаются, поэтому более или менее одинаковое время для всех таблиц на скриншоте правильно).

Для риска и побочных эффектов используйте свой мозг и/или попросите своего врача или фармацевта;)

Ответ 2

Вы уверены, что приближаетесь к этому правильно? Вы не объяснили, что вы пытаетесь сделать, но это похоже на то, что, возможно, это было бы лучше разрешено с помощью столбца даты и схемы разделов.