66 elog(
PANIC,
"failed to add tuple to page");
145 bool need_to_pin_buffer1;
146 bool need_to_pin_buffer2;
147 bool released_locks =
false;
157 Buffer *tmpvmbuf = vmbuffer1;
161 vmbuffer1 = vmbuffer2;
165 vmbuffer2 = tmpvmbuf;
180 if (!need_to_pin_buffer1 && !need_to_pin_buffer2)
184 released_locks =
true;
190 if (need_to_pin_buffer1)
192 if (need_to_pin_buffer2)
207 || (need_to_pin_buffer1 && need_to_pin_buffer2))
211 return released_locks;
240 int num_pages,
bool use_fsm,
bool *did_unlock)
242 #define MAX_BUFFERS_TO_EXTEND_BY 64
254 if (bistate == NULL && !use_fsm)
270 extend_by_pages = num_pages;
284 extend_by_pages += extend_by_pages * waitcount;
303 if (num_pages > 1 && bistate == NULL)
304 not_in_fsm_pages = 1;
306 not_in_fsm_pages = num_pages;
330 buffer = victim_buffers[0];
331 last_block = first_block + (extend_by_pages - 1);
342 elog(
ERROR,
"page %u of relation \"%s\" should be empty but is not",
354 if (use_fsm && not_in_fsm_pages < extend_by_pages)
367 for (
uint32 i = 1;
i < extend_by_pages;
i++)
376 if (use_fsm &&
i >= not_in_fsm_pages)
385 if (use_fsm && not_in_fsm_pages < extend_by_pages)
387 BlockNumber first_fsm_block = first_block + not_in_fsm_pages;
398 if (extend_by_pages > 1)
415 #undef MAX_BUFFERS_TO_EXTEND_BY
493 Size nearlyEmptyFreeSpace,
499 bool unlockedTargetBuffer;
516 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
517 errmsg(
"row is too big: size %zu, maximum size %zu",
532 if (
len + saveFreeSpace > nearlyEmptyFreeSpace)
533 targetFreeSpace =
Max(
len, nearlyEmptyFreeSpace);
535 targetFreeSpace =
len + saveFreeSpace;
579 targetBlock = nblocks - 1;
614 else if (otherBlock == targetBlock)
617 buffer = otherBuffer;
622 else if (otherBlock < targetBlock)
663 targetBlock, otherBlock, vmbuffer,
685 if (targetFreeSpace <= pageFreeSpace)
701 else if (otherBlock != targetBlock)
750 &unlockedTargetBuffer);
766 if (!unlockedTargetBuffer)
768 unlockedTargetBuffer =
true;
781 recheckVmPins =
false;
782 if (unlockedTargetBuffer)
788 recheckVmPins =
true;
805 Assert(otherBuffer != buffer);
806 Assert(targetBlock > otherBlock);
810 unlockedTargetBuffer =
true;
815 recheckVmPins =
true;
829 otherBlock, targetBlock, vmbuffer_other,
831 unlockedTargetBuffer =
true;
842 if (
len > pageFreeSpace)
844 if (unlockedTargetBuffer)
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
void IncrBufferRefCount(Buffer buffer)
BlockNumber BufferGetBlockNumber(Buffer buffer)
bool ConditionalLockBuffer(Buffer buffer)
void ReleaseBuffer(Buffer buffer)
void UnlockReleaseBuffer(Buffer buffer)
void MarkBufferDirty(Buffer buffer)
BlockNumber ExtendBufferedRelBy(ExtendBufferedWhat eb, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, Buffer *buffers, uint32 *extended_by)
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)
elog(ERROR, "%s: %s", p2, msg)
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)
Assert(fmt[strlen(fmt) - 1] !='\n')
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
bool visibilitymap_pin_ok(BlockNumber heapBlk, Buffer vmbuf)
void visibilitymap_pin(Relation rel, BlockNumber heapBlk, Buffer *vmbuf)
static StringInfoData tmpbuf