2016-09-20 67 views
6

我最近继承了一个使用PostgreSQL的应用程序,并且一直在解决与在数据库中保存记录有关的问题。如何跟踪PostgreSQL日志中的事务?

我知道PostgreSQL允许我通过在log_line_prefix中包含特殊值%x来记录交易ID。但是,我注意到,事务中发生的第一条语句总是以零记录。

如果我执行PSQL以下操作,

begin; 
insert into numbers (1); 
insert into numbers (2); 
commit; 

查询日志将包含以下项目:

2016-09-20 03:07:40 UTC 0 LOG: statement: begin; 
2016-09-20 03:07:53 UTC 0 LOG: statement: insert into numbers values (1); 
2016-09-20 03:07:58 UTC 689 LOG: statement: insert into numbers values (2); 
2016-09-20 03:08:03 UTC 689 LOG: statement: commit; 

我的日志格式%t %x,正如你所看到的,事务ID对于第一个插入语句是0,但是当我执行第二个插入时它变为689。

任何人都可以解释为什么开始一个事务后PostgreSQL不会在第一条语句上记录正确的事务ID吗?或者,如果我只是做了这个错误,是否有一种更可靠的方式通过查看日志文件来确定哪些查询是单个事务的一部分?

回答

8

事务ID在语句开始后分配,因此log_statement不捕获它。 BEGIN不分配事务ID,它会延迟到第一次写入操作。

使用虚拟txid,而不是立即分配。占位符是%v。这些被立即分配,但不是持久的,并且是后端本地的。

我觉得记录两者都很有用。 txid因为它匹配到xminxmax系统列的内容等; vtxid帮助我将交易中完成的操作分组。