Re: 8.3.0: vacuum full analyze: "invalid memory alloc request size"

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Tomas Szepe <szepe(at)pinerecords(dot)com>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: 8.3.0: vacuum full analyze: "invalid memory alloc request size"
Date: 2008-02-10 18:34:48
Message-ID: 17704.1202668488@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Tomas Szepe <szepe(at)pinerecords(dot)com> writes:
>> Do you perhaps have a ridiculously low fillfactor attached to
>> the system catalogs?

> I don't know - how do I tell?

If you did, you'd know it --- that's not something that would happen
without your trying to do it.

After poking around in the code a bit, I found a way to reproduce the
assert failure:

regression=# create table foo as select null::int as x from generate_series(1,2000) x;
SELECT
regression=# delete from foo;
DELETE 2000
regression=# select count(*) from foo;
count
-------
0
(1 row)

regression=# vacuum full foo;
server closed the connection unexpectedly

What is happening here is that after the SELECT, we have pages
containing MaxHeapTuplesPerPage DEAD line pointers (and nothing else).
PageGetHeapFreeSpace is designed to return zero in this situation,
so PageGetFreeSpaceWithFillFactor does too, which means we end up with
do_frag = false and notup = true, which is not a combination that the
empty_end_pages logic is prepared for.

While it would clearly be a good idea to defend against that
combination, I think the real problem here is that we are blindly
applying PageGetHeapFreeSpace in a context where it's inappropriate.
Those DEAD line pointers are going to get recycled and so there is
no need to prevent VACUUM FULL from trying to put more tuples on
the page. OTOH, if we don't do it this way we'd probably need to
put explicit checks for too-many-line-pointers somewhere else in
VACUUM FULL.

Another issue is that while I can create a page with
MaxHeapTuplesPerPage dead tuples easily enough in testing, it's not
clear how you managed to get into that state in the system catalogs.
Neither pg_class nor pg_attribute can have minimal-length tuples.
Are you doing anything that would involve lots of updates in these
catalogs --- maybe repeatedly renaming a column, or something like that?

regards, tom lane

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message vha 2008-02-10 18:55:18 BUG #3951: SELECT ... WHERE Param = ? does not work if Param is of type bytea
Previous Message Dave Page 2008-02-10 17:50:30 Re: BUG #3947: Unable to Initialize Data Cluster