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
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c pgsql.orig/src/backend/access/gist/gistutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/gist/gistutil.c pá Ärc 4 10:23:41 2008
***************
*** 592,599 ****
/*
* Additionally check that the special area looks sane.
*/
! if (((PageHeader) (page))->pd_special !=
! (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains corrupted page at block %u",
--- 592,598 ----
/*
* Additionally check that the special area looks sane.
*/
! if ( PageGetSpecialSize(page) != MAXALIGN(sizeof(GISTPageOpaqueData)))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains corrupted page at block %u",
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c pgsql.orig/src/backend/access/hash/hashpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/hash/hashpage.c pá Ärc 4 10:23:41 2008
***************
*** 407,413 ****
for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
{
if ((1 << i) <= (metap->hashm_bsize -
! (MAXALIGN(sizeof(PageHeaderData)) +
MAXALIGN(sizeof(HashPageOpaqueData)))))
break;
}
--- 407,413 ----
for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
{
if ((1 << i) <= (metap->hashm_bsize -
! (MAXALIGN(SizeOfPageHeaderData) +
MAXALIGN(sizeof(HashPageOpaqueData)))))
break;
}
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c pgsql.orig/src/backend/access/hash/hashutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/hash/hashutil.c pá Ärc 4 10:23:41 2008
***************
*** 164,171 ****
/*
* Additionally check that the special area looks sane.
*/
! if (((PageHeader) (page))->pd_special !=
! (BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains corrupted page at block %u",
--- 164,170 ----
/*
* Additionally check that the special area looks sane.
*/
! if ( PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains corrupted page at block %u",
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c pgsql.orig/src/backend/access/heap/heapam.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/heapam.c pá Ärc 4 10:23:41 2008
***************
*** 1342,1348 ****
ItemPointer tid = &(tuple->t_self);
ItemId lp;
Buffer buffer;
! PageHeader dp;
OffsetNumber offnum;
bool valid;
--- 1342,1348 ----
ItemPointer tid = &(tuple->t_self);
ItemId lp;
Buffer buffer;
! Page page;
OffsetNumber offnum;
bool valid;
***************
*** 1355,1361 ****
* Need share lock on buffer to examine tuple commit status.
*/
LockBuffer(buffer, BUFFER_LOCK_SHARE);
! dp = (PageHeader) BufferGetPage(buffer);
/*
* We'd better check for out-of-range offnum in case of VACUUM since the
--- 1355,1361 ----
* Need share lock on buffer to examine tuple commit status.
*/
LockBuffer(buffer, BUFFER_LOCK_SHARE);
! page = BufferGetPage(buffer);
/*
* We'd better check for out-of-range offnum in case of VACUUM since the
***************
*** 1362,1368 ****
* TID was obtained.
*/
offnum = ItemPointerGetOffsetNumber(tid);
! if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
{
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
if (keep_buf)
--- 1362,1368 ----
* TID was obtained.
*/
offnum = ItemPointerGetOffsetNumber(tid);
! if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
{
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
if (keep_buf)
***************
*** 1379,1385 ****
/*
* get the item line pointer corresponding to the requested tid
*/
! lp = PageGetItemId(dp, offnum);
/*
* Must check for deleted tuple.
--- 1379,1385 ----
/*
* get the item line pointer corresponding to the requested tid
*/
! lp = PageGetItemId(page, offnum);
/*
* Must check for deleted tuple.
***************
*** 1401,1407 ****
/*
* fill in *tuple fields
*/
! tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
tuple->t_len = ItemIdGetLength(lp);
tuple->t_tableOid = RelationGetRelid(relation);
--- 1401,1407 ----
/*
* fill in *tuple fields
*/
! tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
tuple->t_len = ItemIdGetLength(lp);
tuple->t_tableOid = RelationGetRelid(relation);
***************
*** 1626,1632 ****
for (;;)
{
Buffer buffer;
! PageHeader dp;
OffsetNumber offnum;
ItemId lp;
HeapTupleData tp;
--- 1626,1632 ----
for (;;)
{
Buffer buffer;
! Page page;
OffsetNumber offnum;
ItemId lp;
HeapTupleData tp;
***************
*** 1637,1643 ****
*/
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
LockBuffer(buffer, BUFFER_LOCK_SHARE);
! dp = (PageHeader) BufferGetPage(buffer);
/*
* Check for bogus item number. This is not treated as an error
--- 1637,1643 ----
*/
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
LockBuffer(buffer, BUFFER_LOCK_SHARE);
! page = BufferGetPage(buffer);
/*
* Check for bogus item number. This is not treated as an error
***************
*** 1645,1656 ****
* just assume that the prior tid is OK and return it unchanged.
*/
offnum = ItemPointerGetOffsetNumber(&ctid);
! if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
{
UnlockReleaseBuffer(buffer);
break;
}
! lp = PageGetItemId(dp, offnum);
if (!ItemIdIsNormal(lp))
{
UnlockReleaseBuffer(buffer);
--- 1645,1656 ----
* just assume that the prior tid is OK and return it unchanged.
*/
offnum = ItemPointerGetOffsetNumber(&ctid);
! if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
{
UnlockReleaseBuffer(buffer);
break;
}
! lp = PageGetItemId(page, offnum);
if (!ItemIdIsNormal(lp))
{
UnlockReleaseBuffer(buffer);
***************
*** 1659,1665 ****
/* OK to access the tuple */
tp.t_self = ctid;
! tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
tp.t_len = ItemIdGetLength(lp);
/*
--- 1659,1665 ----
/* OK to access the tuple */
tp.t_self = ctid;
! tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
tp.t_len = ItemIdGetLength(lp);
/*
***************
*** 1963,1969 ****
TransactionId xid = GetCurrentTransactionId();
ItemId lp;
HeapTupleData tp;
! PageHeader dp;
Buffer buffer;
bool have_tuple_lock = false;
bool iscombo;
--- 1963,1969 ----
TransactionId xid = GetCurrentTransactionId();
ItemId lp;
HeapTupleData tp;
! Page page;
Buffer buffer;
bool have_tuple_lock = false;
bool iscombo;
***************
*** 1973,1983 ****
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
! dp = (PageHeader) BufferGetPage(buffer);
! lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsNormal(lp));
! tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
tp.t_len = ItemIdGetLength(lp);
tp.t_self = *tid;
--- 1973,1983 ----
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
! page = BufferGetPage(buffer);
! lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsNormal(lp));
! tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
tp.t_len = ItemIdGetLength(lp);
tp.t_self = *tid;
***************
*** 2111,2117 ****
* the subsequent page pruning will be a no-op and the hint will be
* cleared.
*/
! PageSetPrunable(dp, xid);
/* store transaction information of xact deleting the tuple */
tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
--- 2111,2117 ----
* the subsequent page pruning will be a no-op and the hint will be
* cleared.
*/
! PageSetPrunable(page, xid);
/* store transaction information of xact deleting the tuple */
tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
***************
*** 2149,2156 ****
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);
! PageSetLSN(dp, recptr);
! PageSetTLI(dp, ThisTimeLineID);
}
END_CRIT_SECTION();
--- 2149,2156 ----
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);
! PageSetLSN(page, recptr);
! PageSetTLI(page, ThisTimeLineID);
}
END_CRIT_SECTION();
***************
*** 2275,2281 ****
ItemId lp;
HeapTupleData oldtup;
HeapTuple heaptup;
! PageHeader dp;
Buffer buffer,
newbuf;
bool need_toast,
--- 2275,2281 ----
ItemId lp;
HeapTupleData oldtup;
HeapTuple heaptup;
! Page page;
Buffer buffer,
newbuf;
bool need_toast,
***************
*** 2305,2315 ****
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
! dp = (PageHeader) BufferGetPage(buffer);
! lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
Assert(ItemIdIsNormal(lp));
! oldtup.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
oldtup.t_len = ItemIdGetLength(lp);
oldtup.t_self = *otid;
--- 2305,2315 ----
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
! page = BufferGetPage(buffer);
! lp = PageGetItemId(page, ItemPointerGetOffsetNumber(otid));
Assert(ItemIdIsNormal(lp));
! oldtup.t_data = (HeapTupleHeader) PageGetItem(page, lp);
oldtup.t_len = ItemIdGetLength(lp);
oldtup.t_self = *otid;
***************
*** 2490,2496 ****
HeapTupleHasExternal(newtup) ||
newtup->t_len > TOAST_TUPLE_THRESHOLD);
! pagefree = PageGetHeapFreeSpace((Page) dp);
newtupsize = MAXALIGN(newtup->t_len);
--- 2490,2496 ----
HeapTupleHasExternal(newtup) ||
newtup->t_len > TOAST_TUPLE_THRESHOLD);
! pagefree = PageGetHeapFreeSpace(page);
newtupsize = MAXALIGN(newtup->t_len);
***************
*** 2556,2562 ****
/* Re-acquire the lock on the old tuple's page. */
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
/* Re-check using the up-to-date free space */
! pagefree = PageGetHeapFreeSpace((Page) dp);
if (newtupsize > pagefree)
{
/*
--- 2556,2562 ----
/* Re-acquire the lock on the old tuple's page. */
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
/* Re-check using the up-to-date free space */
! pagefree = PageGetHeapFreeSpace(page);
if (newtupsize > pagefree)
{
/*
***************
*** 2602,2608 ****
else
{
/* Set a hint that the old page could use prune/defrag */
! PageSetFull(dp);
}
/* NO EREPORT(ERROR) from here till changes are logged */
--- 2602,2608 ----
else
{
/* Set a hint that the old page could use prune/defrag */
! PageSetFull(page);
}
/* NO EREPORT(ERROR) from here till changes are logged */
***************
*** 2620,2626 ****
* not to optimize for aborts. Note that heap_xlog_update must be kept in
* sync if this decision changes.
*/
! PageSetPrunable(dp, xid);
if (use_hot_update)
{
--- 2620,2626 ----
* not to optimize for aborts. Note that heap_xlog_update must be kept in
* sync if this decision changes.
*/
! PageSetPrunable(page, xid);
if (use_hot_update)
{
***************
*** 2945,2951 ****
HTSU_Result result;
ItemPointer tid = &(tuple->t_self);
ItemId lp;
! PageHeader dp;
TransactionId xid;
TransactionId xmax;
uint16 old_infomask;
--- 2945,2951 ----
HTSU_Result result;
ItemPointer tid = &(tuple->t_self);
ItemId lp;
! Page page;
TransactionId xid;
TransactionId xmax;
uint16 old_infomask;
***************
*** 2958,2968 ****
*buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);
! dp = (PageHeader) BufferGetPage(*buffer);
! lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsNormal(lp));
! tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
tuple->t_len = ItemIdGetLength(lp);
tuple->t_tableOid = RelationGetRelid(relation);
--- 2958,2968 ----
*buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);
! page = BufferGetPage(*buffer);
! lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsNormal(lp));
! tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
tuple->t_len = ItemIdGetLength(lp);
tuple->t_tableOid = RelationGetRelid(relation);
***************
*** 3301,3308 ****
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);
! PageSetLSN(dp, recptr);
! PageSetTLI(dp, ThisTimeLineID);
}
END_CRIT_SECTION();
--- 3301,3308 ----
recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);
! PageSetLSN(page, recptr);
! PageSetTLI(page, ThisTimeLineID);
}
END_CRIT_SECTION();
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c pgsql.orig/src/backend/access/heap/hio.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/hio.c pá Ärc 4 10:23:41 2008
***************
*** 107,113 ****
Buffer otherBuffer, bool use_fsm)
{
Buffer buffer = InvalidBuffer;
! Page pageHeader;
Size pageFreeSpace,
saveFreeSpace;
BlockNumber targetBlock,
--- 107,113 ----
Buffer otherBuffer, bool use_fsm)
{
Buffer buffer = InvalidBuffer;
! Page page;
Size pageFreeSpace,
saveFreeSpace;
BlockNumber targetBlock,
***************
*** 218,225 ****
* Now we can check to see if there's enough free space here. If so,
* we're done.
*/
! pageHeader = (Page) BufferGetPage(buffer);
! pageFreeSpace = PageGetHeapFreeSpace(pageHeader);
if (len + saveFreeSpace <= pageFreeSpace)
{
/* use this page as future insert target, too */
--- 218,225 ----
* Now we can check to see if there's enough free space here. If so,
* we're done.
*/
! page = BufferGetPage(buffer);
! pageFreeSpace = PageGetHeapFreeSpace(page);
if (len + saveFreeSpace <= pageFreeSpace)
{
/* use this page as future insert target, too */
***************
*** 303,318 ****
* is empty (this should never happen, but if it does we don't want to
* risk wiping out valid data).
*/
! pageHeader = (Page) BufferGetPage(buffer);
! if (!PageIsNew((PageHeader) pageHeader))
elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
BufferGetBlockNumber(buffer),
RelationGetRelationName(relation));
! PageInit(pageHeader, BufferGetPageSize(buffer), 0);
! if (len > PageGetHeapFreeSpace(pageHeader))
{
/* We should not get here given the test at the top */
elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
--- 303,318 ----
* is empty (this should never happen, but if it does we don't want to
* risk wiping out valid data).
*/
! page = BufferGetPage(buffer);
! if (!PageIsNew(page))
elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
BufferGetBlockNumber(buffer),
RelationGetRelationName(relation));
! PageInit(page, BufferGetPageSize(buffer), 0);
! if (len > PageGetHeapFreeSpace(page))
{
/* We should not get here given the test at the top */
elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c pgsql.orig/src/backend/access/heap/pruneheap.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/pruneheap.c pá Ärc 4 10:23:41 2008
***************
*** 71,77 ****
void
heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
{
! PageHeader dp = (PageHeader) BufferGetPage(buffer);
Size minfree;
/*
--- 71,77 ----
void
heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
{
! Page page = BufferGetPage(buffer);
Size minfree;
/*
***************
*** 80,86 ****
* Forget it if page is not hinted to contain something prunable that's
* older than OldestXmin.
*/
! if (!PageIsPrunable(dp, OldestXmin))
return;
/*
--- 80,86 ----
* Forget it if page is not hinted to contain something prunable that's
* older than OldestXmin.
*/
! if (!PageIsPrunable(page, OldestXmin))
return;
/*
***************
*** 99,105 ****
HEAP_DEFAULT_FILLFACTOR);
minfree = Max(minfree, BLCKSZ / 10);
! if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
{
/* OK, try to get exclusive buffer lock */
if (!ConditionalLockBufferForCleanup(buffer))
--- 99,105 ----
HEAP_DEFAULT_FILLFACTOR);
minfree = Max(minfree, BLCKSZ / 10);
! if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
{
/* OK, try to get exclusive buffer lock */
if (!ConditionalLockBufferForCleanup(buffer))
***************
*** 111,117 ****
* prune. (We needn't recheck PageIsPrunable, since no one else could
* have pruned while we hold pin.)
*/
! if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
{
/* OK to prune (though not to remove redirects) */
(void) heap_page_prune(relation, buffer, OldestXmin, false, true);
--- 111,117 ----
* prune. (We needn't recheck PageIsPrunable, since no one else could
* have pruned while we hold pin.)
*/
! if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
{
/* OK to prune (though not to remove redirects) */
(void) heap_page_prune(relation, buffer, OldestXmin, false, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c pgsql.orig/src/backend/access/nbtree/nbtpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/nbtree/nbtpage.c pá Ärc 4 10:23:41 2008
***************
*** 436,448 ****
/*
* Additionally check that the special area looks sane.
*/
! if (((PageHeader) (page))->pd_special !=
! (BLCKSZ - MAXALIGN(sizeof(BTPageOpaqueData))))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains corrupted page at block %u",
RelationGetRelationName(rel),
! BufferGetBlockNumber(buf)),
errhint("Please REINDEX it.")));
}
--- 436,447 ----
/*
* Additionally check that the special area looks sane.
*/
! if ( (PageGetSpecialSize(page)) != MAXALIGN(sizeof(BTPageOpaqueData)))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains corrupted page at block %u",
RelationGetRelationName(rel),
! BufferGetBlockNumber(buf)),
errhint("Please REINDEX it.")));
}
***************
*** 555,561 ****
/* Initialize the new page before returning it */
page = BufferGetPage(buf);
! Assert(PageIsNew((PageHeader) page));
_bt_pageinit(page, BufferGetPageSize(buf));
}
--- 554,560 ----
/* Initialize the new page before returning it */
page = BufferGetPage(buf);
! Assert(PageIsNew(page));
_bt_pageinit(page, BufferGetPageSize(buf));
}
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c pgsql.orig/src/backend/access/transam/xlog.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/transam/xlog.c pá Ärc 4 10:23:41 2008
***************
*** 1017,1025 ****
XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
XLogRecPtr *lsn, BkpBlock *bkpb)
{
! PageHeader page;
! page = (PageHeader) BufferGetBlock(rdata->buffer);
/*
* XXX We assume page LSN is first data on *every* page that can be passed
--- 1017,1025 ----
XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
XLogRecPtr *lsn, BkpBlock *bkpb)
{
! Page page;
! page = BufferGetBlock(rdata->buffer);
/*
* XXX We assume page LSN is first data on *every* page that can be passed
***************
*** 1026,1035 ****
* to XLogInsert, whether it otherwise has the standard page layout or
* not.
*/
! *lsn = page->pd_lsn;
if (doPageWrites &&
! XLByteLE(page->pd_lsn, RedoRecPtr))
{
/*
* The page needs to be backed up, so set up *bkpb
--- 1026,1035 ----
* to XLogInsert, whether it otherwise has the standard page layout or
* not.
*/
! *lsn = PageGetLSN(page);
if (doPageWrites &&
! XLByteLE(PageGetLSN(page), RedoRecPtr))
{
/*
* The page needs to be backed up, so set up *bkpb
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c pgsql.orig/src/backend/access/transam/xlogutils.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/access/transam/xlogutils.c pá Ärc 4 10:23:41 2008
***************
*** 262,268 ****
/* check that page has been initialized */
Page page = (Page) BufferGetPage(buffer);
! if (PageIsNew((PageHeader) page))
{
UnlockReleaseBuffer(buffer);
log_invalid_page(reln->rd_node, blkno, true);
--- 262,268 ----
/* check that page has been initialized */
Page page = (Page) BufferGetPage(buffer);
! if (PageIsNew(page))
{
UnlockReleaseBuffer(buffer);
log_invalid_page(reln->rd_node, blkno, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c pgsql.orig/src/backend/commands/sequence.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/commands/sequence.c pá Ärc 4 10:23:41 2008
***************
*** 109,115 ****
Oid seqoid;
Relation rel;
Buffer buf;
! PageHeader page;
sequence_magic *sm;
HeapTuple tuple;
TupleDesc tupDesc;
--- 109,115 ----
Oid seqoid;
Relation rel;
Buffer buf;
! Page page;
sequence_magic *sm;
HeapTuple tuple;
TupleDesc tupDesc;
***************
*** 212,220 ****
buf = ReadBuffer(rel, P_NEW);
Assert(BufferGetBlockNumber(buf) == 0);
! page = (PageHeader) BufferGetPage(buf);
! PageInit((Page) page, BufferGetPageSize(buf), sizeof(sequence_magic));
sm = (sequence_magic *) PageGetSpecialPointer(page);
sm->magic = SEQ_MAGIC;
--- 212,220 ----
buf = ReadBuffer(rel, P_NEW);
Assert(BufferGetBlockNumber(buf) == 0);
! page = BufferGetPage(buf);
! PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
sm = (sequence_magic *) PageGetSpecialPointer(page);
sm->magic = SEQ_MAGIC;
***************
*** 954,960 ****
static Form_pg_sequence
read_info(SeqTable elm, Relation rel, Buffer *buf)
{
! PageHeader page;
ItemId lp;
HeapTupleData tuple;
sequence_magic *sm;
--- 954,960 ----
static Form_pg_sequence
read_info(SeqTable elm, Relation rel, Buffer *buf)
{
! Page page;
ItemId lp;
HeapTupleData tuple;
sequence_magic *sm;
***************
*** 963,969 ****
*buf = ReadBuffer(rel, 0);
LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
! page = (PageHeader) BufferGetPage(*buf);
sm = (sequence_magic *) PageGetSpecialPointer(page);
if (sm->magic != SEQ_MAGIC)
--- 963,969 ----
*buf = ReadBuffer(rel, 0);
LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);
! page = BufferGetPage(*buf);
sm = (sequence_magic *) PageGetSpecialPointer(page);
if (sm->magic != SEQ_MAGIC)
***************
*** 972,978 ****
lp = PageGetItemId(page, FirstOffsetNumber);
Assert(ItemIdIsNormal(lp));
! tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);
seq = (Form_pg_sequence) GETSTRUCT(&tuple);
--- 972,978 ----
lp = PageGetItemId(page, FirstOffsetNumber);
Assert(ItemIdIsNormal(lp));
! tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
seq = (Form_pg_sequence) GETSTRUCT(&tuple);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c pgsql.orig/src/backend/commands/trigger.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/commands/trigger.c pá Ärc 4 10:23:41 2008
***************
*** 2203,2219 ****
}
else
{
! PageHeader dp;
ItemId lp;
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
! dp = (PageHeader) BufferGetPage(buffer);
! lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsNormal(lp));
! tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
tuple.t_len = ItemIdGetLength(lp);
tuple.t_self = *tid;
tuple.t_tableOid = RelationGetRelid(relation);
--- 2203,2219 ----
}
else
{
! Page page;
ItemId lp;
buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
! page = BufferGetPage(buffer);
! lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
Assert(ItemIdIsNormal(lp));
! tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
tuple.t_len = ItemIdGetLength(lp);
tuple.t_self = *tid;
tuple.t_tableOid = RelationGetRelid(relation);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c pgsql.orig/src/backend/optimizer/util/plancat.c
*** pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/optimizer/util/plancat.c pá Ärc 4 10:23:41 2008
***************
*** 429,435 ****
tuple_width += sizeof(HeapTupleHeaderData);
tuple_width += sizeof(ItemPointerData);
/* note: integer division is intentional here */
! density = (BLCKSZ - sizeof(PageHeaderData)) / tuple_width;
}
*tuples = rint(density * (double) curpages);
break;
--- 429,435 ----
tuple_width += sizeof(HeapTupleHeaderData);
tuple_width += sizeof(ItemPointerData);
/* note: integer division is intentional here */
! density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
}
*tuples = rint(density * (double) curpages);
break;
diff -cr pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c pgsql.orig/src/backend/storage/buffer/bufmgr.c
*** pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/backend/storage/buffer/bufmgr.c pá Ärc 4 10:23:41 2008
***************
*** 223,229 ****
* always have left a zero-filled buffer, complain if not PageIsNew.
*/
bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
! if (!PageIsNew((PageHeader) bufBlock))
ereport(ERROR,
(errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
blockNum, RelationGetRelationName(reln)),
--- 223,229 ----
* always have left a zero-filled buffer, complain if not PageIsNew.
*/
bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
! if (!PageIsNew((Page) bufBlock))
ereport(ERROR,
(errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
blockNum, RelationGetRelationName(reln)),
***************
*** 292,298 ****
else
smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
/* check for garbage data */
! if (!PageHeaderIsValid((PageHeader) bufBlock))
{
if (zero_damaged_pages)
{
--- 292,298 ----
else
smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
/* check for garbage data */
! if (!PageHeaderIsValid((Page) bufBlock))
{
if (zero_damaged_pages)
{
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/hash.h pgsql.orig/src/include/access/hash.h
*** pgsql.orig.da8c485e0e2a/src/include/access/hash.h pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/include/access/hash.h pá Ärc 4 10:23:41 2008
***************
*** 166,174 ****
*/
#define HashMaxItemSize(page) \
(PageGetPageSize(page) - \
! sizeof(PageHeaderData) - \
! MAXALIGN(sizeof(HashPageOpaqueData)) - \
! sizeof(ItemIdData))
#define HASH_MIN_FILLFACTOR 10
#define HASH_DEFAULT_FILLFACTOR 75
--- 166,173 ----
*/
#define HashMaxItemSize(page) \
(PageGetPageSize(page) - \
! ( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemId)) + \
! MAXALIGN(sizeof(HashPageOpaqueData)) ))
#define HASH_MIN_FILLFACTOR 10
#define HASH_DEFAULT_FILLFACTOR 75
***************
*** 191,197 ****
#define BMPG_SHIFT(metap) ((metap)->hashm_bmshift)
#define BMPG_MASK(metap) (BMPGSZ_BIT(metap) - 1)
#define HashPageGetBitmap(pg) \
! ((uint32 *) (((char *) (pg)) + MAXALIGN(sizeof(PageHeaderData))))
/*
* The number of bits in an ovflpage bitmap word.
--- 190,196 ----
#define BMPG_SHIFT(metap) ((metap)->hashm_bmshift)
#define BMPG_MASK(metap) (BMPGSZ_BIT(metap) - 1)
#define HashPageGetBitmap(pg) \
! ((uint32 *) (((char *) (pg)) + MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))))
/*
* The number of bits in an ovflpage bitmap word.
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/htup.h pgsql.orig/src/include/access/htup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/htup.h pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/include/access/htup.h pá Ärc 4 10:23:41 2008
***************
*** 367,373 ****
* of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
* on the same page.
*/
! #define MaxHeapTupleSize (BLCKSZ - MAXALIGN(sizeof(PageHeaderData)))
/*
* MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
--- 367,373 ----
* of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
* on the same page.
*/
! #define MaxHeapTupleSize (BLCKSZ - MAXALIGN( (SizeOfPageHeaderData) + sizeof(ItemIdData)))
/*
* MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
***************
*** 381,387 ****
* require increases in the size of work arrays.
*/
#define MaxHeapTuplesPerPage \
! ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
(MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))
/*
--- 381,387 ----
* require increases in the size of work arrays.
*/
#define MaxHeapTuplesPerPage \
! ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
(MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))
/*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/itup.h pgsql.orig/src/include/access/itup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/itup.h pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/include/access/itup.h pá Ärc 4 10:23:41 2008
***************
*** 134,140 ****
* must be maxaligned, and it must have an associated item pointer.
*/
#define MaxIndexTuplesPerPage \
! ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
(MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
--- 134,140 ----
* must be maxaligned, and it must have an associated item pointer.
*/
#define MaxIndexTuplesPerPage \
! ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
(MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h pgsql.orig/src/include/access/nbtree.h
*** pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/include/access/nbtree.h pá Ärc 4 10:23:41 2008
***************
*** 119,125 ****
*/
#define BTMaxItemSize(page) \
MAXALIGN_DOWN((PageGetPageSize(page) - \
! MAXALIGN(sizeof(PageHeaderData) + 2*sizeof(ItemIdData)) - \
MAXALIGN(sizeof(BTPageOpaqueData))) / 3)
/*
--- 119,125 ----
*/
#define BTMaxItemSize(page) \
MAXALIGN_DOWN((PageGetPageSize(page) - \
! MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
MAXALIGN(sizeof(BTPageOpaqueData))) / 3)
/*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h pgsql.orig/src/include/access/tuptoaster.h
*** pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h pá Ärc 4 10:23:41 2008
--- pgsql.orig/src/include/access/tuptoaster.h pá Ärc 4 10:23:41 2008
***************
*** 49,55 ****
/* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
#define TOAST_TUPLE_THRESHOLD \
MAXALIGN_DOWN((BLCKSZ - \
! MAXALIGN(sizeof(PageHeaderData) + (TOAST_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
/ TOAST_TUPLES_PER_PAGE)
#define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD
--- 49,55 ----
/* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
#define TOAST_TUPLE_THRESHOLD \
MAXALIGN_DOWN((BLCKSZ - \
! MAXALIGN(SizeOfPageHeaderData + (TOAST_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
/ TOAST_TUPLES_PER_PAGE)
#define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD
***************
*** 76,82 ****
/* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
#define EXTERN_TUPLE_MAX_SIZE \
MAXALIGN_DOWN((BLCKSZ - \
! MAXALIGN(sizeof(PageHeaderData) + (EXTERN_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
/ EXTERN_TUPLES_PER_PAGE)
#define TOAST_MAX_CHUNK_SIZE \
--- 76,82 ----
/* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
#define EXTERN_TUPLE_MAX_SIZE \
MAXALIGN_DOWN((BLCKSZ - \
! MAXALIGN(SizeOfPageHeaderData + (EXTERN_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
/ EXTERN_TUPLES_PER_PAGE)
#define TOAST_MAX_CHUNK_SIZE \
--
Sent via pgsql-patches mailing list (pgsql-patches@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-patches