如何找到PostgreSQL数据库最后一次更新的时间?

时间:2009-05-22 18:11:24

标签: sql postgresql metadata database-administration

我正在使用一个批量更新的postgreSQL数据库。我需要知道数据库(或数据库中的表)最后一次更新或修改的时间。

我看到postgeSQL论坛上有人建议使用日志记录并查询日志。这对我不起作用,因为我无法控制客户端代码库。

5 个答案:

答案 0 :(得分:24)

每次在特定表上进行插入/更新时,您都可以编写trigger来运行。常见的用法是将行的“created”或“last_updated”列设置为当前时间,但如果您不想更改现有表,也可以在中心位置更新时间。

例如,典型的方法如下:

CREATE FUNCTION stamp_updated() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
BEGIN
  NEW.last_updated := now();
  RETURN NEW;
END
$$;
-- repeat for each table you need to track:
ALTER TABLE sometable ADD COLUMN last_updated TIMESTAMP;
CREATE TRIGGER sometable_stamp_updated
  BEFORE INSERT OR UPDATE ON sometable
  FOR EACH ROW EXECUTE PROCEDURE stamp_updated();

然后要查找上次更新时间,您需要从您正在跟踪的每个表中选择“MAX(last_updated)”并取其中最大的一个,例如:

SELECT MAX(max_last_updated) FROM (
  SELECT MAX(last_updated) AS max_last_updated FROM sometable
  UNION ALL
  SELECT MAX(last_updated) FROM someothertable
) updates

对于具有串行(或类似生成)主键的表,您可以尝试通过使用主键索引来避免顺序扫描以查找最新更新时间,或者在last_updated上创建索引。

-- get timestamp of row with highest id
SELECT last_updated FROM sometable ORDER BY sometable_id DESC LIMIT 1

请注意,如果ID不是非常顺序,但是您需要多少准确度,这会导致稍微错误的结果? (请记住,事务意味着行可以按照与创建它们不同的顺序对您可见。)

避免向每个表添加“更新”列的另一种方法是使用中央表来存储更新时间戳。例如:

CREATE TABLE update_log(table_name text PRIMARY KEY, updated timestamp NOT NULL DEFAULT now());
CREATE FUNCTION stamp_update_log() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$
BEGIN
  INSERT INTO update_log(table_name) VALUES(TG_TABLE_NAME);
  RETURN NEW;
END
$$;
-- Repeat for each table you need to track:
CREATE TRIGGER sometable_stamp_update_log
 AFTER INSERT OR UPDATE ON sometable
 FOR EACH STATEMENT EXECUTE stamp_update_log();

这将为您提供一个表格,其中包含每个表格更新的行:您可以这样做:

SELECT MAX(updated) FROM update_log

获取上次更新时间。 (如果你愿意的话,可以按表拆分)。这个表当然会继续增长:或者在'updated'上创建一个索引(这应该会使得最新的一个很快)或者如果它适合你的用例就定期截断它(例如对表进行独占锁定,获取最新的更新时间,如果您需要定期检查是否已进行更改,请将其截断。

另一种方法 - 可能是论坛上人们的意思 - 是在数据库配置中设置'log_statement = mod'(对于集群是全局的,或者是在您需要跟踪的数据库或用户上)然后修改数据库的所有语句都将写入服务器日志。然后,您需要在数据库外部编写一些内容来扫描服务器日志,过滤掉您不感兴趣的表等。

答案 1 :(得分:4)

看起来您可以使用pg_stat_database获取交易计数,并检查这是否从一次备份运行更改为下一次 - 请参阅this dba.se answer和评论以获取更多详细信息

答案 2 :(得分:4)

我喜欢杰克的方法。您可以查询表统计信息并了解插入,更新,删除等的数量:

select n_tup_upd from pg_stat_user_tables  where relname = 'YOUR_TABLE';

每次更新都会使计数增加1.

请记住,当您拥有一个数据库时,此方法是可行的。多个实例可能需要不同的方法。

答案 3 :(得分:2)

请参阅以下文章:

MySQL与PostgreSQL:将“上次修改时间”列添加到表中 http://www.pointbeing.net/weblog/2008/03/mysql-versus-postgresql-adding-a-last-modified-column-to-a-table.html

答案 4 :(得分:0)

您可以使用“不受信任的语言”(例如plpythonu)编写存储过程:这允许访问postgres“base”目录中的文件。在存储过程中返回这些文件的大小mtime。

但这只是含糊不清,因为真空会改变这些文件和mtime。