Thread: pgsql: Include information on buffer usage during planning phase, in EX

pgsql: Include information on buffer usage during planning phase, in EX

From
Fujii Masao
Date:
Include information on buffer usage during planning phase, in EXPLAIN output.

When BUFFERS option is enabled, EXPLAIN command includes the information
on buffer usage during each plan node, in its output. In addition to that,
this commit makes EXPLAIN command include also the information on
buffer usage during planning phase, in its output. This feature makes it
easier to discern the cases where lots of buffer access happen during
planning.

Author: Julien Rouhaud, slightly revised by Fujii Masao
Reviewed-by: Justin Pryzby
Discussion: https://postgr.es/m/16109-26a1a88651e90608@postgresql.org

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/ed7a5095716ee498ecc406e1b8d5ab92c7662d10

Modified Files
--------------
src/backend/commands/explain.c        | 32 ++++++++++++++++++--
src/backend/commands/prepare.c        | 13 ++++++++-
src/include/commands/explain.h        |  3 +-
src/test/regress/expected/explain.out | 55 ++++++++++++++++++++++++++++++++---
4 files changed, 95 insertions(+), 8 deletions(-)


Re: pgsql: Include information on buffer usage during planningphase, in EX

From
Michael Paquier
Date:
Hi Fujii-san,

On Fri, Apr 03, 2020 at 02:28:27AM +0000, Fujii Masao wrote:
> Include information on buffer usage during planning phase, in EXPLAIN output.
>
> When BUFFERS option is enabled, EXPLAIN command includes the information
> on buffer usage during each plan node, in its output. In addition to that,
> this commit makes EXPLAIN command include also the information on
> buffer usage during planning phase, in its output. This feature makes it
> easier to discern the cases where lots of buffer access happen during
> planning.

prion did not like that:
https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=prion&dt=2020-04-03%2002%3A33%3A13

Here is the diff from test explain:
@@ -73,8 +73,9 @@
  Seq Scan on int8_tbl i8  (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
    Buffers: shared [read]
  Planning Time: N.N ms
+   Buffers: shared [read]
  Execution Time: N.N ms
-(4 rows)
+(5 rows)

Note that this animal uses -DRELCACHE_FORCE_RELEASE and
-DCATCACHE_FORCE_RELEASE.
--
Michael

Attachment

Re: pgsql: Include information on buffer usage during planning phase,in EX

From
Fujii Masao
Date:

On 2020/04/03 11:58, Michael Paquier wrote:
> Hi Fujii-san,
> 
> On Fri, Apr 03, 2020 at 02:28:27AM +0000, Fujii Masao wrote:
>> Include information on buffer usage during planning phase, in EXPLAIN output.
>>
>> When BUFFERS option is enabled, EXPLAIN command includes the information
>> on buffer usage during each plan node, in its output. In addition to that,
>> this commit makes EXPLAIN command include also the information on
>> buffer usage during planning phase, in its output. This feature makes it
>> easier to discern the cases where lots of buffer access happen during
>> planning.
> 
> prion did not like that:
> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=prion&dt=2020-04-03%2002%3A33%3A13
> 
> Here is the diff from test explain:
> @@ -73,8 +73,9 @@
>    Seq Scan on int8_tbl i8  (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
>      Buffers: shared [read]
>    Planning Time: N.N ms
> +   Buffers: shared [read]
>    Execution Time: N.N ms
> -(4 rows)
> +(5 rows)
> 
> Note that this animal uses -DRELCACHE_FORCE_RELEASE and
> -DCATCACHE_FORCE_RELEASE.

Thanks for reporting that!

Since we're now developing very heavily because of the last CF,
it's not good to keep the buildfarm red for a long time. So I just
reverted the commit. Then I will consider how to address the issue.

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION



Fujii Masao <masao.fujii@oss.nttdata.com> writes:
> On 2020/04/03 11:58, Michael Paquier wrote:
>> prion did not like that:
>> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=prion&dt=2020-04-03%2002%3A33%3A13

dory failed as well.  The problem is that in text mode, a Buffers line
won't appear at all if there were zero buffer accesses.  I don't think
we really want to change that, so probably the thing to do is adapt
the filter functions in explain.sql so that they suppress Buffers lines
altogether in text output.  Kind of annoying, but ...

            regards, tom lane



Re: pgsql: Include information on buffer usage during planning phase,in EX

From
Fujii Masao
Date:

On 2020/04/03 12:30, Tom Lane wrote:
> Fujii Masao <masao.fujii@oss.nttdata.com> writes:
>> On 2020/04/03 11:58, Michael Paquier wrote:
>>> prion did not like that:
>>> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=prion&dt=2020-04-03%2002%3A33%3A13
> 
> dory failed as well.  The problem is that in text mode, a Buffers line
> won't appear at all if there were zero buffer accesses.  I don't think
> we really want to change that,

Yes.

> so probably the thing to do is adapt
> the filter functions in explain.sql so that they suppress Buffers lines
> altogether in text output.  Kind of annoying, but ...

I'm thinking to suppress only Buffers line just after Planning Time line,
by applying something like the following changes to explain_filter().
Thought?

  declare
      ln text;
+    ignore_output boolean;
  begin
      for ln in execute $1
      loop
+        IF ignore_output THEN
+            ignore_output := false;
+            CONTINUE WHEN (ln ~~ '  Buffers: %');
+        END IF;
+        ignore_output := ln ~~ 'Planning Time: %';
          -- Replace any numeric word with just 'N'
          ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
          -- In sort output, the above won't match units-suffixed numbers

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION



Re: pgsql: Include information on buffer usage during planningphase, in EX

From
Julien Rouhaud
Date:
On Fri, Apr 03, 2020 at 03:24:41PM +0900, Fujii Masao wrote:
> 
> 
> On 2020/04/03 12:30, Tom Lane wrote:
> > Fujii Masao <masao.fujii@oss.nttdata.com> writes:
> > > On 2020/04/03 11:58, Michael Paquier wrote:
> > > > prion did not like that:
> > > > https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=prion&dt=2020-04-03%2002%3A33%3A13
> > 
> > dory failed as well.  The problem is that in text mode, a Buffers line
> > won't appear at all if there were zero buffer accesses.  I don't think
> > we really want to change that,
> 
> Yes.
> 
> > so probably the thing to do is adapt
> > the filter functions in explain.sql so that they suppress Buffers lines
> > altogether in text output.  Kind of annoying, but ...
> 
> I'm thinking to suppress only Buffers line just after Planning Time line,
> by applying something like the following changes to explain_filter().
> Thought?


+1, that's a better workaround.


> 
>  declare
>      ln text;
> +    ignore_output boolean;
>  begin
>      for ln in execute $1
>      loop
> +        IF ignore_output THEN
> +            ignore_output := false;
> +            CONTINUE WHEN (ln ~~ '  Buffers: %');
> +        END IF;
> +        ignore_output := ln ~~ 'Planning Time: %';
>          -- Replace any numeric word with just 'N'
>          ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
>          -- In sort output, the above won't match units-suffixed numbers


I'm not sure of what's plpgsql behavior here, but it's probably better to
initialize ignore_output to false.  Nitpicking, but I think that
planning_time_found, or something similar, would be better here.



Re: pgsql: Include information on buffer usage during planning phase,in EX

From
Fujii Masao
Date:

On 2020/04/03 16:43, Julien Rouhaud wrote:
> On Fri, Apr 03, 2020 at 03:24:41PM +0900, Fujii Masao wrote:
>>
>>
>> On 2020/04/03 12:30, Tom Lane wrote:
>>> Fujii Masao <masao.fujii@oss.nttdata.com> writes:
>>>> On 2020/04/03 11:58, Michael Paquier wrote:
>>>>> prion did not like that:
>>>>> https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=prion&dt=2020-04-03%2002%3A33%3A13
>>>
>>> dory failed as well.  The problem is that in text mode, a Buffers line
>>> won't appear at all if there were zero buffer accesses.  I don't think
>>> we really want to change that,
>>
>> Yes.
>>
>>> so probably the thing to do is adapt
>>> the filter functions in explain.sql so that they suppress Buffers lines
>>> altogether in text output.  Kind of annoying, but ...
>>
>> I'm thinking to suppress only Buffers line just after Planning Time line,
>> by applying something like the following changes to explain_filter().
>> Thought?
> 
> 
> +1, that's a better workaround.
> 
> 
>>
>>   declare
>>       ln text;
>> +    ignore_output boolean;
>>   begin
>>       for ln in execute $1
>>       loop
>> +        IF ignore_output THEN
>> +            ignore_output := false;
>> +            CONTINUE WHEN (ln ~~ '  Buffers: %');
>> +        END IF;
>> +        ignore_output := ln ~~ 'Planning Time: %';
>>           -- Replace any numeric word with just 'N'
>>           ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
>>           -- In sort output, the above won't match units-suffixed numbers
> 
> 
> I'm not sure of what's plpgsql behavior here, but it's probably better to
> initialize ignore_output to false.

Thanks for the review! Yes, that's necessary.

> Nitpicking, but I think that
> planning_time_found, or something similar, would be better here.

Yeah, that sounds better.

Attached is the updated version of the patch.

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION

Attachment

Re: pgsql: Include information on buffer usage during planningphase, in EX

From
Julien Rouhaud
Date:
On Fri, Apr 03, 2020 at 09:27:38PM +0900, Fujii Masao wrote:
> 
> 
> On 2020/04/03 16:43, Julien Rouhaud wrote:
> > On Fri, Apr 03, 2020 at 03:24:41PM +0900, Fujii Masao wrote:
> > > 
> > > 
> > > On 2020/04/03 12:30, Tom Lane wrote:
> > > > Fujii Masao <masao.fujii@oss.nttdata.com> writes:
> > > > > On 2020/04/03 11:58, Michael Paquier wrote:
> > > > > > prion did not like that:
> > > > > > https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=prion&dt=2020-04-03%2002%3A33%3A13
> > > > 
> > > > dory failed as well.  The problem is that in text mode, a Buffers line
> > > > won't appear at all if there were zero buffer accesses.  I don't think
> > > > we really want to change that,
> > > 
> > > Yes.
> > > 
> > > > so probably the thing to do is adapt
> > > > the filter functions in explain.sql so that they suppress Buffers lines
> > > > altogether in text output.  Kind of annoying, but ...
> > > 
> > > I'm thinking to suppress only Buffers line just after Planning Time line,
> > > by applying something like the following changes to explain_filter().
> > > Thought?
> > 
> > 
> > +1, that's a better workaround.
> > 
> > 
> > > 
> > >   declare
> > >       ln text;
> > > +    ignore_output boolean;
> > >   begin
> > >       for ln in execute $1
> > >       loop
> > > +        IF ignore_output THEN
> > > +            ignore_output := false;
> > > +            CONTINUE WHEN (ln ~~ '  Buffers: %');
> > > +        END IF;
> > > +        ignore_output := ln ~~ 'Planning Time: %';
> > >           -- Replace any numeric word with just 'N'
> > >           ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
> > >           -- In sort output, the above won't match units-suffixed numbers
> > 
> > 
> > I'm not sure of what's plpgsql behavior here, but it's probably better to
> > initialize ignore_output to false.
> 
> Thanks for the review! Yes, that's necessary.
> 
> > Nitpicking, but I think that
> > planning_time_found, or something similar, would be better here.
> 
> Yeah, that sounds better.
> 
> Attached is the updated version of the patch.


Thanks Fuji-san!  Just to be extra safe I locally added an extra

RAISE notice '%', ln;

before the continue and I confirm that this is only filtering the intended
lines.

Minor thinko:

+    -- test output stable. This is necessary because whether text-mode
+    -- buffers output for the planning appears or not varies depending
+    -- on the compile option. It appears if the server is built with
+    -- -DRELCACHE_FORCE_RELEASE -DCATCACHE_FORCE_RELEASE,
+    -- but not otherwise.

those lines begin with a leading tabulation while the rest of the sql file only
contains space indentation.  Other than that it all looks good to me.



Fujii Masao <masao.fujii@oss.nttdata.com> writes:
> On 2020/04/03 12:30, Tom Lane wrote:
>> so probably the thing to do is adapt
>> the filter functions in explain.sql so that they suppress Buffers lines
>> altogether in text output.  Kind of annoying, but ...

> I'm thinking to suppress only Buffers line just after Planning Time line,
> by applying something like the following changes to explain_filter().
> Thought?

I think this is a bad idea.  It's overcomplicated, and more to the
point: now that we've seen the problem we should realize that we're
eventually going to have failures for *any* Buffers line in text-mode
output.  We're already filtering them so hard as to be nearly useless
(see a couple lines further down).  I think we should just drop them
in text mode and be content with checking for them in non-text modes.

Robert's muttered about possibly introducing some EXPLAIN option
that would make the output a bit less variable.  Perhaps we should
do that.  I'm not quite sure I like the idea on theoretical grounds:
testing a different behavior from what you do in production seems
like the wrong thing.  But it'd allow undoing decisions like this one.
It's too late to consider such a thing for v13, though --- four days
before feature freeze is no time to be designing new features.
So for now, we have to make the output stable with the tools we have,
and text-mode Buffers output is unstable by design.

            regards, tom lane



Re: pgsql: Include information on buffer usage during planning phase,in EX

From
Fujii Masao
Date:

On 2020/04/03 22:35, Tom Lane wrote:
> Fujii Masao <masao.fujii@oss.nttdata.com> writes:
>> On 2020/04/03 12:30, Tom Lane wrote:
>>> so probably the thing to do is adapt
>>> the filter functions in explain.sql so that they suppress Buffers lines
>>> altogether in text output.  Kind of annoying, but ...
> 
>> I'm thinking to suppress only Buffers line just after Planning Time line,
>> by applying something like the following changes to explain_filter().
>> Thought?
> 
> I think this is a bad idea.  It's overcomplicated, and more to the
> point: now that we've seen the problem we should realize that we're
> eventually going to have failures for *any* Buffers line in text-mode
> output.  We're already filtering them so hard as to be nearly useless
> (see a couple lines further down).  I think we should just drop them
> in text mode and be content with checking for them in non-text modes.

Yeah, I'm fine with the idea. The regression test for EXPLAIN has
the following four similar tests. The first one fails in regression test
because of buffers output for the planning. Your idea seems to be
equal to removal of this first test. Because there are already
the same tests with other format. Is my understanding right?

select explain_filter('explain (analyze, buffers, format text) select * from int8_tbl i8');
select explain_filter('explain (analyze, buffers, format json) select * from int8_tbl i8');
select explain_filter('explain (analyze, buffers, format xml) select * from int8_tbl i8');
select explain_filter('explain (analyze, buffers, format yaml) select * from int8_tbl i8');

Or another idea is to specify "summary off" in the above first
EXPLAIN command, to suppress the summary output including
the buffers output for the planning. This seems simple and enough.
Thought?

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION



Fujii Masao <masao.fujii@oss.nttdata.com> writes:
> On 2020/04/03 22:35, Tom Lane wrote:
>> I think this is a bad idea.  It's overcomplicated, and more to the
>> point: now that we've seen the problem we should realize that we're
>> eventually going to have failures for *any* Buffers line in text-mode
>> output.  We're already filtering them so hard as to be nearly useless
>> (see a couple lines further down).  I think we should just drop them
>> in text mode and be content with checking for them in non-text modes.

> Yeah, I'm fine with the idea. The regression test for EXPLAIN has
> the following four similar tests. The first one fails in regression test
> because of buffers output for the planning. Your idea seems to be
> equal to removal of this first test. Because there are already
> the same tests with other format. Is my understanding right?

Well, there are at least three ways you could interpret my suggestion:

* don't do the test with format = text at all

* do it, but remove the buffers option

* keep test the same, make explain_filter() drop Buffers lines

But I had the last one in mind.  Even if we can't *see* the output,
there is some value in making the backend run through the code ---
it'd at least catch core-dumping bugs there.

> Or another idea is to specify "summary off" in the above first
> EXPLAIN command, to suppress the summary output including
> the buffers output for the planning. This seems simple and enough.

That's still assuming that only the summary Buffers line is problematic,
which I think is wrong.  Keep in mind that the explain.sql test is
barely two months old; it has never seen the field, and there is no
good reason to trust that it's rock solid stable.  Now that we've
seen this failure, I'm quite afraid that the existing test case

 Seq Scan on int8_tbl i8  (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
   Buffers: shared [read]
 Planning Time: N.N ms

can be made to fall over, eg by running with high enough shared_buffers.

            regards, tom lane



Re: pgsql: Include information on buffer usage during planning phase,in EX

From
Fujii Masao
Date:

On 2020/04/03 23:55, Tom Lane wrote:
> Fujii Masao <masao.fujii@oss.nttdata.com> writes:
>> On 2020/04/03 22:35, Tom Lane wrote:
>>> I think this is a bad idea.  It's overcomplicated, and more to the
>>> point: now that we've seen the problem we should realize that we're
>>> eventually going to have failures for *any* Buffers line in text-mode
>>> output.  We're already filtering them so hard as to be nearly useless
>>> (see a couple lines further down).  I think we should just drop them
>>> in text mode and be content with checking for them in non-text modes.
> 
>> Yeah, I'm fine with the idea. The regression test for EXPLAIN has
>> the following four similar tests. The first one fails in regression test
>> because of buffers output for the planning. Your idea seems to be
>> equal to removal of this first test. Because there are already
>> the same tests with other format. Is my understanding right?
> 
> Well, there are at least three ways you could interpret my suggestion:
> 
> * don't do the test with format = text at all
> 
> * do it, but remove the buffers option
> 
> * keep test the same, make explain_filter() drop Buffers lines
> 
> But I had the last one in mind.  Even if we can't *see* the output,
> there is some value in making the backend run through the code ---
> it'd at least catch core-dumping bugs there.

Yes, this makes sense. Thanks for clarifying that!

>> Or another idea is to specify "summary off" in the above first
>> EXPLAIN command, to suppress the summary output including
>> the buffers output for the planning. This seems simple and enough.
> 
> That's still assuming that only the summary Buffers line is problematic,
> which I think is wrong.  Keep in mind that the explain.sql test is
> barely two months old; it has never seen the field, and there is no
> good reason to trust that it's rock solid stable.  Now that we've
> seen this failure, I'm quite afraid that the existing test case
> 
>   Seq Scan on int8_tbl i8  (cost=N.N..N.N rows=N width=N) (actual time=N.N..N.N rows=N loops=N)
>     Buffers: shared [read]
>   Planning Time: N.N ms
> 
> can be made to fall over, eg by running with high enough shared_buffers.

Yeah, so I'm feeling that it's better to firstly make the explain test
more stable, separately from the patch for the planning buffers output.
Attached is the patch that changes explain.c as follows (i.e., removes
Buffers lines at all) to make it more stable.

          ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
          -- In sort output, the above won't match units-suffixed numbers
          ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g');
-        -- Text-mode buffers output varies depending on the system state
-        ln := regexp_replace(ln, '^( +Buffers: shared)( hit=N)?( read=N)?', '\1 [read]');
+        -- Ignore text-mode buffers output because it varies depending
+        -- on the system state
+        CONTINUE WHEN (ln ~ ' +Buffers: .*');
          return next ln;
      end loop;
  end;

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION

Attachment
Fujii Masao <masao.fujii@oss.nttdata.com> writes:
> Attached is the patch that changes explain.c as follows (i.e., removes
> Buffers lines at all) to make it more stable.

>           ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
>           -- In sort output, the above won't match units-suffixed numbers
>           ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g');
> -        -- Text-mode buffers output varies depending on the system state
> -        ln := regexp_replace(ln, '^( +Buffers: shared)( hit=N)?( read=N)?', '\1 [read]');
> +        -- Ignore text-mode buffers output because it varies depending
> +        -- on the system state
> +        CONTINUE WHEN (ln ~ ' +Buffers: .*');
>           return next ln;
>       end loop;
>   end;

Works for me.

            regards, tom lane



Re: pgsql: Include information on buffer usage during planning phase,in EX

From
Fujii Masao
Date:

On 2020/04/04 0:34, Tom Lane wrote:
> Fujii Masao <masao.fujii@oss.nttdata.com> writes:
>> Attached is the patch that changes explain.c as follows (i.e., removes
>> Buffers lines at all) to make it more stable.
> 
>>            ln := regexp_replace(ln, '\m\d+\M', 'N', 'g');
>>            -- In sort output, the above won't match units-suffixed numbers
>>            ln := regexp_replace(ln, '\m\d+kB', 'NkB', 'g');
>> -        -- Text-mode buffers output varies depending on the system state
>> -        ln := regexp_replace(ln, '^( +Buffers: shared)( hit=N)?( read=N)?', '\1 [read]');
>> +        -- Ignore text-mode buffers output because it varies depending
>> +        -- on the system state
>> +        CONTINUE WHEN (ln ~ ' +Buffers: .*');
>>            return next ln;
>>        end loop;
>>    end;
> 
> Works for me.

Many thanks! Pushed.

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION



Fujii Masao <masao.fujii@oss.nttdata.com> writes:
> Many thanks! Pushed.

Looks like you didn't un-revert the main patch?

            regards, tom lane



Re: pgsql: Include information on buffer usage during planning phase,in EX

From
Fujii Masao
Date:

On 2020/04/04 2:46, Tom Lane wrote:
> Fujii Masao <masao.fujii@oss.nttdata.com> writes:
>> Many thanks! Pushed.
> 
> Looks like you didn't un-revert the main patch?

Right now, pushed! I was waiting for my test to finish
without errors before commit. Anyway thanks!

Regards,

-- 
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION



Re: pgsql: Include information on buffer usage during planning phase,in EX

From
Julien Rouhaud
Date:
On Fri, Apr 3, 2020 at 8:16 PM Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
>
> On 2020/04/04 2:46, Tom Lane wrote:
> > Fujii Masao <masao.fujii@oss.nttdata.com> writes:
> >> Many thanks! Pushed.
> >
> > Looks like you didn't un-revert the main patch?
>
> Right now, pushed! I was waiting for my test to finish
> without errors before commit. Anyway thanks!

Thanks a lot!