On Wed, Jun 8, 2022 at 2:23 PM Robert Haas <robertmh...@gmail.com> wrote: > In my tests, PageGetPageSize(page) = 8192, SizeOfPageHeaderData = 24, > sizeof(ItemIdData) = 4, sizeof(ItemPointerData) = 6, and > sizeof(BTPageOpaqueData) = 16. Assuming MAXIMUM_ALIGNOF == 8, I > believe that makes BTMaxItemSize come out to 2704 and > BTMaxItemSizeNoHeapTid come out to 2712.
I agree that these numbers are what you get on all mainstream platforms. I know these specifics from memory alone, actually. > To see why, suppose that sizeof(BTPageOpaqueData) were 24 rather than > 16. Then we'd have: > > BTMaxItemSize = MAXALIGN_DOWN((8192 - MAXALIGN(24 + 3 * 4 + 3 * 6) - > MAXALIGN(24)) / 3) = MAXALIGN_DOWN((8192 - MAXALIGN(54) - 24) / 3) = > MAXALIGN_DOWN(2704) = 2704 > BTMaxItemSizeNoHeapTid = MAXALIGN_DOWN((8192 - MAXALIGN(24 + 3 * 4) - > MAXALIGN(24)) / 3 = MAXALIGN_DOWN((8192 - MAXALIGN(36) - 24) / 3) = > MAXALIGN_DOWN(2709) = 2704 > > That's a problem, because if in that scenario you allow three 2704 > byte items that don't need a heap TID and later you find you need to > add a heap TID to one of those items, the result will be bigger than > 2704 bytes, and then you can't fit three of them into a page. Seems you must be right. I'm guessing that the field "cabbage" was originally a nonce value, as part of a draft patch you're working on? I actually tested this in a fairly brute force fashion back when I was working on the Postgres 12 nbtree stuff. Essentially I found a way to build the tallest possible B-Tree, consisting of only 3 items (plus a high key) on each leaf page, each of which was the largest possible size, up to the byte. If memory serves, it is just about impossible to get beyond 7 levels. It took as long as 30 minutes or more to run the test. I think that we should fix this on HEAD, on general principle. There is no reason to believe that this is a live bug, so a backpatch seems unnecessary. -- Peter Geoghegan