使用 pgAudit 记录 PostgreSQL 活动

John Doe 十一月 14, 2025

金融机构、政府机构以及众多行业都需要留存审计日志,以满足监管要求。通过在 PostgreSQL 数据库实例中使用 PostgreSQL 审计扩展(pgAudit),您可以捕获审计人员通常所需或满足监管要求必备的详细记录。例如,您可以配置 pgAudit 扩展,以跟踪对特定数据库和表所做的更改、记录执行更改的用户,以及捕获其他诸多详细信息。

image

pgAudit 概述

pgAudit 扩展基于 PostgreSQL 原生日志记录的功能构建,通过添加更多细节来扩展日志消息。换句话说,您查看审计日志的方式,与查看其他所有日志消息的方式一致。

pgAudit 扩展会对日志中的敏感数据(如明文密码)进行脱敏处理。如果您的 PostgreSQL 实例已配置为记录数据操作语言(DML)语句,那么通过使用 PostgreSQL 审计扩展,您可以避免明文密码相关的安全问题。

您可以高度灵活地为数据库实例配置审计规则,既能对所有数据库和所有用户进行审计,也可以选择仅对特定数据库、特定用户及其他特定对象进行审计。您还可以明确排除某些用户和数据库,不对其进行审计。

鉴于 pgAudit 可能捕获大量详细信息,我们建议:如果您使用 pgAudit,务必监控存储消耗情况。

数据库对象审计

在 PostgreSQL 实例上设置好 pgAudit 并根据需求完成配置后,PostgreSQL 日志中会捕获更详细的信息。例如,默认的 PostgreSQL 日志配置仅能记录数据库表中更改的时间,而通过 pgAudit 扩展,日志条目可包含模式、执行更改的用户以及其他详细信息(具体取决于扩展参数的配置方式)。您可以通过以下方式设置审计以跟踪更改:

  • 按用户跟踪每个会话的更改。在会话级别,您可以捕获完全限定的命令文本。
  • 按用户和数据库跟踪每个对象的更改。

当您在系统上创建mypgaudit角色,并将该角色添加到自定义参数组的pgaudit.role参数中时,对象审计功能将被激活。以下步骤假定您已完成了 pgAudit 的初始化并创建了 pgAudit 扩展。

2025-10-07 23:36:51 UTC:postgres@1abdb:[1374]:LOG: statement: SELECT feedback, s.sentiment, s.confidence FROM support, detect_sentiment (feedback, 'en')s ORDER BY s.confidence DESC;
2025-10-07 23:36:51 UTC:postgres@1abdb:[1374]:LOG: AUDIT: SESSION, 2, 1, READ, SELECT, TABLE, public.support, "SELECT feedback, s.sentiment,s.confidence FROM support, detect_sentiment (feedback, 'en')s ORDER BY s.confidence DESC;",<none>
2025-10-07 23:36:51 UTC:postgres@1abdb:[1374]:LOG: QUERY STATISTICS
2025-10-07 23:36:51 UTC:postgres@1abdb:[1374]:DETAIL:  system usage stats:
0.009494 s user, 0.007442 s system, 0.141985 s elapsed
[0.022327 s user, 0.007442 s system total]

如上述示例所示,“LOG: AUDIT: SESSION” 行包含了表及其模式等相关信息。

配置对象审计的步骤

shared_preload_libraries参数设置为pgaudit,重启数据库,重新加载配置更改。

ALTER SYSTEM SET shared_preload_libraries = 'pgaudit';

在初始化 pgAudit 后,你现在可以创建扩展。你需要在初始化库之后创建扩展,因为 pgaudit 扩展会安装用于审计数据定义语言(DDL)语句的事件触发器。

CREATE EXTENSION pgaudit;

执行以下命令创建名为mypgaudit的数据库角色:

CREATE ROLE mypgaudit;

pgaudit.role 参数设置为 mypgaudit(默认情况下,该参数为空),重启数据库,重新加载配置更改。

ALTER SYSTEM SET pgaudit.role = 'mypgaudit';

如需测试 pgAudit 日志记录功能,可运行多个您希望审计的示例命令。例如,可执行以下命令:

CREATE TABLE t1 (id int);
GRANT SELECT ON t1 TO mypgaudit;
SELECT * FROM t1;

执行结果如下:

 id
----
(0 rows)

数据库日志中应包含类似以下内容的条目:

...
2025-06-12 19:09:49 UTC:...:test@postgres:[11701]:LOG: AUDIT: OBJECT,1,1,READ,SELECT,TABLE,public.t1,select * from t1;
...

pgAudit 扩展配置参数

您可以通过修改下面列出的一个或多个参数,指定审计日志所需的详细程度。

控制 pgAudit 行为

您可以通过修改下表中列出的一个或多个参数,对审计日志记录进行控制。

参数 说明
pgaudit.log 指定会话审计日志将记录的语句类别。允许的值包括 ddl(数据定义语言)、function(函数)、misc(杂项)、read(读取)、role(角色)、write(写入)、none(无)、all(全部)。有关详细信息,请参阅下面pgaudit.log参数允许的设置列表。
pgaudit.log_catalog 启用后(设置为 1),如果一条语句中的所有关系都位于 pg_catalog 中,则会将该语句添加到审计跟踪中。
pgaudit.log_level 指定用于日志条目的日志级别。允许的值包括:debug5、debug4、debug3、debug2、debug1、info、notice、warning、log。
pgaudit.log_parameter 启用后(设置为 1),审计日志中将捕获随语句一起传递的参数。
pgaudit.log_relation 启用后(设置为 1),会话的审计日志会为 SELECT 或 DML(数据操作语言)语句中引用的每个关系(如表、视图等)创建单独的日志条目。
pgaudit.log_statement_once 指定日志记录是在语句/子语句组合的第一条日志条目中包含语句文本和参数,还是在每条条目中都包含。
pgaudit.role 指定用于对象审计日志记录的主角色。

pgaudit.log 参数允许的设置列表

说明
none 这是默认值。不记录任何数据库更改。
all 记录所有内容(包括 read、write、function、role、ddl、misc)。
ddl 记录所有未包含在ROLE类别中的数据定义语言(DDL)语句。
function 记录函数调用和DO匿名块。
misc 记录杂项命令,例如DISCARDFETCHCHECKPOINTVACUUMSET
read 当源为关系(如表)或查询时,记录SELECTCOPY操作。
role 记录与角色和权限相关的语句,例如GRANT(授权)、REVOKE(撤销授权)、CREATE ROLE(创建角色)、ALTER ROLE(修改角色)和DROP ROLE(删除角色)。
write 当目标为关系(表)时,记录INSERT(插入)、UPDATE(更新)、DELETE(删除)、TRUNCATE(截断)和COPY操作。

若要通过会话审计记录多种事件类型,请使用逗号分隔的列表。若要记录所有事件类型,请将pgaudit.log设置为ALL。修改后需重启数据库实例,更改才能生效。

通过对象审计,您可以细化审计日志记录范围,使其仅适用于特定关系。例如,您可以指定仅对一个或多个表上的READ(读取)操作进行审计日志记录。

参考

pgaudit:https://github.com/pgaudit/pgaudit