#include "access/xlogdefs.h"#include "storage/block.h"#include "storage/item.h"#include "storage/off.h"

Go to the source code of this file.
Data Structures | |
| struct | PageXLogRecPtr |
| struct | PageHeaderData |
Defines | |
| #define | PageXLogRecPtrGet(val) ((uint64) (val).xlogid << 32 | (val).xrecoff) |
| #define | PageXLogRecPtrSet(ptr, lsn) ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn)) |
| #define | PD_HAS_FREE_LINES 0x0001 |
| #define | PD_PAGE_FULL 0x0002 |
| #define | PD_ALL_VISIBLE 0x0004 |
| #define | PD_VALID_FLAG_BITS 0x0007 |
| #define | PG_PAGE_LAYOUT_VERSION 4 |
| #define | PG_DATA_CHECKSUM_VERSION 1 |
| #define | PageIsValid(page) PointerIsValid(page) |
| #define | SizeOfPageHeaderData (offsetof(PageHeaderData, pd_linp)) |
| #define | PageIsEmpty(page) (((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData) |
| #define | PageIsNew(page) (((PageHeader) (page))->pd_upper == 0) |
| #define | PageGetItemId(page, offsetNumber) ((ItemId) (&((PageHeader) (page))->pd_linp[(offsetNumber) - 1])) |
| #define | PageGetContents(page) ((char *) (page) + MAXALIGN(SizeOfPageHeaderData)) |
| #define | PageSizeIsValid(pageSize) ((pageSize) == BLCKSZ) |
| #define | PageGetPageSize(page) ((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00)) |
| #define | PageGetPageLayoutVersion(page) (((PageHeader) (page))->pd_pagesize_version & 0x00FF) |
| #define | PageSetPageSizeAndVersion(page, size, version) |
| #define | PageGetSpecialSize(page) ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special)) |
| #define | PageGetSpecialPointer(page) |
| #define | PageGetItem(page, itemId) |
| #define | PageGetMaxOffsetNumber(page) |
| #define | PageGetLSN(page) PageXLogRecPtrGet(((PageHeader) (page))->pd_lsn) |
| #define | PageSetLSN(page, lsn) PageXLogRecPtrSet(((PageHeader) (page))->pd_lsn, lsn) |
| #define | PageHasFreeLinePointers(page) (((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES) |
| #define | PageSetHasFreeLinePointers(page) (((PageHeader) (page))->pd_flags |= PD_HAS_FREE_LINES) |
| #define | PageClearHasFreeLinePointers(page) (((PageHeader) (page))->pd_flags &= ~PD_HAS_FREE_LINES) |
| #define | PageIsFull(page) (((PageHeader) (page))->pd_flags & PD_PAGE_FULL) |
| #define | PageSetFull(page) (((PageHeader) (page))->pd_flags |= PD_PAGE_FULL) |
| #define | PageClearFull(page) (((PageHeader) (page))->pd_flags &= ~PD_PAGE_FULL) |
| #define | PageIsAllVisible(page) (((PageHeader) (page))->pd_flags & PD_ALL_VISIBLE) |
| #define | PageSetAllVisible(page) (((PageHeader) (page))->pd_flags |= PD_ALL_VISIBLE) |
| #define | PageClearAllVisible(page) (((PageHeader) (page))->pd_flags &= ~PD_ALL_VISIBLE) |
| #define | PageIsPrunable(page, oldestxmin) |
| #define | PageSetPrunable(page, xid) |
| #define | PageClearPrunable(page) (((PageHeader) (page))->pd_prune_xid = InvalidTransactionId) |
Typedefs | |
| typedef Pointer | Page |
| typedef uint16 | LocationIndex |
| typedef struct PageHeaderData | PageHeaderData |
| typedef PageHeaderData * | PageHeader |
Functions | |
| void | PageInit (Page page, Size pageSize, Size specialSize) |
| bool | PageIsVerified (Page page, BlockNumber blkno) |
| OffsetNumber | PageAddItem (Page page, Item item, Size size, OffsetNumber offsetNumber, bool overwrite, bool is_heap) |
| Page | PageGetTempPage (Page page) |
| Page | PageGetTempPageCopy (Page page) |
| Page | PageGetTempPageCopySpecial (Page page) |
| void | PageRestoreTempPage (Page tempPage, Page oldPage) |
| void | PageRepairFragmentation (Page page) |
| Size | PageGetFreeSpace (Page page) |
| Size | PageGetExactFreeSpace (Page page) |
| Size | PageGetHeapFreeSpace (Page page) |
| void | PageIndexTupleDelete (Page page, OffsetNumber offset) |
| void | PageIndexMultiDelete (Page page, OffsetNumber *itemnos, int nitems) |
| char * | PageSetChecksumCopy (Page page, BlockNumber blkno) |
| void | PageSetChecksumInplace (Page page, BlockNumber blkno) |
| #define PageClearAllVisible | ( | page | ) | (((PageHeader) (page))->pd_flags &= ~PD_ALL_VISIBLE) |
Definition at line 367 of file bufpage.h.
Referenced by heap_delete(), heap_insert(), heap_multi_insert(), heap_update(), heap_xlog_delete(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), and lazy_scan_heap().
| #define PageClearFull | ( | page | ) | (((PageHeader) (page))->pd_flags &= ~PD_PAGE_FULL) |
Definition at line 360 of file bufpage.h.
Referenced by heap_page_prune().
| #define PageClearHasFreeLinePointers | ( | page | ) | (((PageHeader) (page))->pd_flags &= ~PD_HAS_FREE_LINES) |
Definition at line 353 of file bufpage.h.
Referenced by PageAddItem(), and PageRepairFragmentation().
| #define PageClearPrunable | ( | page | ) | (((PageHeader) (page))->pd_prune_xid = InvalidTransactionId) |
| #define PageGetContents | ( | page | ) | ((char *) (page) + MAXALIGN(SizeOfPageHeaderData)) |
Definition at line 243 of file bufpage.h.
Referenced by fsm_get_avail(), fsm_get_max_avail(), fsm_page_contents(), fsm_rebuild_page(), fsm_search_avail(), fsm_set_avail(), fsm_truncate_avail(), fsm_vacuum_page(), visibilitymap_clear(), visibilitymap_count(), visibilitymap_set(), visibilitymap_test(), and visibilitymap_truncate().
| #define PageGetItem | ( | page, | ||
| itemId | ||||
| ) |
( \
AssertMacro(PageIsValid(page)), \
AssertMacro(ItemIdHasStorage(itemId)), \
(Item)(((char *)(page)) + ItemIdGetOffset(itemId)) \
)
Definition at line 318 of file bufpage.h.
Referenced by _bt_buildadd(), _bt_check_unique(), _bt_checkkeys(), _bt_compare(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_isequal(), _bt_killitems(), _bt_newroot(), _bt_pagedel(), _bt_search(), _bt_split(), _hash_binsearch(), _hash_binsearch_last(), _hash_first(), _hash_next(), _hash_splitbucket(), _hash_squeezebucket(), _hash_step(), acquire_sample_rows(), addLeafTuple(), addOrReplaceTuple(), bitgetpage(), BitmapHeapNext(), bt_page_items(), btree_xlog_delete_get_latestRemovedXid(), btree_xlog_delete_page(), btree_xlog_newroot(), btree_xlog_split(), btvacuumpage(), checkSplitConditions(), collectMatchBitmap(), collectMatchesForHeapRow(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryIsEnoughSpace(), entryLocateEntry(), entryLocateLeafEntry(), entryPreparePage(), entrySplitPage(), fill_seq_with_data(), GetBTPageStatistics(), getRightMostTuple(), GetTupleForTrigger(), ginbulkdelete(), ginEntryInsert(), ginRedoInsert(), ginVacuumEntryPage(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistbulkdelete(), gistchoose(), gistdoinsert(), gistextractpage(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistGetMaxLevel(), gistMemorizeAllDownlinks(), gistnospace(), gistProcessItup(), gistScanPage(), hashbulkdelete(), hashgettuple(), heap_delete(), heap_fetch(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_lock_tuple(), heap_page_is_all_visible(), heap_page_items(), heap_prune_chain(), heap_update(), heap_xlog_delete(), heap_xlog_freeze(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_update(), heapgetpage(), heapgettup(), heapgettup_pagemode(), lazy_check_needs_freeze(), lazy_scan_heap(), matchPartialInPendingList(), moveLeafs(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgWalk(), startScanEntry(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and xlogVacuumPage().
| #define PageGetItemId | ( | page, | ||
| offsetNumber | ||||
| ) | ((ItemId) (&((PageHeader) (page))->pd_linp[(offsetNumber) - 1])) |
Definition at line 232 of file bufpage.h.
Referenced by _bt_buildadd(), _bt_check_unique(), _bt_checkkeys(), _bt_compare(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_isequal(), _bt_killitems(), _bt_newroot(), _bt_pagedel(), _bt_search(), _bt_slideleft(), _bt_split(), _bt_vacuum_one_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_first(), _hash_next(), _hash_splitbucket(), _hash_squeezebucket(), _hash_step(), acquire_sample_rows(), addLeafTuple(), addOrReplaceTuple(), bitgetpage(), BitmapHeapNext(), bt_page_items(), btree_xlog_delete_get_latestRemovedXid(), btree_xlog_delete_page(), btree_xlog_newroot(), btree_xlog_split(), btvacuumpage(), checkSplitConditions(), collectMatchBitmap(), collectMatchesForHeapRow(), count_nondeletable_pages(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryIsEnoughSpace(), entryLocateEntry(), entryLocateLeafEntry(), entryPreparePage(), entrySplitPage(), fill_seq_with_data(), GetBTPageStatistics(), getRightMostTuple(), GetTupleForTrigger(), ginbulkdelete(), ginEntryInsert(), ginRedoInsert(), ginVacuumEntryPage(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistbulkdelete(), gistchoose(), gistdoinsert(), gistextractpage(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistGetMaxLevel(), gistMemorizeAllDownlinks(), gistnospace(), gistProcessItup(), gistScanPage(), hashbulkdelete(), hashgetbitmap(), hashgettuple(), heap_delete(), heap_fetch(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_lock_tuple(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune(), heap_page_prune_execute(), heap_prune_chain(), heap_update(), heap_xlog_delete(), heap_xlog_freeze(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_update(), heapgetpage(), heapgettup(), heapgettup_pagemode(), lazy_check_needs_freeze(), lazy_scan_heap(), lazy_vacuum_page(), matchPartialInPendingList(), moveLeafs(), PageAddItem(), PageGetHeapFreeSpace(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageRepairFragmentation(), pgstat_index_page(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgWalk(), startScanEntry(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and xlogVacuumPage().
| #define PageGetLSN | ( | page | ) | PageXLogRecPtrGet(((PageHeader) (page))->pd_lsn) |
Definition at line 344 of file bufpage.h.
Referenced by _bt_split(), btree_xlog_delete(), btree_xlog_delete_page(), btree_xlog_insert(), btree_xlog_split(), btree_xlog_vacuum(), BufferGetLSNAtomic(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoUpdateMetapage(), ginRedoVacuumPage(), gistbulkdelete(), gistdoinsert(), gistFindCorrectParent(), gistFindPath(), gistRedoClearFollowRight(), gistRedoPageUpdateRecord(), heap_xlog_clean(), heap_xlog_delete(), heap_xlog_freeze(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), nextval_internal(), page_header(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), and XLogCheckBuffer().
| #define PageGetMaxOffsetNumber | ( | page | ) |
(((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData ? 0 : \ ((((PageHeader) (page))->pd_lower - SizeOfPageHeaderData) \ / sizeof(ItemIdData)))
Definition at line 335 of file bufpage.h.
Referenced by _bt_binsrch(), _bt_check_unique(), _bt_checkkeys(), _bt_endpoint(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_killitems(), _bt_pagedel(), _bt_parent_deletion_safe(), _bt_readpage(), _bt_slideleft(), _bt_split(), _bt_steppage(), _bt_vacuum_one_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_splitbucket(), _hash_squeezebucket(), _hash_step(), acquire_sample_rows(), addOrReplaceTuple(), bitgetpage(), bt_page_items(), btree_xlog_delete_page(), btree_xlog_split(), btvacuumpage(), checkSplitConditions(), count_nondeletable_pages(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryLocateEntry(), entryLocateLeafEntry(), entrySplitPage(), GetBTPageStatistics(), getRightMostTuple(), ginbulkdelete(), ginHeapTupleFastInsert(), ginInsertCleanup(), ginRedoInsert(), ginRedoUpdateMetapage(), ginRedoVacuumPage(), ginvacuumcleanup(), ginVacuumEntryPage(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistbulkdelete(), gistchoose(), gistextractpage(), gistfillbuffer(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistMemorizeAllDownlinks(), gistRedoPageUpdateRecord(), gistScanPage(), hashbulkdelete(), hashgettuple(), heap_fetch(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_insert(), heap_multi_insert(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune(), heap_prune_chain(), heap_xlog_delete(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heapgetpage(), heapgettup(), lazy_check_needs_freeze(), lazy_scan_heap(), log_heap_update(), moveLeafs(), moveRightIfItNeeded(), PageAddItem(), PageGetHeapFreeSpace(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageRepairFragmentation(), pgstat_btree_page(), pgstat_gist_page(), pgstat_hash_page(), processPendingPage(), scanGetCandidate(), SpGistPageAddNewItem(), spgRedoVacuumRedirect(), spgWalk(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and xlogVacuumPage().
| #define PageGetPageLayoutVersion | ( | page | ) | (((PageHeader) (page))->pd_pagesize_version & 0x00FF) |
Definition at line 272 of file bufpage.h.
Referenced by page_header().
| #define PageGetPageSize | ( | page | ) | ((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00)) |
Definition at line 265 of file bufpage.h.
Referenced by _bt_findsplitloc(), dataSplitPage(), entrySplitPage(), GetBTPageStatistics(), page_header(), PageGetTempPage(), PageGetTempPageCopy(), PageGetTempPageCopySpecial(), and PageRestoreTempPage().
| #define PageGetSpecialPointer | ( | page | ) |
( \
AssertMacro(PageIsValid(page)), \
(char *) ((char *) (page) + ((PageHeader) (page))->pd_special) \
)
Definition at line 304 of file bufpage.h.
Referenced by _bt_binsrch(), _bt_blnewpage(), _bt_buildadd(), _bt_check_unique(), _bt_checkkeys(), _bt_compare(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_endpoint(), _bt_findinsertloc(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getbuf(), _bt_getroot(), _bt_getrootheight(), _bt_getstackbuf(), _bt_gettrueroot(), _bt_initmetapage(), _bt_insert_parent(), _bt_insertonpg(), _bt_isequal(), _bt_killitems(), _bt_moveright(), _bt_newroot(), _bt_page_recyclable(), _bt_pagedel(), _bt_parent_deletion_safe(), _bt_pgaddtup(), _bt_readpage(), _bt_restore_meta(), _bt_search(), _bt_sortaddtup(), _bt_split(), _bt_steppage(), _bt_uppershutdown(), _bt_vacuum_one_page(), _bt_walk_left(), _hash_addovflpage(), _hash_checkpage(), _hash_doinsert(), _hash_first(), _hash_freeovflpage(), _hash_initbitmap(), _hash_metapinit(), _hash_readnext(), _hash_readprev(), _hash_splitbucket(), _hash_squeezebucket(), _hash_step(), bt_page_items(), btree_xlog_cleanup(), btree_xlog_delete(), btree_xlog_delete_page(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_vacuum(), btvacuumpage(), fill_seq_with_data(), GetBTPageStatistics(), hashbulkdelete(), PageGetTempPageCopySpecial(), pgstat_btree_page(), pgstat_hash_page(), pgstatindex(), read_seq_tuple(), and seq_redo().
| #define PageGetSpecialSize | ( | page | ) | ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special)) |
Definition at line 297 of file bufpage.h.
Referenced by _bt_checkpage(), _hash_checkpage(), gistcheckpage(), PageGetTempPageCopySpecial(), and pgstat_hash_page().
| #define PageHasFreeLinePointers | ( | page | ) | (((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES) |
Definition at line 349 of file bufpage.h.
Referenced by PageAddItem(), and PageGetHeapFreeSpace().
| #define PageIsAllVisible | ( | page | ) | (((PageHeader) (page))->pd_flags & PD_ALL_VISIBLE) |
Definition at line 363 of file bufpage.h.
Referenced by GetVisibilityMapPins(), heap_delete(), heap_insert(), heap_multi_insert(), heap_update(), heapgetpage(), lazy_scan_heap(), RelationGetBufferForTuple(), and visibilitymap_set().
| #define PageIsEmpty | ( | page | ) | (((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData) |
Definition at line 219 of file bufpage.h.
Referenced by _bt_slideleft(), _hash_squeezebucket(), count_nondeletable_pages(), ginHeapTupleFastInsert(), ginRedoUpdateMetapage(), gistfillbuffer(), gistRedoPageUpdateRecord(), lazy_check_needs_freeze(), lazy_scan_heap(), PageIndexTupleDelete(), SpGistGetBuffer(), SpGistNewBuffer(), and spgvacuumpage().
| #define PageIsFull | ( | page | ) | (((PageHeader) (page))->pd_flags & PD_PAGE_FULL) |
Definition at line 356 of file bufpage.h.
Referenced by heap_page_prune(), and heap_page_prune_opt().
| #define PageIsNew | ( | page | ) | (((PageHeader) (page))->pd_upper == 0) |
Definition at line 226 of file bufpage.h.
Referenced by _bt_checkpage(), _bt_getbuf(), _bt_page_recyclable(), _hash_checkpage(), _hash_pageinit(), btvacuumpage(), count_nondeletable_pages(), fsm_readbuf(), GinNewBuffer(), gistcheckpage(), gistNewBuffer(), gistvacuumcleanup(), heap_xlog_newpage(), lazy_check_needs_freeze(), lazy_scan_heap(), log_newpage(), log_newpage_buffer(), PageCalcChecksum16(), PageIsVerified(), PageSetChecksumCopy(), PageSetChecksumInplace(), pgstat_btree_page(), ReadBuffer_common(), RelationGetBufferForTuple(), SpGistGetBuffer(), SpGistNewBuffer(), spgprocesspending(), spgvacuumpage(), vm_readbuf(), XLogReadBufferExtended(), and XLogRecordPageWithFreeSpace().
| #define PageIsPrunable | ( | page, | ||
| oldestxmin | ||||
| ) |
( \
AssertMacro(TransactionIdIsNormal(oldestxmin)), \
TransactionIdIsValid(((PageHeader) (page))->pd_prune_xid) && \
TransactionIdPrecedes(((PageHeader) (page))->pd_prune_xid, oldestxmin) \
)
Definition at line 370 of file bufpage.h.
Referenced by heap_page_prune_opt().
| #define PageSetAllVisible | ( | page | ) | (((PageHeader) (page))->pd_flags |= PD_ALL_VISIBLE) |
Definition at line 365 of file bufpage.h.
Referenced by heap_xlog_visible(), lazy_scan_heap(), and lazy_vacuum_page().
| #define PageSetFull | ( | page | ) | (((PageHeader) (page))->pd_flags |= PD_PAGE_FULL) |
Definition at line 358 of file bufpage.h.
Referenced by heap_update().
| #define PageSetHasFreeLinePointers | ( | page | ) | (((PageHeader) (page))->pd_flags |= PD_HAS_FREE_LINES) |
Definition at line 351 of file bufpage.h.
Referenced by PageRepairFragmentation().
| #define PageSetLSN | ( | page, | ||
| lsn | ||||
| ) | PageXLogRecPtrSet(((PageHeader) (page))->pd_lsn, lsn) |
Definition at line 346 of file bufpage.h.
Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_newroot(), _bt_pagedel(), _bt_restore_meta(), _bt_split(), addLeafTuple(), AlterSequence(), btree_xlog_delete(), btree_xlog_delete_page(), btree_xlog_insert(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_vacuum(), createPostingTree(), do_setval(), doPickSplit(), fill_seq_with_data(), ginbuild(), ginDeletePage(), ginHeapTupleFastInsert(), ginInsertValue(), ginRedoCreateIndex(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoSplit(), ginRedoUpdateMetapage(), ginRedoVacuumPage(), ginUpdateStats(), gistbuild(), gistbulkdelete(), gistplacetopage(), gistRedoClearFollowRight(), gistRedoCreateIndex(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), heap_delete(), heap_inplace_update(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_page_prune(), heap_update(), heap_xlog_clean(), heap_xlog_delete(), heap_xlog_freeze(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_newpage(), heap_xlog_update(), lazy_scan_heap(), lazy_vacuum_page(), log_newpage(), log_newpage_buffer(), MarkBufferDirtyHint(), moveLeafs(), nextval_internal(), RestoreBackupBlockContents(), seq_redo(), shiftList(), spgAddNodeAction(), spgbuild(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoCreateIndex(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), spgSplitNodeAction(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), visibilitymap_set(), writeListPage(), and xlogVacuumPage().
| #define PageSetPageSizeAndVersion | ( | page, | ||
| size, | ||||
| version | ||||
| ) |
( \
AssertMacro(((size) & 0xFF00) == (size)), \
AssertMacro(((version) & 0x00FF) == (version)), \
((PageHeader) (page))->pd_pagesize_version = (size) | (version) \
)
Definition at line 282 of file bufpage.h.
Referenced by PageInit().
| #define PageSetPrunable | ( | page, | ||
| xid | ||||
| ) |
do { \ Assert(TransactionIdIsNormal(xid)); \ if (!TransactionIdIsValid(((PageHeader) (page))->pd_prune_xid) || \ TransactionIdPrecedes(xid, ((PageHeader) (page))->pd_prune_xid)) \ ((PageHeader) (page))->pd_prune_xid = (xid); \ } while (0)
Definition at line 376 of file bufpage.h.
Referenced by heap_delete(), heap_update(), heap_xlog_delete(), and heap_xlog_update().
| #define PageSizeIsValid | ( | pageSize | ) | ((pageSize) == BLCKSZ) |
| #define PD_VALID_FLAG_BITS 0x0007 |
Definition at line 182 of file bufpage.h.
Referenced by PageIsVerified().
| #define PG_PAGE_LAYOUT_VERSION 4 |
Definition at line 196 of file bufpage.h.
Referenced by PageInit().
| #define SizeOfPageHeaderData (offsetof(PageHeaderData, pd_linp)) |
Definition at line 213 of file bufpage.h.
Referenced by _bt_findsplitloc(), calculatePagesPerBuffer(), gistInitBuffering(), heap_page_items(), PageAddItem(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageInit(), PageRepairFragmentation(), and XLogCheckBuffer().
| typedef uint16 LocationIndex |
| typedef PageHeaderData* PageHeader |
| typedef struct PageHeaderData PageHeaderData |
| OffsetNumber PageAddItem | ( | Page | page, | |
| Item | item, | |||
| Size | size, | |||
| OffsetNumber | offsetNumber, | |||
| bool | overwrite, | |||
| bool | is_heap | |||
| ) |
Definition at line 175 of file bufpage.c.
References elog, ereport, errcode(), errmsg(), ItemIdHasStorage, ItemIdIsUsed, ItemIdSetNormal, MAXALIGN, MaxHeapTuplesPerPage, memmove, OffsetNumberIsValid, OffsetNumberNext, PageClearHasFreeLinePointers, PageGetItemId, PageGetMaxOffsetNumber, PageHasFreeLinePointers, PANIC, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, SizeOfPageHeaderData, and WARNING.
Referenced by _bt_newroot(), _bt_pgaddtup(), _bt_restore_page(), _bt_sortaddtup(), _bt_split(), _hash_pgaddtup(), addLeafTuple(), addOrReplaceTuple(), btree_xlog_insert(), btree_xlog_split(), doPickSplit(), entryPlaceToPage(), entrySplitPage(), ginEntryFillRoot(), ginHeapTupleFastInsert(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoSplit(), ginRedoUpdateMetapage(), ginRedoVacuumPage(), ginVacuumEntryPage(), gistfillbuffer(), gistplacetopage(), gistRedoPageUpdateRecord(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), raw_heap_insert(), RelationPutHeapTuple(), seq_redo(), spgAddNodeAction(), SpGistPageAddNewItem(), spgPageIndexMultiDelete(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoSplitTuple(), spgSplitNodeAction(), and writeListPage().
{
PageHeader phdr = (PageHeader) page;
Size alignedSize;
int lower;
int upper;
ItemId itemId;
OffsetNumber limit;
bool needshuffle = false;
/*
* Be wary about corrupted page pointers
*/
if (phdr->pd_lower < SizeOfPageHeaderData ||
phdr->pd_lower > phdr->pd_upper ||
phdr->pd_upper > phdr->pd_special ||
phdr->pd_special > BLCKSZ)
ereport(PANIC,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
/*
* Select offsetNumber to place the new item at
*/
limit = OffsetNumberNext(PageGetMaxOffsetNumber(page));
/* was offsetNumber passed in? */
if (OffsetNumberIsValid(offsetNumber))
{
/* yes, check it */
if (overwrite)
{
if (offsetNumber < limit)
{
itemId = PageGetItemId(phdr, offsetNumber);
if (ItemIdIsUsed(itemId) || ItemIdHasStorage(itemId))
{
elog(WARNING, "will not overwrite a used ItemId");
return InvalidOffsetNumber;
}
}
}
else
{
if (offsetNumber < limit)
needshuffle = true; /* need to move existing linp's */
}
}
else
{
/* offsetNumber was not passed in, so find a free slot */
/* if no free slot, we'll put it at limit (1st open slot) */
if (PageHasFreeLinePointers(phdr))
{
/*
* Look for "recyclable" (unused) ItemId. We check for no storage
* as well, just to be paranoid --- unused items should never have
* storage.
*/
for (offsetNumber = 1; offsetNumber < limit; offsetNumber++)
{
itemId = PageGetItemId(phdr, offsetNumber);
if (!ItemIdIsUsed(itemId) && !ItemIdHasStorage(itemId))
break;
}
if (offsetNumber >= limit)
{
/* the hint is wrong, so reset it */
PageClearHasFreeLinePointers(phdr);
}
}
else
{
/* don't bother searching if hint says there's no free slot */
offsetNumber = limit;
}
}
if (offsetNumber > limit)
{
elog(WARNING, "specified item offset is too large");
return InvalidOffsetNumber;
}
if (is_heap && offsetNumber > MaxHeapTuplesPerPage)
{
elog(WARNING, "can't put more than MaxHeapTuplesPerPage items in a heap page");
return InvalidOffsetNumber;
}
/*
* Compute new lower and upper pointers for page, see if it'll fit.
*
* Note: do arithmetic as signed ints, to avoid mistakes if, say,
* alignedSize > pd_upper.
*/
if (offsetNumber == limit || needshuffle)
lower = phdr->pd_lower + sizeof(ItemIdData);
else
lower = phdr->pd_lower;
alignedSize = MAXALIGN(size);
upper = (int) phdr->pd_upper - (int) alignedSize;
if (lower > upper)
return InvalidOffsetNumber;
/*
* OK to insert the item. First, shuffle the existing pointers if needed.
*/
itemId = PageGetItemId(phdr, offsetNumber);
if (needshuffle)
memmove(itemId + 1, itemId,
(limit - offsetNumber) * sizeof(ItemIdData));
/* set the item pointer */
ItemIdSetNormal(itemId, upper, size);
/* copy the item's data onto the page */
memcpy((char *) page + upper, item, size);
/* adjust page header */
phdr->pd_lower = (LocationIndex) lower;
phdr->pd_upper = (LocationIndex) upper;
return offsetNumber;
}
Definition at line 565 of file bufpage.c.
Referenced by _bt_findsplitloc(), allocNewBuffer(), doPickSplit(), ginHeapTupleFastInsert(), spgAddNodeAction(), SpGistGetBuffer(), SpGistPageAddNewItem(), SpGistSetLastUsedPage(), and writeListPage().
{
int space;
/*
* Use signed arithmetic here so that we behave sensibly if pd_lower >
* pd_upper.
*/
space = (int) ((PageHeader) page)->pd_upper -
(int) ((PageHeader) page)->pd_lower;
if (space < 0)
return 0;
return (Size) space;
}
Definition at line 541 of file bufpage.c.
Referenced by _bt_buildadd(), _bt_findinsertloc(), _bt_insertonpg(), _hash_doinsert(), _hash_splitbucket(), _hash_squeezebucket(), entryIsEnoughSpace(), GetBTPageStatistics(), gistnospace(), PageGetHeapFreeSpace(), pgstat_index_page(), and pgstatindex().
{
int space;
/*
* Use signed arithmetic here so that we behave sensibly if pd_lower >
* pd_upper.
*/
space = (int) ((PageHeader) page)->pd_upper -
(int) ((PageHeader) page)->pd_lower;
if (space < (int) sizeof(ItemIdData))
return 0;
space -= sizeof(ItemIdData);
return (Size) space;
}
Definition at line 598 of file bufpage.c.
References FirstOffsetNumber, ItemIdIsUsed, MaxHeapTuplesPerPage, OffsetNumberNext, PageGetFreeSpace(), PageGetItemId, PageGetMaxOffsetNumber, and PageHasFreeLinePointers.
Referenced by heap_multi_insert(), heap_page_prune_opt(), heap_update(), heap_xlog_clean(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), lazy_scan_heap(), lazy_vacuum_heap(), pgstat_heap(), raw_heap_insert(), and RelationGetBufferForTuple().
{
Size space;
space = PageGetFreeSpace(page);
if (space > 0)
{
OffsetNumber offnum,
nline;
/*
* Are there already MaxHeapTuplesPerPage line pointers in the page?
*/
nline = PageGetMaxOffsetNumber(page);
if (nline >= MaxHeapTuplesPerPage)
{
if (PageHasFreeLinePointers((PageHeader) page))
{
/*
* Since this is just a hint, we must confirm that there is
* indeed a free line pointer
*/
for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
{
ItemId lp = PageGetItemId(page, offnum);
if (!ItemIdIsUsed(lp))
break;
}
if (offnum > nline)
{
/*
* The hint is wrong, but we can't clear it here since we
* don't have the ability to mark the page dirty.
*/
space = 0;
}
}
else
{
/*
* Although the hint might be wrong, PageAddItem will believe
* it anyway, so we must believe it too.
*/
space = 0;
}
}
}
return space;
}
Definition at line 317 of file bufpage.c.
References PageGetPageSize, and palloc().
Referenced by _bt_split().
{
Size pageSize;
Page temp;
pageSize = PageGetPageSize(page);
temp = (Page) palloc(pageSize);
return temp;
}
Definition at line 334 of file bufpage.c.
References PageGetPageSize, and palloc().
Referenced by dataSplitPage(), entrySplitPage(), and ginVacuumEntryPage().
{
Size pageSize;
Page temp;
pageSize = PageGetPageSize(page);
temp = (Page) palloc(pageSize);
memcpy(temp, page, pageSize);
return temp;
}
Definition at line 354 of file bufpage.c.
References PageGetPageSize, PageGetSpecialPointer, PageGetSpecialSize, PageInit(), and palloc().
Referenced by gistplacetopage().
{
Size pageSize;
Page temp;
pageSize = PageGetPageSize(page);
temp = (Page) palloc(pageSize);
PageInit(temp, pageSize, PageGetSpecialSize(page));
memcpy(PageGetSpecialPointer(temp),
PageGetSpecialPointer(page),
PageGetSpecialSize(page));
return temp;
}
| void PageIndexMultiDelete | ( | Page | page, | |
| OffsetNumber * | itemnos, | |||
| int | nitems | |||
| ) |
Definition at line 765 of file bufpage.c.
References itemIdSortData::alignedlen, Assert, elog, ereport, errcode(), errmsg(), ERROR, FirstOffsetNumber, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, itemIdSortData::itemoff, itemoffcompare(), ItemIdData::lp_off, MAXALIGN, memmove, itemIdSortData::offsetindex, OffsetNumberNext, itemIdSortData::olditemid, PageGetItemId, PageGetMaxOffsetNumber, PageIndexTupleDelete(), palloc(), PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, pfree(), qsort, and SizeOfPageHeaderData.
Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _hash_splitbucket(), _hash_squeezebucket(), btree_xlog_delete(), btree_xlog_split(), btree_xlog_vacuum(), ginRedoVacuumPage(), hashbulkdelete(), spgPageIndexMultiDelete(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), vacuumLeafRoot(), and vacuumRedirectAndPlaceholder().
{
PageHeader phdr = (PageHeader) page;
Offset pd_lower = phdr->pd_lower;
Offset pd_upper = phdr->pd_upper;
Offset pd_special = phdr->pd_special;
itemIdSort itemidbase,
itemidptr;
ItemId lp;
int nline,
nused;
int i;
Size totallen;
Offset upper;
Size size;
unsigned offset;
int nextitm;
OffsetNumber offnum;
/*
* If there aren't very many items to delete, then retail
* PageIndexTupleDelete is the best way. Delete the items in reverse
* order so we don't have to think about adjusting item numbers for
* previous deletions.
*
* TODO: tune the magic number here
*/
if (nitems <= 2)
{
while (--nitems >= 0)
PageIndexTupleDelete(page, itemnos[nitems]);
return;
}
/*
* As with PageRepairFragmentation, paranoia seems justified.
*/
if (pd_lower < SizeOfPageHeaderData ||
pd_lower > pd_upper ||
pd_upper > pd_special ||
pd_special > BLCKSZ ||
pd_special != MAXALIGN(pd_special))
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
pd_lower, pd_upper, pd_special)));
/*
* Scan the item pointer array and build a list of just the ones we are
* going to keep. Notice we do not modify the page yet, since we are
* still validity-checking.
*/
nline = PageGetMaxOffsetNumber(page);
itemidbase = (itemIdSort) palloc(sizeof(itemIdSortData) * nline);
itemidptr = itemidbase;
totallen = 0;
nused = 0;
nextitm = 0;
for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
{
lp = PageGetItemId(page, offnum);
Assert(ItemIdHasStorage(lp));
size = ItemIdGetLength(lp);
offset = ItemIdGetOffset(lp);
if (offset < pd_upper ||
(offset + size) > pd_special ||
offset != MAXALIGN(offset))
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("corrupted item pointer: offset = %u, size = %u",
offset, (unsigned int) size)));
if (nextitm < nitems && offnum == itemnos[nextitm])
{
/* skip item to be deleted */
nextitm++;
}
else
{
itemidptr->offsetindex = nused; /* where it will go */
itemidptr->itemoff = offset;
itemidptr->olditemid = *lp;
itemidptr->alignedlen = MAXALIGN(size);
totallen += itemidptr->alignedlen;
itemidptr++;
nused++;
}
}
/* this will catch invalid or out-of-order itemnos[] */
if (nextitm != nitems)
elog(ERROR, "incorrect index offsets supplied");
if (totallen > (Size) (pd_special - pd_lower))
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("corrupted item lengths: total %u, available space %u",
(unsigned int) totallen, pd_special - pd_lower)));
/* sort itemIdSortData array into decreasing itemoff order */
qsort((char *) itemidbase, nused, sizeof(itemIdSortData),
itemoffcompare);
/* compactify page and install new itemids */
upper = pd_special;
for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++)
{
lp = PageGetItemId(page, itemidptr->offsetindex + 1);
upper -= itemidptr->alignedlen;
memmove((char *) page + upper,
(char *) page + itemidptr->itemoff,
itemidptr->alignedlen);
*lp = itemidptr->olditemid;
lp->lp_off = upper;
}
phdr->pd_lower = SizeOfPageHeaderData + nused * sizeof(ItemIdData);
phdr->pd_upper = upper;
pfree(itemidbase);
}
| void PageIndexTupleDelete | ( | Page | page, | |
| OffsetNumber | offset | |||
| ) |
Definition at line 659 of file bufpage.c.
References Assert, elog, ereport, errcode(), errmsg(), ERROR, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdData::lp_off, MAXALIGN, memmove, PageGetItemId, PageGetMaxOffsetNumber, PageIsEmpty, PageHeaderData::pd_linp, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, and SizeOfPageHeaderData.
Referenced by _bt_pagedel(), addLeafTuple(), addOrReplaceTuple(), btree_xlog_delete_page(), entryPreparePage(), ginRedoInsert(), ginVacuumEntryPage(), gistbulkdelete(), gistplacetopage(), gistRedoPageUpdateRecord(), PageIndexMultiDelete(), spgAddNodeAction(), SpGistPageAddNewItem(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoSplitTuple(), and spgSplitNodeAction().
{
PageHeader phdr = (PageHeader) page;
char *addr;
ItemId tup;
Size size;
unsigned offset;
int nbytes;
int offidx;
int nline;
/*
* As with PageRepairFragmentation, paranoia seems justified.
*/
if (phdr->pd_lower < SizeOfPageHeaderData ||
phdr->pd_lower > phdr->pd_upper ||
phdr->pd_upper > phdr->pd_special ||
phdr->pd_special > BLCKSZ)
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
nline = PageGetMaxOffsetNumber(page);
if ((int) offnum <= 0 || (int) offnum > nline)
elog(ERROR, "invalid index offnum: %u", offnum);
/* change offset number to offset index */
offidx = offnum - 1;
tup = PageGetItemId(page, offnum);
Assert(ItemIdHasStorage(tup));
size = ItemIdGetLength(tup);
offset = ItemIdGetOffset(tup);
if (offset < phdr->pd_upper || (offset + size) > phdr->pd_special ||
offset != MAXALIGN(offset) || size != MAXALIGN(size))
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("corrupted item pointer: offset = %u, size = %u",
offset, (unsigned int) size)));
/*
* First, we want to get rid of the pd_linp entry for the index tuple. We
* copy all subsequent linp's back one slot in the array. We don't use
* PageGetItemId, because we are manipulating the _array_, not individual
* linp's.
*/
nbytes = phdr->pd_lower -
((char *) &phdr->pd_linp[offidx + 1] - (char *) phdr);
if (nbytes > 0)
memmove((char *) &(phdr->pd_linp[offidx]),
(char *) &(phdr->pd_linp[offidx + 1]),
nbytes);
/*
* Now move everything between the old upper bound (beginning of tuple
* space) and the beginning of the deleted tuple forward, so that space in
* the middle of the page is left free. If we've just deleted the tuple
* at the beginning of tuple space, then there's no need to do the copy
* (and bcopy on some architectures SEGV's if asked to move zero bytes).
*/
/* beginning of tuple space */
addr = (char *) page + phdr->pd_upper;
if (offset > phdr->pd_upper)
memmove(addr + size, addr, (int) (offset - phdr->pd_upper));
/* adjust free space boundary pointers */
phdr->pd_upper += size;
phdr->pd_lower -= sizeof(ItemIdData);
/*
* Finally, we need to adjust the linp entries that remain.
*
* Anything that used to be before the deleted tuple's data was moved
* forward by the size of the deleted tuple.
*/
if (!PageIsEmpty(page))
{
int i;
nline--; /* there's one less than when we started */
for (i = 1; i <= nline; i++)
{
ItemId ii = PageGetItemId(phdr, i);
Assert(ItemIdHasStorage(ii));
if (ItemIdGetOffset(ii) <= offset)
ii->lp_off += size;
}
}
}
Definition at line 40 of file bufpage.c.
References Assert, MAXALIGN, MemSet, PageSetPageSizeAndVersion, PageHeaderData::pd_flags, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, PG_PAGE_LAYOUT_VERSION, and SizeOfPageHeaderData.
Referenced by _bt_pageinit(), _hash_pageinit(), fill_seq_with_data(), fsm_extend(), fsm_readbuf(), GinInitPage(), GISTInitBuffer(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), lazy_scan_heap(), PageGetTempPageCopySpecial(), raw_heap_insert(), RelationGetBufferForTuple(), seq_redo(), SetMatViewToPopulated(), SpGistInitPage(), vm_extend(), vm_readbuf(), and XLogRecordPageWithFreeSpace().
{
PageHeader p = (PageHeader) page;
specialSize = MAXALIGN(specialSize);
Assert(pageSize == BLCKSZ);
Assert(pageSize > specialSize + SizeOfPageHeaderData);
/* Make sure all fields of page are zero, as well as unused space */
MemSet(p, 0, pageSize);
p->pd_flags = 0;
p->pd_lower = SizeOfPageHeaderData;
p->pd_upper = pageSize - specialSize;
p->pd_special = pageSize - specialSize;
PageSetPageSizeAndVersion(page, pageSize, PG_PAGE_LAYOUT_VERSION);
/* p->pd_prune_xid = InvalidTransactionId; done by above MemSet */
}
| bool PageIsVerified | ( | Page | page, | |
| BlockNumber | blkno | |||
| ) |
Definition at line 80 of file bufpage.c.
References DataChecksumsEnabled(), ereport, errmsg(), i, ignore_checksum_failure, MAXALIGN, PageCalcChecksum16(), PageIsNew, PageHeaderData::pd_checksum, PageHeaderData::pd_flags, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, PD_VALID_FLAG_BITS, and WARNING.
Referenced by copy_relation_data(), and ReadBuffer_common().
{
PageHeader p = (PageHeader) page;
char *pagebytes;
int i;
bool checksum_failure = false;
bool header_sane = false;
bool all_zeroes = false;
uint16 checksum = 0;
/*
* Don't verify page data unless the page passes basic non-zero test
*/
if (!PageIsNew(page))
{
if (DataChecksumsEnabled())
{
checksum = PageCalcChecksum16(page, blkno);
if (checksum != p->pd_checksum)
checksum_failure = true;
}
/*
* The following checks don't prove the header is correct,
* only that it looks sane enough to allow into the buffer pool.
* Later usage of the block can still reveal problems,
* which is why we offer the checksum option.
*/
if ((p->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
p->pd_lower <= p->pd_upper &&
p->pd_upper <= p->pd_special &&
p->pd_special <= BLCKSZ &&
p->pd_special == MAXALIGN(p->pd_special))
header_sane = true;
if (header_sane && !checksum_failure)
return true;
}
/* Check all-zeroes case */
all_zeroes = true;
pagebytes = (char *) page;
for (i = 0; i < BLCKSZ; i++)
{
if (pagebytes[i] != 0)
{
all_zeroes = false;
break;
}
}
if (all_zeroes)
return true;
/*
* Throw a WARNING if the checksum fails, but only after we've checked for
* the all-zeroes case.
*/
if (checksum_failure)
{
ereport(WARNING,
(ERRCODE_DATA_CORRUPTED,
errmsg("page verification failed, calculated checksum %u but expected %u",
checksum, p->pd_checksum)));
if (header_sane && ignore_checksum_failure)
return true;
}
return false;
}
| void PageRepairFragmentation | ( | Page | page | ) |
Definition at line 417 of file bufpage.c.
References itemIdSortData::alignedlen, ereport, errcode(), errmsg(), ERROR, FirstOffsetNumber, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdIsUsed, ItemIdSetUnused, itemIdSortData::itemoff, itemoffcompare(), ItemIdData::lp_off, MAXALIGN, memmove, itemIdSortData::offsetindex, PageClearHasFreeLinePointers, PageGetItemId, PageGetMaxOffsetNumber, PageSetHasFreeLinePointers, palloc(), pfree(), qsort, and SizeOfPageHeaderData.
Referenced by heap_page_prune_execute(), and lazy_vacuum_page().
{
Offset pd_lower = ((PageHeader) page)->pd_lower;
Offset pd_upper = ((PageHeader) page)->pd_upper;
Offset pd_special = ((PageHeader) page)->pd_special;
itemIdSort itemidbase,
itemidptr;
ItemId lp;
int nline,
nstorage,
nunused;
int i;
Size totallen;
Offset upper;
/*
* It's worth the trouble to be more paranoid here than in most places,
* because we are about to reshuffle data in (what is usually) a shared
* disk buffer. If we aren't careful then corrupted pointers, lengths,
* etc could cause us to clobber adjacent disk buffers, spreading the data
* loss further. So, check everything.
*/
if (pd_lower < SizeOfPageHeaderData ||
pd_lower > pd_upper ||
pd_upper > pd_special ||
pd_special > BLCKSZ ||
pd_special != MAXALIGN(pd_special))
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
pd_lower, pd_upper, pd_special)));
nline = PageGetMaxOffsetNumber(page);
nunused = nstorage = 0;
for (i = FirstOffsetNumber; i <= nline; i++)
{
lp = PageGetItemId(page, i);
if (ItemIdIsUsed(lp))
{
if (ItemIdHasStorage(lp))
nstorage++;
}
else
{
/* Unused entries should have lp_len = 0, but make sure */
ItemIdSetUnused(lp);
nunused++;
}
}
if (nstorage == 0)
{
/* Page is completely empty, so just reset it quickly */
((PageHeader) page)->pd_upper = pd_special;
}
else
{ /* nstorage != 0 */
/* Need to compact the page the hard way */
itemidbase = (itemIdSort) palloc(sizeof(itemIdSortData) * nstorage);
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),
errmsg("corrupted item lengths: total %u, available space %u",
(unsigned int) totallen, pd_special - pd_lower)));
/* sort itemIdSortData array into decreasing itemoff order */
qsort((char *) itemidbase, nstorage, sizeof(itemIdSortData),
itemoffcompare);
/* compactify page */
upper = pd_special;
for (i = 0, itemidptr = itemidbase; i < nstorage; i++, itemidptr++)
{
lp = PageGetItemId(page, itemidptr->offsetindex + 1);
upper -= itemidptr->alignedlen;
memmove((char *) page + upper,
(char *) page + itemidptr->itemoff,
itemidptr->alignedlen);
lp->lp_off = upper;
}
((PageHeader) page)->pd_upper = upper;
pfree(itemidbase);
}
/* Set hint bit for PageAddItem */
if (nunused > 0)
PageSetHasFreeLinePointers(page);
else
PageClearHasFreeLinePointers(page);
}
Definition at line 376 of file bufpage.c.
References PageGetPageSize, and pfree().
Referenced by _bt_split(), ginbulkdelete(), ginInsertValue(), and gistplacetopage().
{
Size pageSize;
pageSize = PageGetPageSize(tempPage);
memcpy((char *) oldPage, (char *) tempPage, pageSize);
pfree(tempPage);
}
| char* PageSetChecksumCopy | ( | Page | page, | |
| BlockNumber | blkno | |||
| ) |
Definition at line 901 of file bufpage.c.
References DataChecksumsEnabled(), pageCopy, PageIsNew, and PageSetChecksumInplace().
Referenced by FlushBuffer().
{
if (PageIsNew(page) || !DataChecksumsEnabled())
return (char *) page;
/*
* We make a copy iff we need to calculate a checksum because other
* backends may set hint bits on this page while we write, which
* would mean the checksum differs from the page contents. It doesn't
* matter if we include or exclude hints during the copy, as long
* as we write a valid page and associated checksum.
*/
memcpy((char *) pageCopy, (char *) page, BLCKSZ);
PageSetChecksumInplace(pageCopy, blkno);
return (char *) pageCopy;
}
| void PageSetChecksumInplace | ( | Page | page, | |
| BlockNumber | blkno | |||
| ) |
Definition at line 926 of file bufpage.c.
References DataChecksumsEnabled(), PageCalcChecksum16(), PageIsNew, and PageHeaderData::pd_checksum.
Referenced by _bt_blwritepage(), btbuildempty(), copy_relation_data(), end_heap_rewrite(), FlushRelationBuffers(), fsm_extend(), LocalBufferAlloc(), PageSetChecksumCopy(), raw_heap_insert(), SetMatViewToPopulated(), spgbuildempty(), and vm_extend().
{
if (PageIsNew(page))
return;
if (DataChecksumsEnabled())
{
PageHeader p = (PageHeader) page;
p->pd_checksum = PageCalcChecksum16(page, blkno);
}
return;
}
1.7.1