Re: [HACKERS] Error "vacuum pg_proc"

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Mateus Cordeiro Inssa <mateus(at)ifnet(dot)com(dot)br>
Cc: pgsql-hackers(at)postgreSQL(dot)org
Subject: Re: [HACKERS] Error "vacuum pg_proc"
Date: 1999-12-26 21:20:49
Message-ID: 23238.946243249@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I wrote:
> Mateus Cordeiro Inssa <mateus(at)ifnet(dot)com(dot)br> writes:
>> I got this error vacuuming pg_proc:
>> ERROR: _bt_endpoint: leftmost page (20) has not leftmost flag

> Hmm, I wonder if this could be yet another manifestation of the problems
> that btree indexes have with oversized key values. Do you have any
> procedures with long definitions? "Long" in this context means over
> about 4K.

I spent some more time looking into this, and found out that actually
the safe upper limit for btree index entries is not ~ BLCKSZ/2, but
~ BLCKSZ/3. btree needs to be able to insert two items on every page,
but it *also* keeps an extra item (the "high key") on non-rightmost
pages. So if any item exceeds one-third the available space, you run
a risk of failure depending on what page it ends up on and what else
is on that same page.

It turns out that for an index on a single text column, the maximum
safe text length is 2700 bytes. So the correct check for dangerous
procedure definitions in 6.5.* is

select proname from pg_proc where length(prosrc) > 2700;

I have committed a check for dangerously long index entries into both
current sources and REL6_5 branch. The patch is attached if you want to
add it to your installation right away. Note that this only defends
against oversize new entries; if you've already got oversize index
entries, you still have trouble waiting to happen...

regards, tom lane

*** src/backend/access/nbtree/nbtinsert.c.orig Wed Sep 1 13:54:00 1999
--- src/backend/access/nbtree/nbtinsert.c Sun Dec 26 15:44:15 1999
***************
*** 268,273 ****
--- 268,285 ----
* consistent */

/*
+ * Check whether the item can fit on a btree page at all.
+ * (Eventually, we ought to try to apply TOAST methods if not.)
+ * We actually need to be able to fit three items on every page,
+ * so restrict any one item to 1/3 the per-page available space.
+ * Note that at this point, itemsz doesn't include the ItemId.
+ */
+ if (itemsz > (PageGetPageSize(page)-sizeof(PageHeaderData)-MAXALIGN(sizeof(BTPageOpaqueData)))/3 - sizeof(ItemIdData))
+ elog(ERROR, "btree: index item size %d exceeds maximum %d",
+ itemsz,
+ (PageGetPageSize(page)-sizeof(PageHeaderData)-MAXALIGN(sizeof(BTPageOpaqueData)))/3 - sizeof(ItemIdData));
+
+ /*
* If we have to insert item on the leftmost page which is the first
* page in the chain of duplicates then: 1. if scankey == hikey (i.e.
* - new duplicate item) then insert it here; 2. if scankey < hikey

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Ryan Kirkpatrick 1999-12-27 01:05:02 Re: [HACKERS] database replication
Previous Message Ansley, Michael 1999-12-26 21:04:34 Unlimited query length - The final chapter (part II)