On Fri, May 28, 2021, at 7:22 AM, Tom Lane wrote:
> The text column would cause the table to have an associated toast table [1],
> which in turn would have an index.  Both of those would be reallocated as
> new files on-disk during TRUNCATE, just like the table proper.
> 
> A plausible theory here is that TRUNCATE leaks some storage associated
> with an index's relcache entry, but not any for a plain table.
> 
>                       regards, tom lane
> 
> [1] https://www.postgresql.org/docs/current/storage-toast.html

Yeah, I forgot to mention this originally, but I see memory growth against a 
"varchar(501)" field, but *not* against a "varchar(500)" field, so I was 
wondering if there was some length threshold that triggered something with 
toast table behavior somehow involved. But if the toast table involves an 
index, then maybe all of this gets back to just the indexes like you say.

And I originally thought this issue was limited to temp tables, but now I'm not 
so sure. I seem to be able to reproduce the memory growth against regular 
tables (both normal and UNLOGGED) too:

DO $$
  DECLARE
    i bigint;
  BEGIN
    CREATE TABLE public.foo (id integer, bar text);

    FOR i IN 1..200000000 LOOP
      TRUNCATE public.foo;
    END LOOP;
  END
$$

The memory growth seems to be slower in this case, so maybe that's why I didn't 
catch it earlier, but I think it's maybe growing at the same rate, it's just 
that this loop goes slower against real tables than temp tables. For example, I 
see similar total memory growth by the time this reaches 100,000 loops for 
either temp or non-temp tables, the temp version just reaches that point a lot 
more quickly (which makes sense).

Thanks!
Nick


Reply via email to