有没有办法根据创建日期自动删除/删除所有表及与之关联的索引?
我在Postgres中找不到记录表/索引创建日期的内置/本地列。我正在运行Postgres 8.4。我以为我可以做这样的事情(伪SQL):
select all from pg_tables where creation_date is older than 90 days;
然后删除该选择的结果(对于pg_indexes也是如此)。但是,我无法找到任何类型的表或索引创建日期。我可以自己装配一些创建日期跟踪器,但我确信Postgres中会有一些原生的东西已经存储了这些信息......是吗?
由于
答案 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
(使用nhibernate模式创建的所有表都创建,因此截图中所有表上的或多或少相同的时间都是正确的。)
对于风险和副作用,请使用您的大脑和/或询问您的医生或药剂师;)
答案 1 :(得分:0)
你确定你正确地接近这个吗?你没有解释你想要做什么,但听起来好像通过日期列和分区方案可以更好地解决。