Thread: unreliable behaviour of track_functions

unreliable behaviour of track_functions

From
pinker
Date:
Hi All!

I've been experimenting with track_functions options and what I've saw it's
really puzzling me.
Documentation says: 
/ SQL-language functions that are simple enough to be "inlined" into the
calling query will not be tracked, regardless of this setting./

But it came up, it depends on much more factors, like duration or placing it
in the query, it is totally non-deterministic behaviour.

This really simple SQL function:
CREATE FUNCTION a(a bigint)
  RETURNS bigint
STABLE
LANGUAGE SQL
AS $$
SELECT $1
$$;

Is not shown in the pg_stat_user_functions at all. It is started to be shown
when one line:
select pg_sleep(1);

is added???

Another one, gets tracked only if I use:
SELECT get_unique_term(2556);

If it lands in FROM then it's not tracked...
SELECT * FROM get_unique_term(2556);

That's the body of the function:
CREATE FUNCTION get_unique_term(i_game_pin bigint)
  RETURNS TABLE(term text, category text)
STABLE
LANGUAGE SQL
AS $$
SELECT
  i.term,
  i.dict_category_id
FROM (SELECT
        categories.term,
        categories.dict_category_id
      FROM categories
      EXCEPT ALL
      SELECT
        games.term,
        games.category
      FROM games
      WHERE game_pin = $1) i
ORDER BY (random())
LIMIT 1;
$$;

What's going on here? That's pretty unreliable behaviour...


My version of postgres:
 PostgreSQL 9.6.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.3
20140911 (Red Hat 4.8.3-9), 64-bit

show track_functions;
 track_functions 
-----------------
 all
(1 wiersz)



 




--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: unreliable behaviour of track_functions

From
Adrian Klaver
Date:
On 03/31/2018 04:40 PM, pinker wrote:
> Hi All!
> 
> I've been experimenting with track_functions options and what I've saw it's
> really puzzling me.
> Documentation says:
> / SQL-language functions that are simple enough to be "inlined" into the
> calling query will not be tracked, regardless of this setting./
> 
> But it came up, it depends on much more factors, like duration or placing it
> in the query, it is totally non-deterministic behaviour.
> 
> This really simple SQL function:
> CREATE FUNCTION a(a bigint)
>    RETURNS bigint
> STABLE
> LANGUAGE SQL
> AS $$
> SELECT $1
> $$;
> 
> Is not shown in the pg_stat_user_functions at all. It is started to be shown
> when one line:
> select pg_sleep(1);
> 
> is added???
> 
> Another one, gets tracked only if I use:
> SELECT get_unique_term(2556);
> 
> If it lands in FROM then it's not tracked...
> SELECT * FROM get_unique_term(2556);
> 
> That's the body of the function:
> CREATE FUNCTION get_unique_term(i_game_pin bigint)
>    RETURNS TABLE(term text, category text)
> STABLE
> LANGUAGE SQL
> AS $$
> SELECT
>    i.term,
>    i.dict_category_id
> FROM (SELECT
>          categories.term,
>          categories.dict_category_id
>        FROM categories
>        EXCEPT ALL
>        SELECT
>          games.term,
>          games.category
>        FROM games
>        WHERE game_pin = $1) i
> ORDER BY (random())
> LIMIT 1;
> $$;
> 
> What's going on here? That's pretty unreliable behaviour...

?:

https://www.postgresql.org/docs/10/static/monitoring-stats.html#PG-STAT-USER-FUNCTIONS-VIEW

"...But if you want to see new results with each query, be sure to do 
the queries outside any transaction block. Alternatively, you can invoke 
pg_stat_clear_snapshot(), which will discard the current transaction's 
statistics snapshot (if any). The next use of statistical information 
will cause a new snapshot to be fetched.

A transaction can also see its own statistics (as yet untransmitted to 
the collector) in the views pg_stat_xact_all_tables, 
pg_stat_xact_sys_tables, pg_stat_xact_user_tables, and 
pg_stat_xact_user_functions. These numbers do not act as stated above; 
instead they update continuously throughout the transaction.

"
> 
> 
> My version of postgres:
>   PostgreSQL 9.6.6 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.3
> 20140911 (Red Hat 4.8.3-9), 64-bit
> 
> show track_functions;
>   track_functions
> -----------------
>   all
> (1 wiersz)
> 
> 
> 
>   
> 
> 
> 
> 
> --
> Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html
> 
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com


Re: unreliable behaviour of track_functions

From
pinker
Date:
Adrian Klaver-4 wrote
> https://www.postgresql.org/docs/10/static/monitoring-stats.html#PG-STAT-USER-FUNCTIONS-VIEW
> 
> "...But if you want to see new results with each query, be sure to do 
> the queries outside any transaction block. Alternatively, you can invoke 
> pg_stat_clear_snapshot(), which will discard the current transaction's 
> statistics snapshot (if any). The next use of statistical information 
> will cause a new snapshot to be fetched.
> 
> A transaction can also see its own statistics (as yet untransmitted to 
> the collector) in the views pg_stat_xact_all_tables, 
> pg_stat_xact_sys_tables, pg_stat_xact_user_tables, and 
> pg_stat_xact_user_functions. These numbers do not act as stated above; 
> instead they update continuously throughout the transaction.
> 
> "
> Adrian Klaver

> adrian.klaver@


Thank you for that, but does this strange behaviour should not be better
documented? 
If somebody (like me, I have some time ago being unaware of this behaviour)
wants to build a monitoring system that base on the view
pg_stat_user_functions, should not be informed what to expect?




--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: unreliable behaviour of track_functions

From
Adrian Klaver
Date:
On 03/31/2018 05:17 PM, pinker wrote:
> Adrian Klaver-4 wrote
>> https://www.postgresql.org/docs/10/static/monitoring-stats.html#PG-STAT-USER-FUNCTIONS-VIEW
>>
>> "...But if you want to see new results with each query, be sure to do
>> the queries outside any transaction block. Alternatively, you can invoke
>> pg_stat_clear_snapshot(), which will discard the current transaction's
>> statistics snapshot (if any). The next use of statistical information
>> will cause a new snapshot to be fetched.
>>
>> A transaction can also see its own statistics (as yet untransmitted to
>> the collector) in the views pg_stat_xact_all_tables,
>> pg_stat_xact_sys_tables, pg_stat_xact_user_tables, and
>> pg_stat_xact_user_functions. These numbers do not act as stated above;
>> instead they update continuously throughout the transaction.
>>
>> "
>> Adrian Klaver
> 
>> adrian.klaver@
> 
> 
> Thank you for that, but does this strange behaviour should not be better
> documented?

This came from the documentation, so I am not sure what you mean by 
better documented?

> If somebody (like me, I have some time ago being unaware of this behaviour)
> wants to build a monitoring system that base on the view
> pg_stat_user_functions, should not be informed what to expect?

See comment above.

> 
> 
> 
> 
> --
> Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html
> 
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com


Re: unreliable behaviour of track_functions

From
pinker
Date:
I mean this part describing track_function:

https://www.postgresql.org/docs/10/static/runtime-config-statistics.html

Enables tracking of function call counts and time used. Specify pl to track
only procedural-language functions, all to also track SQL and C language
functions. The default is none, which disables function statistics tracking.
Only superusers can change this setting.

Note
SQL-language functions that are simple enough to be “inlined” into the
calling query will not be tracked, regardless of this setting.

Only case described here, that exclude function from being tracked it's
inlining, not the time and not the place in the query.
So I would expect that pg_stat_user_function will show me that my function
was executed. Good that are other ways to do it, but changing
track_functions to 'all' I would expect all calls will be tracked...



--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: unreliable behaviour of track_functions

From
pinker
Date:
I mean this part describing track_function:

https://www.postgresql.org/docs/10/static/runtime-config-statistics.html

Enables tracking of function call counts and time used. Specify pl to track
only procedural-language functions, all to also track SQL and C language
functions. The default is none, which disables function statistics tracking.
Only superusers can change this setting.

Note
SQL-language functions that are simple enough to be “inlined” into the
calling query will not be tracked, regardless of this setting.

Only case described here, that exclude function from being tracked it's
inlining, not the time and not the place in the query.
So I would expect that pg_stat_user_function will show me that my function
was executed. Good that are other ways to do it, but changing
track_functions to 'all' I would expect all calls will be tracked...



--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: unreliable behaviour of track_functions

From
pinker
Date:
and to be clear I was experimenting with pg_stat_clear_snapshot() after your
answer, but it doesn't change behaviour of track_functions.



--
Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html


Re: unreliable behaviour of track_functions

From
Adrian Klaver
Date:
On 04/01/2018 06:02 AM, pinker wrote:
> I mean this part describing track_function:
> 
> https://www.postgresql.org/docs/10/static/runtime-config-statistics.html
> 
> Enables tracking of function call counts and time used. Specify pl to track
> only procedural-language functions, all to also track SQL and C language
> functions. The default is none, which disables function statistics tracking.
> Only superusers can change this setting.
> 
> Note
> SQL-language functions that are simple enough to be “inlined” into the
> calling query will not be tracked, regardless of this setting.
> 
> Only case described here, that exclude function from being tracked it's
> inlining, not the time and not the place in the query.

The below might help:

https://wiki.postgresql.org/wiki/Inlining_of_SQL_functions

In particular for your second case(place in query):

" Table functions

A table function call is any instance where func(args) appears where a 
table is expected. (This is, for most functions, a PostgreSQL extension 
to the SQL standard.) For example:

select * from func(123);
"

For your first case:

Inlining conditions for scalar functions

"the function body consists of a single, simple, SELECT expression"

So from your OP:

CREATE FUNCTION a(a bigint)
   RETURNS bigint
STABLE
LANGUAGE SQL
AS $$
SELECT $1
$$;

If you change to:

CREATE FUNCTION a(a bigint)
   RETURNS bigint
STABLE
LANGUAGE SQL
AS $$
SELECT 'test';
SELECT $1
$$;

then before change:

test=> select * from pg_stat_user_functions ;
  funcid  | schemaname | funcname | calls | total_time | self_time
---------+------------+----------+-------+------------+-----------
  1386647 | public     | a        |     2 |   1251.598 |  1251.598
(1 row)


after change:

test=> select * from pg_stat_user_functions ;
  funcid  | schemaname | funcname | calls | total_time | self_time
---------+------------+----------+-------+------------+-----------
  1386647 | public     | a        |     3 |   1251.682 |  1251.682





> So I would expect that pg_stat_user_function will show me that my function
> was executed. Good that are other ways to do it, but changing
> track_functions to 'all' I would expect all calls will be tracked...
> 
> 
> 
> --
> Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html
> 
> 


-- 
Adrian Klaver
adrian.klaver@aklaver.com