如何跟踪PostgreSQL日志中的事务?

Win*_*rle 12 postgresql transactions

我最近继承了一个使用PostgreSQL的应用程序,我一直在解决与保存数据库中的记录有关的问题.

我知道,PostgreSQL允许我通过包括特殊值记录在日志中的事务ID %xlog_line_prefix.然而,我注意到,事务中发生的第一个语句总是以零记录.

如果我在psql中执行以下操作,

begin;
insert into numbers (1);
insert into numbers (2);
commit;
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)

我的日志格式是%t %x,正如您所看到的,第一个insert语句的事务ID是0,但是当我执行第二个插入时它会更改为689.

任何人都可以解释为什么在启动事务后PostgreSQL没有在第一个语句上记录正确的事务ID?或者,如果我只是做错了,是否有更可靠的方法通过查看日志文件来识别哪些查询是单个事务的一部分?

Cra*_*ger 12

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

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

我发现记录它们都很有用.txid因为它匹配xminxmax系统列内容等; vtxid帮助我对事务中的操作进行分组.