如何将“ALTER table [...] ADD column”之类的更改记录到我的 PostgreSQL 表中?
Posted
技术标签:
【中文标题】如何将“ALTER table [...] ADD column”之类的更改记录到我的 PostgreSQL 表中?【英文标题】:How can I log changes like "ALTER table [...] ADD column" to my PostgreSQL table? 【发布时间】:2020-01-06 02:06:28 【问题描述】:我想记录一列何时添加到我的表中。我已经找到了概述 (information_schema.columns
)。但是,这里缺少时间,甚至不显示已删除的列。我正在使用 PostgreSQL 8.4.4,我可以更新到 9.6.5
我的想法是在information_schema.columns
上触发,但这不起作用,因为它不是表格。
【问题讨论】:
为什么要在 2019 年升级到“仅”9.6?为什么不升级到当前版本? (11 - 即将成为 12)如果由于某种原因你真的被限制在 9.6,你至少需要 9.6.15,这是 9.6 分支中的最新版本 【参考方案1】:对于较新版本的 postgres,您可以使用 event triggers。除非您用 C 编写函数来解析 pg_ddl_command 类型,否则您似乎无法获取有关添加的实际列的信息,但您可以获得有关受影响的表、谁做的以及何时做的信息:
CREATE TABLE alter_table_log (
id bigserial primary key,
tstamp timestamp with time zone default now(),
table_id regclass,
altered_by regrole
);
GRANT insert, select on table alter_table_log to public;
GRANT usage on alter_table_log_id_seq to public;
CREATE OR REPLACE FUNCTION log_alter_trig()
RETURNS event_trigger
LANGUAGE plpgsql AS
$$
BEGIN
INSERT INTO alter_table_log(table_id, altered_by)
select obj.objid::regclass, current_user::regrole
FROM (select * from pg_event_trigger_ddl_commands()) as obj;
END
$$;
CREATE EVENT TRIGGER log_alter_trig
ON ddl_command_end
WHEN TAG IN ('ALTER TABLE')
EXECUTE PROCEDURE log_alter_trig();
create table test (a text);
alter table test add column b text;
select * from alter_table_log;
id | tstamp | table_id | altered_by
----+-------------------------------+----------+------------
1 | 2019-09-03 13:21:36.361964+00 | test | postgres
您将无法在 8.4 中执行此操作。我建议更新到 11。在不再支持之前,9.6 不会为您争取太多时间。
【讨论】:
【参考方案2】:您应该能够利用Postgres Reporting and Logging tools:
基本上,您需要将log_statement
参数设置为(至少)'ddl'
:
ddl
记录所有数据定义语句,如CREATE
、ALTER
和DROP
语句
那么您应该能够在服务器日志中使用 grep 表达式,例如 "alter table <mytable> add column"
。
PS:
您需要reload the configuration 才能使更改生效
如果大量 DDL 操作发生在您的数据库中,此设置可能会生成大量日志,从而使此解决方案有点过头了
【讨论】:
首先,谢谢。有用。但这并不是我真正想要的。登录已经在 (log_destination = 'stderr'
) 上运行,我不能将其设置为 ('csvlog'
) 以获得更好的概览,因为我正在使用外部软件。现在我必须定期解析日志文件并将其写入数据库。是否有更优雅的解决方案可以直接格式化保存数据?我可以设置(log_destination to 'stderr' and 'csvlog'
)并只保存(log_statement = 'ddl' in 'csvlog'
)吗?
@Andreas;好吧,您可以使用如下表达式设置多个日志记录目标:log_destination('stderr,csvlog')
。但是,我认为每个目的地不可能有不同的登录设置。以上是关于如何将“ALTER table [...] ADD column”之类的更改记录到我的 PostgreSQL 表中?的主要内容,如果未能解决你的问题,请参考以下文章
sql [ALTER TABLE ADD COLUMN]将新列添加到现有表#SQL
SQL ALTER TABLE ADD PRIMARY KEY 错误 1064