我最近继承了一个使用PostgreSQL的应用程序,我一直在解决与保存数据库中的记录有关的问题。
我知道PostgreSQL允许我通过在%x
中包含log_line_prefix
的特殊值来记录日志中的事务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
,如您所见,第一个insert语句的事务ID为0,但是当我执行第二个插入时,它会更改为689.
有人可以解释为什么在启动事务后PostgreSQL没有在第一个语句上记录正确的事务ID吗?或者,如果我这样做错了,是否有更可靠的方法通过查看日志文件来识别哪些查询属于单个事务?
答案 0 :(得分:9)
事务ID在语句开始后分配,因此log_statement
不会捕获它。 BEGIN
没有分配交易ID,它会延迟到第一次写入操作。
使用虚拟txid代替,立即分配。占位符为%v
。这些是立即分配的,但不是持久性的,并且是后端本地的。
我发现记录它们都很有用。 txid因为它匹配xmin
和xmax
系统列内容等; vtxid帮助我对事务中的操作进行分组。