1

我正在调查 Postgres 数据库上常用的查询,以帮助减少 XID 的使用。我可以使用 获取执行的查询列表和调用次数pg_stat_statements,但它不包括因违反唯一约束等原因而失败的查询。有没有办法可以记录并计算这些失败的查询?

例子:

test_xid=# \d test
     Table "public.test"
 Column |  Type   | Modifiers 
--------+---------+-----------
 id     | integer | not null
Indexes:
    "test_pkey" PRIMARY KEY, btree (id)

test_xid=# truncate test;
TRUNCATE TABLE
test_xid=# select pg_stat_statements_reset();
 pg_stat_statements_reset 
--------------------------

(1 row)

test_xid=# select txid_current();
 txid_current 
--------------
       224547
(1 row)

test_xid=# insert into test(id) values (1);
INSERT 0 1
test_xid=# insert into test(id) values (1);
ERROR:  duplicate key value violates unique constraint "test_pkey"
DETAIL:  Key (id)=(1) already exists.
test_xid=# insert into test(id) values (1);
ERROR:  duplicate key value violates unique constraint "test_pkey"
DETAIL:  Key (id)=(1) already exists.
test_xid=# insert into test(id) values (1);
ERROR:  duplicate key value violates unique constraint "test_pkey"
DETAIL:  Key (id)=(1) already exists.
test_xid=# select txid_current();
 txid_current 
--------------
       224552
(1 row)

test_xid=# select query, calls from pg_stat_statements;
               query                | calls 
------------------------------------+-------
 insert into test(id) values (?);   |     1
 select pg_stat_statements_reset(); |     1
 select txid_current();             |     2
(3 rows)

test_xid=# select pg_stat_statements_reset();
 pg_stat_statements_reset 
--------------------------

(1 row)

test_xid=# insert into test(id) values (1);
ERROR:  duplicate key value violates unique constraint "test_pkey"
DETAIL:  Key (id)=(1) already exists.
test_xid=# select query, calls from pg_stat_statements;
               query                | calls 
------------------------------------+-------
 select pg_stat_statements_reset(); |     1
(1 row)

可以看出,如果 INSERT 查询pg_stat_statments总是失败,并且如果成功执行后查询已经存在,则调用计数不会因后续失败查询而增加,即使失败查询导致当前 XID增加。

4

1 回答 1

0

For general stats, you can look at pg_stat_database.xact_rollback. If you want to know about statements that rolled back, the only thing I can think of that doesn't involve C code is logging all statements and then looking in the logs.

If you want to dive into the C code (or pay someone to), I don't think it would be terribly difficult to add rollback support to pg_stat_statements, and I suspect the community would welcome that.

于 2016-03-22T23:27:16.790 回答