page macros cleanup

Started by Zdenek Kotalaabout 18 years ago26 messagespatches
Jump to latest
#1Zdenek Kotala
Zdenek.Kotala@Sun.COM

I attached code cleanup which is related to in-place upgrade. I replace direct
access to PageHeader structure with already existing macros and I removed also
unnecessary retyping. There still lot of places which directly access to
PageHeader structure which require new macros/fuction in page API. I will fix it
in next patch.

Zdenek

Attachments:

page.patchtext/x-patch; name=page.patchDownload+151-151
#2Pavan Deolasee
pavan.deolasee@gmail.com
In reply to: Zdenek Kotala (#1)
Re: page macros cleanup

On Fri, Jun 13, 2008 at 9:38 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:

I attached code cleanup which is related to in-place upgrade. I replace
direct access to PageHeader structure with already existing macros and I
removed also unnecessary retyping.

A quick review comment:

One thing I noticed is that the modified definition of HashMaxItemSize
now does not account for the size of ItemId which may not be the right
thing. Please recheck that.

Apart from that the patch looks good to me. As you said, we should
probably replace the other direct usage of PageHeader with appropriate
macros.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

#3Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Zdenek Kotala (#1)
Re: page macros cleanup

Just one quick note:

Zdenek Kotala wrote:

*** pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c	pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/gist/gistutil.c	pá črn 13 18:00:35 2008
***************
*** 592,598 ****
/*
* Additionally check that the special area looks sane.
*/
! 	if (((PageHeader) (page))->pd_special !=
(BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
--- 592,598 ----
/*
* Additionally check that the special area looks sane.
*/
! 	if ( PageGetSpecialPointer(page) - page !=
(BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),

Should probably use PageGetSpecialSize here. Much simpler, and doesn't
assume that the special area is always at the end of page (not that I
see us changing that anytime soon).

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#4Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Pavan Deolasee (#2)
Re: page macros cleanup

Pavan Deolasee napsal(a):

On Fri, Jun 13, 2008 at 9:38 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:

I attached code cleanup which is related to in-place upgrade. I replace
direct access to PageHeader structure with already existing macros and I
removed also unnecessary retyping.

A quick review comment:

Thanks you for your review,

One thing I noticed is that the modified definition of HashMaxItemSize
now does not account for the size of ItemId which may not be the right
thing. Please recheck that.

Good catch. I lost in basic arithmetic. What I see now that original definition
count sizeof(ItemIdData) twice and on other side it does not take care about
MAXALING correctly. I think correct formula is:

#define HashMaxItemSize(page) \
(PageGetPageSize(page) - \
( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))+ \
MAXALIGN(sizeof(HashPageOpaqueData)) \
)\
)

What do you think?

Thanks for your comments Zdenek

--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

#5Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Heikki Linnakangas (#3)
Re: page macros cleanup

Heikki Linnakangas napsal(a):

Just one quick note:

Should probably use PageGetSpecialSize here. Much simpler, and doesn't
assume that the special area is always at the end of page (not that I
see us changing that anytime soon).

Thanks for review,
good catch. I found similar example also in nbtree and hash. I attached updated
patch version which also contains fix for Pavan's observation. Patch modifies
HashMaxItemSize. It should require reindex on all hash indexes. Should we bump
catalog version?

thanks Zdenek

--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

Attachments:

page_02.patchtext/x-patch; name=page_02.patchDownload+154-154
#6Pavan Deolasee
pavan.deolasee@gmail.com
In reply to: Zdenek Kotala (#4)
Re: page macros cleanup

On Fri, Jul 4, 2008 at 1:01 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:

Good catch. I lost in basic arithmetic. What I see now that original
definition count sizeof(ItemIdData) twice and on other side it does not take
care about MAXALING correctly. I think correct formula is:

#define HashMaxItemSize(page) \
(PageGetPageSize(page) - \
( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))+ \
MAXALIGN(sizeof(HashPageOpaqueData)) \
)\
)

What do you think?

Yes. I think that's the correct way.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

#7Pavan Deolasee
pavan.deolasee@gmail.com
In reply to: Zdenek Kotala (#5)
Re: page macros cleanup

On Fri, Jul 4, 2008 at 2:08 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:

Patch
modifies HashMaxItemSize. It should require reindex on all hash indexes.
Should we bump catalog version?

Do we really need that ? Even if the new HashMaxItemSize comes out to
be lower than the current limit (because of MAXALIGN), I don't see how
existing hash indexes can have a larger item than the new limit.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

#8Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Pavan Deolasee (#7)
Re: page macros cleanup (ver 03)

Pavan Deolasee napsal(a):

On Fri, Jul 4, 2008 at 2:08 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:

Patch
modifies HashMaxItemSize. It should require reindex on all hash indexes.
Should we bump catalog version?

Do we really need that ? Even if the new HashMaxItemSize comes out to
be lower than the current limit (because of MAXALIGN), I don't see how
existing hash indexes can have a larger item than the new limit.

Yeah, I performed calculation and situation is following (for MAXALIGN 4 and 8):

4 8
Orig 8144 8144
New 8148 8144

It should be OK for all cases.

I fixed also one typo (ItemId -> ItemIdData) and new revision is attached.

Zdenek

--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

Attachments:

page_03.patchtext/x-patch; name=page_03.patchDownload+154-154
#9Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Pavan Deolasee (#6)
Re: page macros cleanup

Pavan Deolasee wrote:

On Fri, Jul 4, 2008 at 1:01 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:

Good catch. I lost in basic arithmetic. What I see now that original
definition count sizeof(ItemIdData) twice and on other side it does not take
care about MAXALING correctly. I think correct formula is:

#define HashMaxItemSize(page) \
(PageGetPageSize(page) - \
( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))+ \
MAXALIGN(sizeof(HashPageOpaqueData)) \
)\
)

What do you think?

Yes. I think that's the correct way.

Doesn't look right to me. There's no padding after the first line
pointer, hence the first MAXALIGN shouldn't be there.

BTW, looking at hashinsert.c where it's used, we're actually passing a
pointer to the meta page to HashMaxItemSize(). So the PageGetPageSize()
call on that is quite bogus, since it's not the meta page that the tuple
is going to be inserted to. It's academical, because all pages are the
same size anyway, but doesn't look right. I think I'd go with BLKCSZ
instead.

I think this is the way it should be:

#define HashMaxItemSize \
(BLCKSZ - \
SizeOfPageHeaderData - \
MAXALIGN(sizeof(HashPageOpaqueData)) - \
sizeof(ItemIdData))

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#10Pavan Deolasee
pavan.deolasee@gmail.com
In reply to: Heikki Linnakangas (#9)
Re: page macros cleanup

On Fri, Jul 4, 2008 at 3:37 PM, Heikki Linnakangas
<heikki@enterprisedb.com> wrote:

I think this is the way it should be:

#define HashMaxItemSize \
(BLCKSZ - \
SizeOfPageHeaderData - \
MAXALIGN(sizeof(HashPageOpaqueData)) - \
sizeof(ItemIdData))

I am wondering if this would fail for corner case if HashMaxItemSize
happened to be unaligned. For example, if (itemsz < HashMaxItemSize <
MAXALIGN(itemsz), PageAddItem() would later fail with a not-so-obvious
error. Should we just MAXALIGN_DOWN the HashMaxItemSize ?

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

#11Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Heikki Linnakangas (#9)
Re: page macros cleanup

Heikki Linnakangas napsal(a):

Pavan Deolasee wrote:

On Fri, Jul 4, 2008 at 1:01 PM, Zdenek Kotala <Zdenek.Kotala@sun.com>
wrote:

Good catch. I lost in basic arithmetic. What I see now that original
definition count sizeof(ItemIdData) twice and on other side it does
not take
care about MAXALING correctly. I think correct formula is:

#define HashMaxItemSize(page) \
(PageGetPageSize(page) - \
( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))+ \
MAXALIGN(sizeof(HashPageOpaqueData)) \
)\
)

What do you think?

Yes. I think that's the correct way.

Doesn't look right to me. There's no padding after the first line
pointer, hence the first MAXALIGN shouldn't be there.

Are you sure? I expecting that tupleheader must be aligned to MAXALIGN. If it is
not required than you are right.

Look on PageAddItem:

00226 alignedSize = MAXALIGN(size);
00227
00228 upper = (int) phdr->pd_upper - (int) alignedSize;

By my opinion first place where tuple should be placed is:

MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))

BTW, looking at hashinsert.c where it's used, we're actually passing a
pointer to the meta page to HashMaxItemSize(). So the PageGetPageSize()
call on that is quite bogus, since it's not the meta page that the tuple
is going to be inserted to. It's academical, because all pages are the
same size anyway, but doesn't look right. I think I'd go with BLKCSZ
instead.

Yeah, BLKCSZ looks good. Anyway, I plan to reorganize all *MaxItemSize staff to
be compatible with in-place upgrade.

thanks Zdenek

--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

#12Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Pavan Deolasee (#10)
Re: page macros cleanup

Pavan Deolasee wrote:

On Fri, Jul 4, 2008 at 3:37 PM, Heikki Linnakangas
<heikki@enterprisedb.com> wrote:

I think this is the way it should be:

#define HashMaxItemSize \
(BLCKSZ - \
SizeOfPageHeaderData - \
MAXALIGN(sizeof(HashPageOpaqueData)) - \
sizeof(ItemIdData))

I am wondering if this would fail for corner case if HashMaxItemSize
happened to be unaligned. For example, if (itemsz < HashMaxItemSize <
MAXALIGN(itemsz), PageAddItem() would later fail with a not-so-obvious
error. Should we just MAXALIGN_DOWN the HashMaxItemSize ?

No, there's a itemsz = MAXALIGN(itemsz) call before the check against
HashMaxItemSize.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#13Pavan Deolasee
pavan.deolasee@gmail.com
In reply to: Heikki Linnakangas (#12)
Re: page macros cleanup

On Fri, Jul 4, 2008 at 4:25 PM, Heikki Linnakangas
<heikki@enterprisedb.com> wrote:

No, there's a itemsz = MAXALIGN(itemsz) call before the check against
HashMaxItemSize.

Ah, right. Still should we just not MAXALIGN_DOWN the Max size to
reflect the practical limit on the itemsz ? It's more academical
though, so not a big deal.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

#14Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Heikki Linnakangas (#12)
Re: page macros cleanup

Heikki Linnakangas napsal(a):

Pavan Deolasee wrote:

On Fri, Jul 4, 2008 at 3:37 PM, Heikki Linnakangas
<heikki@enterprisedb.com> wrote:

I think this is the way it should be:

#define HashMaxItemSize \
(BLCKSZ - \
SizeOfPageHeaderData - \
MAXALIGN(sizeof(HashPageOpaqueData)) - \
sizeof(ItemIdData))

I am wondering if this would fail for corner case if HashMaxItemSize
happened to be unaligned. For example, if (itemsz < HashMaxItemSize <
MAXALIGN(itemsz), PageAddItem() would later fail with a not-so-obvious
error. Should we just MAXALIGN_DOWN the HashMaxItemSize ?

No, there's a itemsz = MAXALIGN(itemsz) call before the check against
HashMaxItemSize.

It is tru, but id somebody will use HashMaxItemSize in different place in the
future he could omit to use same approach. See tuptoaster.h how TOAST_MAX_CHUNK
is defined or BTMaxItemSize in nbtree.h.

Pavan's comments is correct. It should give same result as my implementation
(because BLCKSZ is aligned), but it is better readable and consistent with other.

Zdenek

--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

#15Pavan Deolasee
pavan.deolasee@gmail.com
In reply to: Zdenek Kotala (#11)
Re: page macros cleanup

On Fri, Jul 4, 2008 at 4:20 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:

By my opinion first place where tuple should be placed is:

MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))

Tuple actually starts from the other end of the block.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

#16Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Pavan Deolasee (#15)
Re: page macros cleanup

Pavan Deolasee napsal(a):

On Fri, Jul 4, 2008 at 4:20 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:

By my opinion first place where tuple should be placed is:

MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))

Tuple actually starts from the other end of the block.

Yes, but I meant first from offset point of view which is opposite to insert order.

Zdenek

--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

#17Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Zdenek Kotala (#11)
Re: page macros cleanup

Zdenek Kotala wrote:

By my opinion first place where tuple should be placed is:

MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))

Yeah, but we don't enforce that directly. We enforce it by MAXALIGNing
size in PageAddItem, and with the rule that special-size is MAXALIGNed.

To put it another way, it's possible that there's an unaligned amount of
free space on a page, as returned by PageGetExactFreeSpace. But since
item size is always MAXALIGNed, it's impossible to use it all.

Come to think of it, why do we require MAXALIGN alignment of tuples? I
must be missing something, but AFAICS the widest fields in
HeapTupleHeaderData are 4-bytes wide, so it should be possible to get
away with 4-byte alignment.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#18Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Heikki Linnakangas (#17)
Re: page macros cleanup

Heikki Linnakangas napsal(a):

Zdenek Kotala wrote:

By my opinion first place where tuple should be placed is:

MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))

Yeah, but we don't enforce that directly. We enforce it by MAXALIGNing
size in PageAddItem, and with the rule that special-size is MAXALIGNed.

Yeah, it is implication from other rules. But how Pavan mentioned and I agree
with him. We should have *MaxItemSize value maxaligned, because tuple is
maxaligned anyway and *MaxItemSize defines real limit.

Come to think of it, why do we require MAXALIGN alignment of tuples? I
must be missing something, but AFAICS the widest fields in
HeapTupleHeaderData are 4-bytes wide, so it should be possible to get
away with 4-byte alignment.

I think that you have problem to make correct decision about padding between
header and first data item on platform where MAXALIGN is 8. Padding will depends
on align of offset - if it is max aligned or not. It will have effect for
example on SPARC but it adds extra complexity to code. ... Maybe only set hoff
correctly when new tuple is created ...

Another improvement should be reorder column to got best space allocation during
create table (of course it affect select * from).

Zdenek

--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

#19Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Pavan Deolasee (#13)
Re: page macros cleanup (ver 04)

Pavan Deolasee napsal(a):

On Fri, Jul 4, 2008 at 4:25 PM, Heikki Linnakangas
<heikki@enterprisedb.com> wrote:

No, there's a itemsz = MAXALIGN(itemsz) call before the check against
HashMaxItemSize.

Ah, right. Still should we just not MAXALIGN_DOWN the Max size to
reflect the practical limit on the itemsz ? It's more academical
though, so not a big deal.

Finally I use following formula:

#define HashMaxItemSize(page) \
MAXALIGN_DOWN(PageGetPageSize(page) - \
( SizeOfPageHeaderData + sizeof(ItemIdData) ) - \
MAXALIGN(sizeof(HashPageOpaqueData)) )

I did not replace PageGetPageSize(page), because other *MaxItemSize has same
interface.

Revised patch is attached.

Zdenek

--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

Attachments:

page_04.patchtext/x-patch; name=page_04.patchDownload+156-156
#20Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Zdenek Kotala (#19)
Re: page macros cleanup (ver 04)

Pavan, Heikki,

Is it OK now or do you have any comments?

Thanks Zdenek

Zdenek Kotala napsal(a):

Show quoted text

Pavan Deolasee napsal(a):

On Fri, Jul 4, 2008 at 4:25 PM, Heikki Linnakangas
<heikki@enterprisedb.com> wrote:

No, there's a itemsz = MAXALIGN(itemsz) call before the check against
HashMaxItemSize.

Ah, right. Still should we just not MAXALIGN_DOWN the Max size to
reflect the practical limit on the itemsz ? It's more academical
though, so not a big deal.

Finally I use following formula:

#define HashMaxItemSize(page) \
MAXALIGN_DOWN(PageGetPageSize(page) - \
( SizeOfPageHeaderData + sizeof(ItemIdData) ) - \
MAXALIGN(sizeof(HashPageOpaqueData)) )

I did not replace PageGetPageSize(page), because other *MaxItemSize has
same interface.

Revised patch is attached.

Zdenek

------------------------------------------------------------------------

#21Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Zdenek Kotala (#19)
#22Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Heikki Linnakangas (#21)
#23Tom Lane
tgl@sss.pgh.pa.us
In reply to: Zdenek Kotala (#22)
#24Tom Lane
tgl@sss.pgh.pa.us
In reply to: Heikki Linnakangas (#21)
#25Zdenek Kotala
Zdenek.Kotala@Sun.COM
In reply to: Tom Lane (#24)
#26Tom Lane
tgl@sss.pgh.pa.us
In reply to: Zdenek Kotala (#25)