65 elog(
PANIC,
"failed to add tuple to page");
144 bool need_to_pin_buffer1;
145 bool need_to_pin_buffer2;
146 bool released_locks =
false;
156 Buffer *tmpvmbuf = vmbuffer1;
160 vmbuffer1 = vmbuffer2;
164 vmbuffer2 = tmpvmbuf;
179 if (!need_to_pin_buffer1 && !need_to_pin_buffer2)
183 released_locks =
true;
189 if (need_to_pin_buffer1)
191 if (need_to_pin_buffer2)
206 || (need_to_pin_buffer1 && need_to_pin_buffer2))
210 return released_locks;
239 int num_pages,
bool use_fsm,
bool *did_unlock)
241 #define MAX_BUFFERS_TO_EXTEND_BY 64
253 if (bistate == NULL && !use_fsm)
269 extend_by_pages = num_pages;
283 extend_by_pages += extend_by_pages * waitcount;
320 if (num_pages > 1 && bistate == NULL)
321 not_in_fsm_pages = 1;
323 not_in_fsm_pages = num_pages;
347 buffer = victim_buffers[0];
348 last_block = first_block + (extend_by_pages - 1);
359 elog(
ERROR,
"page %u of relation \"%s\" should be empty but is not",
371 if (use_fsm && not_in_fsm_pages < extend_by_pages)
384 for (
uint32 i = 1;
i < extend_by_pages;
i++)
393 if (use_fsm &&
i >= not_in_fsm_pages)
402 if (use_fsm && not_in_fsm_pages < extend_by_pages)
404 BlockNumber first_fsm_block = first_block + not_in_fsm_pages;
415 if (extend_by_pages > 1)
433 #undef MAX_BUFFERS_TO_EXTEND_BY
511 Size nearlyEmptyFreeSpace,
517 bool unlockedTargetBuffer;
534 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
535 errmsg(
"row is too big: size %zu, maximum size %zu",
550 if (
len + saveFreeSpace > nearlyEmptyFreeSpace)
551 targetFreeSpace =
Max(
len, nearlyEmptyFreeSpace);
553 targetFreeSpace =
len + saveFreeSpace;
597 targetBlock = nblocks - 1;
632 else if (otherBlock == targetBlock)
635 buffer = otherBuffer;
640 else if (otherBlock < targetBlock)
681 targetBlock, otherBlock, vmbuffer,
703 if (targetFreeSpace <= pageFreeSpace)
719 else if (otherBlock != targetBlock)
768 &unlockedTargetBuffer);
784 if (!unlockedTargetBuffer)
786 unlockedTargetBuffer =
true;
799 recheckVmPins =
false;
800 if (unlockedTargetBuffer)
806 recheckVmPins =
true;
823 Assert(otherBuffer != buffer);
824 Assert(targetBlock > otherBlock);
828 unlockedTargetBuffer =
true;
833 recheckVmPins =
true;
847 otherBlock, targetBlock, vmbuffer_other,
849 unlockedTargetBuffer =
true;
860 if (
len > pageFreeSpace)
862 if (unlockedTargetBuffer)
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
void IncrBufferRefCount(Buffer buffer)
BlockNumber BufferGetBlockNumber(Buffer buffer)
BlockNumber ExtendBufferedRelBy(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, Buffer *buffers, uint32 *extended_by)
bool ConditionalLockBuffer(Buffer buffer)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
void LockBuffer(Buffer buffer, int mode)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
#define BUFFER_LOCK_UNLOCK
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static Size BufferGetPageSize(Buffer buffer)
#define BUFFER_LOCK_EXCLUSIVE
@ RBM_ZERO_AND_CLEANUP_LOCK
static bool BufferIsValid(Buffer bufnum)
Size PageGetHeapFreeSpace(Page page)
void PageInit(Page page, Size pageSize, Size specialSize)
static Item PageGetItem(Page page, ItemId itemId)
#define SizeOfPageHeaderData
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static bool PageIsNew(Page page)
static bool PageIsAllVisible(Page page)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
#define Assert(condition)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void FreeSpaceMapVacuumRange(Relation rel, BlockNumber start, BlockNumber end)
BlockNumber RecordAndGetPageWithFreeSpace(Relation rel, BlockNumber oldPage, Size oldSpaceAvail, Size spaceNeeded)
void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail)
BlockNumber GetPageWithFreeSpace(Relation rel, Size spaceNeeded)
#define HEAP_INSERT_SKIP_FSM
#define HEAP_INSERT_FROZEN
void RelationPutHeapTuple(Relation relation, Buffer buffer, HeapTuple tuple, bool token)
static Buffer RelationAddBlocks(Relation relation, BulkInsertState bistate, int num_pages, bool use_fsm, bool *did_unlock)
static bool GetVisibilityMapPins(Relation relation, Buffer buffer1, Buffer buffer2, BlockNumber block1, BlockNumber block2, Buffer *vmbuffer1, Buffer *vmbuffer2)
#define MAX_BUFFERS_TO_EXTEND_BY
Buffer RelationGetBufferForTuple(Relation relation, Size len, Buffer otherBuffer, int options, BulkInsertState bistate, Buffer *vmbuffer, Buffer *vmbuffer_other, int num_pages)
static Buffer ReadBufferBI(Relation relation, BlockNumber targetBlock, ReadBufferMode mode, BulkInsertState bistate)
HeapTupleHeaderData * HeapTupleHeader
#define HEAP_XMAX_IS_MULTI
#define HEAP_XMAX_COMMITTED
#define MaxHeapTuplesPerPage
#define HeapTupleHeaderIsSpeculative(tup)
struct ItemIdData ItemIdData
static void ItemPointerSet(ItemPointerData *pointer, BlockNumber blockNumber, OffsetNumber offNum)
int RelationExtensionLockWaiterCount(Relation relation)
#define InvalidOffsetNumber
static PgChecksumMode mode
#define RELATION_IS_LOCAL(relation)
#define RelationGetTargetPageFreeSpace(relation, defaultff)
#define RelationGetRelationName(relation)
#define RelationGetTargetBlock(relation)
#define RelationSetTargetBlock(relation, targblock)
#define HEAP_DEFAULT_FILLFACTOR
BufferAccessStrategy strategy
uint32 already_extended_by
bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf)
void visibilitymap_pin(Relation rel, BlockNumber heapBlk, Buffer *vmbuf)
static StringInfoData tmpbuf