Thread: Release SPI plans for referential integrity with DISCARD ALL

Release SPI plans for referential integrity with DISCARD ALL

From
yuzuko
Date:
Hello,

We found problem that a huge amount of memory was consumed when
we created a foreign key on a partitioned table including a lots partitions
and accessed them, as discussed in [1].  Kuroda-san's idea proposed in
this thread is reducing cached SPI plans by combining several plans into one.
But we are also considering another option to solve this problem, which
makes users to release cached SPI plans for referential integrity as well as
plain cached plans with DISCARD ALL.  To do that, we added a new
function, RI_DropAllPreparedPlan() which deletes all plans from
ri_query_cache and
modified DISCARD ALL to execute that function.

I tested using a test case yamada-san attached in [2] as follows:
[Before DISCARD ALL]
=# SELECT name, sum(used_bytes) as bytes,
pg_size_pretty(sum(used_bytes)) FROM pg_backend_memory_contexts WHERE
name LIKE 'Cached%' GROUP BY name;
       name       |   bytes   | pg_size_pretty
------------------+-----------+----------------
 CachedPlanQuery  |   1326280 | 1295 kB
 CachedPlanSource |   1474616 | 1440 kB
 CachedPlan       | 744009168 | 710 MB
(3 rows)

[After DISCARD ALL]
=# DISCARD ALL;
DISCARD ALL

=# SELECT name, sum(used_bytes) as bytes,
pg_size_pretty(sum(used_bytes)) FROM pg_backend_memory_contexts WHERE
name LIKE 'Cached%' GROUP BY name;
       name       | bytes | pg_size_pretty
------------------+-------+----------------
 CachedPlanQuery  | 10280 | 10 kB
 CachedPlanSource | 14616 | 14 kB
 CachedPlan       | 13168 | 13 kB
(3 rows)

In addition to that, a following case would be solved with this approach:
When many processes are referencing many tables defined foreign key
constraints thoroughly, a huge amount of memory will be consumed
regardless of whether referenced tables are partitioned or not.

Attached the patch.  Any thoughts?


[1] https://www.postgresql.org/message-id/flat/cab4b85d-9292-967d-adf2-be0d803c3e23%40nttcom.co.jp_1
[2]https://www.postgresql.org/message-id/cab4b85d-9292-967d-adf2-be0d803c3e23%40nttcom.co.jp_1

--
Best regards,
Yuzuko Hosoya
NTT Open Source Software Center

Attachment

Re: Release SPI plans for referential integrity with DISCARD ALL

From
Corey Huinker
Date:
In addition to that, a following case would be solved with this approach:
When many processes are referencing many tables defined foreign key
constraints thoroughly, a huge amount of memory will be consumed
regardless of whether referenced tables are partitioned or not.

Attached the patch.  Any thoughts?

Amit Langote has done some great work at eliminating SPI from INSERT/UPDATE triggers entirely, thus reducing the number of cached plans considerably.

I think he was hoping to have a patch formalized this week, if time allowed.

It doesn't have DELETE triggers in it, so this patch might still have good value for deletes on a commonly used enumeration table.

However, our efforts might be better focused on eliminating SPI from delete triggers as well, an admittedly harder task.

Re: Release SPI plans for referential integrity with DISCARD ALL

From
Corey Huinker
Date:
On Wed, Jan 13, 2021 at 1:03 PM Corey Huinker <corey.huinker@gmail.com> wrote:
In addition to that, a following case would be solved with this approach:
When many processes are referencing many tables defined foreign key
constraints thoroughly, a huge amount of memory will be consumed
regardless of whether referenced tables are partitioned or not.

Attached the patch.  Any thoughts?

Amit Langote has done some great work at eliminating SPI from INSERT/UPDATE triggers entirely, thus reducing the number of cached plans considerably.

I think he was hoping to have a patch formalized this week, if time allowed.

It doesn't have DELETE triggers in it, so this patch might still have good value for deletes on a commonly used enumeration table.

However, our efforts might be better focused on eliminating SPI from delete triggers as well, an admittedly harder task.

Amit's patch is now available in this thread [1]. I'm curious if it has any effect on your memory pressure issue.

Re: Release SPI plans for referential integrity with DISCARD ALL

From
yuzuko
Date:
Hi Corey,

Thank you for sharing.

> Amit's patch is now available in this thread [1]. I'm curious if it has any effect on your memory pressure issue.
>
I just found that thread.  I'll check the patch.

-- 
Best regards,
Yuzuko Hosoya
NTT Open Source Software Center



Re: Release SPI plans for referential integrity with DISCARD ALL

From
Peter Eisentraut
Date:
On 2021-01-13 09:47, yuzuko wrote:
> But we are also considering another option to solve this problem, which
> makes users to release cached SPI plans for referential integrity as well as
> plain cached plans with DISCARD ALL.  To do that, we added a new
> function, RI_DropAllPreparedPlan() which deletes all plans from
> ri_query_cache and
> modified DISCARD ALL to execute that function.

I don't have a comment on the memory management issue, but I think the 
solution of dropping all cached plans as part of DISCARD ALL seems a bit 
too extreme of a solution.  In the context of connection pooling, 
getting a new session with pre-cached plans seems like a good thing, and 
this change could potentially have a performance impact without a 
practical way to opt out.




Re: Release SPI plans for referential integrity with DISCARD ALL

From
yuzuko
Date:
Hello,

Thank you for your comments.
Following Corey's advice, I applied Amit's patches proposed in this
email [1], and confirmed our memory pressure problem was solved.
So dropping cached plan with DISCARD is not necessary anymore.

[1] https://www.postgresql.org/message-id/CA%2BHiwqG1qQuBwApueaUfA855UJ4TiSgFkPF34hQDWx3tOChV5w%40mail.gmail.com

-- 
Best regards,
Yuzuko Hosoya
NTT Open Source Software Center



Re: Release SPI plans for referential integrity with DISCARD ALL

From
vignesh C
Date:
On Wed, Mar 10, 2021 at 1:49 PM yuzuko <yuzukohosoya@gmail.com> wrote:
>
> Hello,
>
> I thought about this suggestion again.
>
> Amit's patch suggested in the thread [1] can eliminate SPI plans from
> INSERT/UPDATE triggers, so our memory pressure issue would be solved.
> But as far as I can see that thread, Amit's patch doesn't cover DELETE case.
> It is not a common case, but there is a risk of pressing memory
> capacity extremely.
> Considering that, this suggestion might still have good value as Corey
> said before.
>
> I improved a patch according to Peter's following comment :
> > but I think the
> > solution of dropping all cached plans as part of DISCARD ALL seems a bit
> > too extreme of a solution.  In the context of connection pooling,
> > getting a new session with pre-cached plans seems like a good thing, and
> > this change could potentially have a performance impact without a
> > practical way to opt out.
>
> In a new patch, I separated discarding SPI Plan caches for RI from DISCARD ALL
> and added a new option "RIPLANS" to DISCARD command to do that.  Also a new
> function, ResetRIPlanCache() which clears SPI plan caches is called by
> DISCARD ALL
> or DISCARD RIPLANS.  The amount of modification is small and this option can be
> removed instantly when it is no longer needed, so I think we can use
> this patch as
> a provisional solution.
>
> Any thoughts?

The patch does not apply on Head anymore, could you rebase and post a
patch. I'm changing the status to "Waiting for Author".

Regards,
Vignesh



Re: Release SPI plans for referential integrity with DISCARD ALL

From
Tom Lane
Date:
yuzuko <yuzukohosoya@gmail.com> writes:
> I improved a patch according to Peter's following comment :

>> but I think the
>> solution of dropping all cached plans as part of DISCARD ALL seems a bit
>> too extreme of a solution.  In the context of connection pooling,
>> getting a new session with pre-cached plans seems like a good thing, and
>> this change could potentially have a performance impact without a
>> practical way to opt out.

> In a new patch, I separated discarding SPI Plan caches for RI from DISCARD ALL
> and added a new option "RIPLANS" to DISCARD command to do that.

I'm not really comfortable with exposing this as a user-visible behavior.
In particular ...

> The amount of modification is small and this option can be
> removed instantly when it is no longer needed, so I think we can use
> this patch as a provisional solution.

... this claim seems like nonsense.  Once there is user-accessible syntax
for something, we basically can't ever take that out, because it'd break
applications that call that command.

It seems like the real problem with the ri_query_cache cache is that
it will grow without limit.  I wonder whether it wouldn't be better
to put some upper bound on it, along with a simple least-recently-used
rule to choose which entry to discard.  (Perhaps the same goes for
ri_constraint_cache and/or ri_compare_cache, although their entry sizes
are smaller.)

            regards, tom lane