在PG数据库中如何实现可以查看表的创建时间?

原文链接:https://pgfans.cn/a/2063

相信用过GP数据库的DBA们都用过pg_stat_last_operation或者pg_stat_last_shoperation这两个系统表去查看数据库对象的元数据信息。pg_stat_last_operation主要是跟踪记录表和视图的元数据信息,pg_stat_last_shoperation则是跟踪记录角色和表空间的元数据信息。

但是在PG数据库中是没有这两个系统表的,所以每次要查找表的创建及其他信息不是凭记忆力就是一一查看日志记录,如果时间久远的话工作量就相对较大了。那么怎么才能实现和GP类似的效果呢?

以下实验基于PostgreSQL 12.11版本

创建记录DDL语句的表
  
  
  
  1. CREATE TABLE pg_stat_last_operation (

  2. id serial PRIMARY KEY,

  3. object_type text,

  4. schema_name VARCHAR(50),

  5. action_name name NOT NULL,

  6. object_identity text,

  7. statime timestamp with time zone

  8. );

创建记录DDL语句的函数get_object_time_func
  
  
  
  1. CREATE OR REPLACE FUNCTION get_object_time_func()

  2. RETURNS event_trigger

  3. LANGUAGE plpgsql

  4. AS $$

  5. DECLARE

  6. obj record;

  7. BEGIN

  8. FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands ()

  9. LOOP

  10. INSERT INTO public.pg_stat_last_operation (object_type, schema_name,action_name,object_identity,statime) SELECT obj.object_type, obj.schema_name, obj.command_tag,obj.object_identity,now();

  11. END LOOP;

  12. END;

  13. $$;

  14. CREATE FUNCTION

创建触发器,在执行DDL语句时将记录写到函数中的表中
  
  
  
  1. CREATE EVENT TRIGGER get_object__history_trigger ON ddl_command_end

  2. EXECUTE PROCEDURE get_object_time_func();

创建表进行测试
  
  
  
  1. 新建表

  2. postgres=# create table t1(id int);

  3. CREATE TABLE

  4. postgres=#select*from pg_stat_last_operation;

  5. id | object_type | schema_name | action_name | object_identity | statime

  6. ----+-------------+-------------+--------------+-----------------+-------------------------------

  7. 1| table |public| CREATE TABLE |public.t1 |2023-01-0517:18:40.825139+08

  8. (1 row)

  9. 修改表owner、授权等

  10. postgres=# alter table t1 owner to test;

  11. ALTER TABLE

  12. postgres=# grant SELECT on t1 TO test1;

  13. GRANT

  14. postgres=# revoke SELECT on t1 from test1;

  15. REVOKE

  16. postgres=# create view v_t1 asselect*from t1;

  17. CREATE VIEW

  18. postgres=#select*from pg_stat_last_operation;

  19. id | object_type | schema_name | action_name | object_identity | statime

  20. ----+-------------+-------------+--------------+-----------------+-------------------------------

  21. 1| table |public| CREATE TABLE |public.t1 |2023-01-0517:18:40.825139+08

  22. 2| table |public| ALTER TABLE |public.t1 |2023-01-0517:22:21.944326+08

  23. 3| TABLE || GRANT ||2023-01-0517:23:58.276351+08

  24. 4| TABLE || REVOKE ||2023-01-0517:24:57.607371+08

  25. 5| view |public| CREATE VIEW |public.v_t1 |2023-01-0517:26:11.191602+08

  26. (5 rows)

这里可以看到该表是有记录对表的相关DDL操作,需要注意的是虽然DDL语句中是包含DROP的,但是需要另外一个触发函数来实现。

  
  
  
  1. CREATE FUNCTION get_object_for_drops()

  2. RETURNS event_trigger LANGUAGE plpgsql AS $$

  3. DECLARE

  4. obj record;

  5. BEGIN

  6. FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()

  7. LOOP

  8. INSERT INTO public.pg_stat_last_operation (object_type, schema_name,action_name,object_identity,statime) SELECT obj.object_type, obj.schema_name,tg_tag,obj.object_identity,now();

  9. END LOOP;

  10. END;

  11. $$;

  12. CREATE EVENT TRIGGER get_object_trigger_for_drops

  13. ON sql_drop

  14. EXECUTE PROCEDURE get_object_for_drops();

删除表测试
  
  
  
  1. postgres=# drop table t1;

  2. NOTICE: DROP TABLE dropped object: table public.t1 public.t1

  3. NOTICE: DROP TABLE dropped object: type public.t1 public.t1

  4. NOTICE: DROP TABLE dropped object: type public._t1 public.t1[]

  5. DROP TABLE

  6. postgres=#select*from pg_stat_last_operation;

  7. id | object_type | schema_name | action_name | object_identity | statime

  8. ----+-------------+-------------+-----------------+-------------------------------+-------------------------------

  9. 1| table |public| CREATE TABLE |public.t1 |2023-01-0517:18:40.825139+08

  10. 2| table |public| ALTER TABLE |public.t1 |2023-01-0517:22:21.944326+08

  11. 3| TABLE || GRANT ||2023-01-0517:23:58.276351+08

  12. 4| TABLE || REVOKE ||2023-01-0517:24:57.607371+08

  13. 5| view |public| CREATE VIEW |public.v_t1 |2023-01-0517:26:11.191602+08

  14. 6| table |public| DROP TABLE |public.t1 |2023-01-0518:05:49.611115+08

  15. 7| type |public| DROP TABLE |public.t1 |2023-01-0518:05:49.611115+08

  16. 8| type |public| DROP TABLE |public.t1[]|2023-01-0518:05:49.611115+08

  17. (8 rows)

以上基本可以实现和GP中pg_stat_last_operation系统表一样的功能,但是这只针对于记录该表及函数触发器以后的DDL操作,之前的DDL语句是无法记录的。以前的就只能按照老方法去找了,如果是新启用的数据库可以一开始就创建该表及函数,这样就可以从一开始记录了,暂时写到这里,希望对大家有所帮助。


本文分享自微信公众号 - 开源软件联盟PostgreSQL分会(kaiyuanlianmeng)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部