如何为 Postgresql 审计触发器设置用户名?
Posted
技术标签:
【中文标题】如何为 Postgresql 审计触发器设置用户名?【英文标题】:How can I set a username for a Postgresql audit trigger? 【发布时间】:2010-11-10 17:32:49 【问题描述】:我在 PostgreSQL 8.2 中使用触发器来审核对表的更改:
CREATE OR REPLACE FUNCTION update_issue_history() RETURNS trigger as $trig$
BEGIN
INSERT INTO issue_history (username, issueid)
VALUES ('fixed-username', OLD.issueid);
RETURN NULL;
END;
$trig$ LANGUAGE plpgsql;
CREATE TRIGGER update_issue_history_trigger
AFTER UPDATE ON issue
FOR EACH ROW EXECUTE PROCEDURE update_issue_history();
我想要做的是在执行更新时提供fixed-username
的值。这可能吗?如果是这样,我该如何完成?
【问题讨论】:
Passing user id to PostgreSQL triggers 的可能重复项 答案 [在这里][1] 总结得很好。 [1]:***.com/a/13172964/947357 8.2?请阅读postgresql.org/support/versioning 并开始规划您的升级。 可能是这样的情况,一个关于旧版本的四年前的问题可能不需要关于升级的警告。碰巧,我什至不再在那里工作了:) 我刚刚在下面更新了我的答案,但我同意另一个更好,并且可以在任何版本上使用,这应该作为重复关闭。 【参考方案1】:试试这样的:
CREATE OR REPLACE FUNCTION update_issue_history()
RETURNS trigger as $trig$
DECLARE
arg_username varchar;
BEGIN
arg_username := TG_ARGV[0];
INSERT INTO issue_history (username, issueid)
VALUES (arg_username, OLD.issueid);
RETURN NULL;
END;
$trig$ LANGUAGE plpgsql;
CREATE TRIGGER update_issue_history_trigger
AFTER UPDATE ON issue
FOR EACH ROW EXECUTE PROCEDURE update_issue_history('my username value');
【讨论】:
【参考方案2】:除了创建临时表并在触发器中使用 EXECUTE 之外,我没有看到其他方法。但是,这将产生性能影响。更好的选择可能是在某个地方绑定到另一个表,并通过会话 ID 和后端 PID 登录/注销谁,然后引用它?
请注意,您没有任何其他方法可以将信息放入更新语句中。请记住,触发器只能查看 API 或数据库中可用的内容。如果您希望触发器透明地工作,则不能期望在运行时将信息传递给它,否则它将无法访问。
您必须问的基本问题是“数据库如何知道要放什么?”一旦你决定了一种方法,答案应该是直截了当的,但没有免费的午餐。
更新
过去,当我以应用程序角色登录数据库时,我不得不做这样的事情,我这样做的方式是创建一个临时表,然后从存储过程中访问该表。目前存储过程可以通过这种方式处理临时表,但过去我们必须使用 EXECUTE。
这种方法有两个巨大的限制。首先是它创建了很多表,这最终导致了 oid wraparound 的可能性。
这些天来,我更喜欢将登录到数据库的用户登录。这使得这更容易管理,您可以通过值 SESSION_USER
访问(一个新手错误是使用 CURRENT_USER
,它向您显示当前的安全上下文而不是用户的登录。
这些方法都不适用于连接池。在第一种情况下,您不能进行连接池,因为您的临时表会被误解或破坏。第二种,因为登录角色不同,所以不能这样做。
【讨论】:
以上是关于如何为 Postgresql 审计触发器设置用户名?的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Postgresql 中的所有数据库创建具有只读权限的用户?