diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/storage/page/bufpage.c | 46 |
1 files changed, 21 insertions, 25 deletions
diff --git a/src/backend/storage/page/bufpage.c b/src/backend/storage/page/bufpage.c index 41642eb59c4..b6aa2af818a 100644 --- a/src/backend/storage/page/bufpage.c +++ b/src/backend/storage/page/bufpage.c @@ -481,6 +481,8 @@ PageRepairFragmentation(Page page) Offset pd_lower = ((PageHeader) page)->pd_lower; Offset pd_upper = ((PageHeader) page)->pd_upper; Offset pd_special = ((PageHeader) page)->pd_special; + itemIdSortData itemidbase[MaxHeapTuplesPerPage]; + itemIdSort itemidptr; ItemId lp; int nline, nstorage, @@ -505,15 +507,31 @@ PageRepairFragmentation(Page page) errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u", pd_lower, pd_upper, pd_special))); + /* + * Run through the line pointer array and collect data about live items. + */ nline = PageGetMaxOffsetNumber(page); - nunused = nstorage = 0; + itemidptr = itemidbase; + nunused = totallen = 0; for (i = FirstOffsetNumber; i <= nline; i++) { lp = PageGetItemId(page, i); if (ItemIdIsUsed(lp)) { if (ItemIdHasStorage(lp)) - nstorage++; + { + itemidptr->offsetindex = i - 1; + itemidptr->itemoff = ItemIdGetOffset(lp); + if (unlikely(itemidptr->itemoff < (int) pd_upper || + itemidptr->itemoff >= (int) pd_special)) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("corrupted item pointer: %u", + itemidptr->itemoff))); + itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp)); + totallen += itemidptr->alignedlen; + itemidptr++; + } } else { @@ -523,6 +541,7 @@ PageRepairFragmentation(Page page) } } + nstorage = itemidptr - itemidbase; if (nstorage == 0) { /* Page is completely empty, so just reset it quickly */ @@ -531,29 +550,6 @@ PageRepairFragmentation(Page page) else { /* Need to compact the page the hard way */ - itemIdSortData itemidbase[MaxHeapTuplesPerPage]; - itemIdSort itemidptr = itemidbase; - - totallen = 0; - for (i = 0; i < nline; i++) - { - lp = PageGetItemId(page, i + 1); - if (ItemIdHasStorage(lp)) - { - itemidptr->offsetindex = i; - itemidptr->itemoff = ItemIdGetOffset(lp); - if (itemidptr->itemoff < (int) pd_upper || - itemidptr->itemoff >= (int) pd_special) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("corrupted item pointer: %u", - itemidptr->itemoff))); - itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp)); - totallen += itemidptr->alignedlen; - itemidptr++; - } - } - if (totallen > (Size) (pd_special - pd_lower)) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), |