My Salesforce colleague Teja Mupparti found an interesting bug. Consider the following example:
drop table if exists test; create table test(i int); insert into test values(1); select pg_sleep(1); begin; insert into test values(2); insert into test values(3); select pg_stat_get_xact_tuples_inserted('test'::regclass); commit; select pg_sleep(1); begin; insert into test values(4); insert into test values(5); select pg_stat_get_xact_tuples_inserted('test'::regclass); commit; If you do this by hand, or with the above script verbatim, the pg_stat_get_xact_tuples_inserted() calls both report "2", which is what you'd expect: the counts are supposed to reflect rows inserted in the current transaction. However, if you take out the pg_sleep calls, you get entirely different results, and soon realize that the counts are including the previous transactions! The reason for this is that pgstat_report_stat() includes a delay check, such that it doesn't ship off statistics counts to the collector unless at least 500 ms have elapsed since the last report. Without the sleeps, the later transactions execute while the previous transactions' counts are still being held locally, *and those counts get included into the reported totals*. This seems like a pretty clear bug to me; does anyone want to argue that it isn't? In the case of pg_stat_get_xact_tuples_inserted and a couple of other routines, it would be entirely trivial to fix: just ignore tabentry->t_counts.t_tuples_inserted (which is the count held over from previous transactions) and only total the trans->tuples_inserted counters. However, for a number of other counters such as blocks_fetched, we don't store transaction-local counts separately, and would have to start doing so if we wanted to make these functions work as documented. Thoughts? I have other things to do right now than fix this myself. regards, tom lane -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers