PostgreSQL 日志触发器/函数查询数据

Posted

技术标签:

【中文标题】PostgreSQL 日志触发器/函数查询数据【英文标题】:PostgreSQL log trigger/function query data 【发布时间】:2021-03-09 07:11:24 【问题描述】:

我们在 SQL 查询(约 200 个触发器)中有业务逻辑,用于补充我们的应用程序代码。而且我们有一些错误 - 为了找到它们,我想查看所有更改数据库中任何内容的事务(而不是手动检查 40 个表)。

我们通过设置启用登录/etc/postgresql/10/main/postgresql.conf

log_statement = 'mod' # none, ddl, mod, all

这会正确记录来自应用程序的所有 INSERT/DELETE/UPDATE 语句,如下所示:

INSERT INTO misc.object_types (uuid, object_type_schema, object_type_table) VALUES 'e49fcebd-e8f4-4ca4-b664-e7194685ae3f', 'gis', 'lines')

但不记录 SQL 函数执行的操作。设置

track_functions = all # none, pl, all

在 conf 文件中确实显示了触发器/函数已被执行。但我对所有值的实际 SQL 语句感兴趣,就像 log_statement= 'mod'

现在我在这里找到了一些主题,但它们都依赖于手动创建audit table 或使用RAISE 手动登录(比如这个Log firing of triggers in postgres 9.1)。

如何在没有手动(容易出错)代码的情况下启用由触发器/函数执行的查询的日志记录?

更重要的是:为什么触发器/函数的处理方式与常规查询不同?这是否也意味着触发器调用的 INSERT 与手动 INSERT 不同?

【问题讨论】:

【参考方案1】:

log_statement 将只记录***语句,即客户端发送的语句。不记录嵌套语句。

记录这些的一种方法是使用auto_explain contrib 模块。您必须启用它,设置auto_explain.log_nested_statements = onauto_explain.log_min_duration = 0。然后将记录所有语句,甚至是嵌套语句,以及它们的执行计划。

【讨论】:

感谢 Laurenz-Albe 的指点!现在我确实得到了日志输出,但使用的是变量而不是值。 INSERT INTO misc.object_types (uuid, object_type_schema, object_type_table, label) VALUES (NEW.uuid, TG_TABLE_SCHEMA, TG_TABLE_NAME, NEW.label) ON CONFLICT DO NOTHING关于如何进一步深入研究的任何想法?而不是变量名 NEW.uuid 我想查看写入数据库的值(我确认我在数据库中有一个值)。我在 EXPLAIN 和 AUTO_EXPLAIN 中都找不到开关。 要了解更多信息,您必须在代码中添加RAISE NOTICE 才能输出数据。

以上是关于PostgreSQL 日志触发器/函数查询数据的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL新手入门

PostgreSQL 9.3 触发函数以参数化名称插入表

如何查看本地安装的Postgresql版本号

PostgreSQL入门,PostgreSQL和mysql

PostgreSQL 查询耗时过长

Postgresql 插入触发器以设置值