42#define LocalBufHdrGetBlock(bufHdr) \
43 LocalBufferBlockPointers[-((bufHdr)->buf_id + 2)]
154 bufid = -victim_buffer - 1;
160 elog(
ERROR,
"local buffer hash table corrupted");
166 bufHdr->
tag = newTag;
195 elog(
ERROR,
"failed to start write IO on local buffer");
270 else if (--trycounter == 0)
272 (
errcode(ERRCODE_INSUFFICIENT_RESOURCES),
273 errmsg(
"no empty local buffer available")));
327 if (*additional_pins <= 1)
337 if (*additional_pins >= max_pins)
338 *additional_pins = max_pins;
373 MemSet(buf_block, 0, BLCKSZ);
385 Assert(first_block <= extend_upto);
387 Assert((
uint64) first_block + extend_by <= extend_upto);
393 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
394 errmsg(
"cannot extend relation %s beyond %u blocks",
406 victim_buf_id = -buffers[
i] - 1;
434 buf_state &= ~BM_VALID;
446 victim_buf_hdr->
tag = tag;
452 hresult->
id = victim_buf_id;
464 io_start, 1, extend_by * BLCKSZ);
479 *extended_by = extend_by;
500 fprintf(stderr,
"LB DIRTY %d\n", buffer);
571 buf_state &= ~BM_IO_ERROR;
574 buf_state &= ~BM_DIRTY;
584 buf_state |= set_flag_bits;
608 int bufid = -buffer - 1;
632 if (check_unreferenced &&
634 elog(
ERROR,
"block %u of %s is still referenced (local %d)",
645 elog(
ERROR,
"local buffer hash table corrupted");
648 buf_state &= ~BUF_FLAG_MASK;
649 buf_state &= ~BUF_USAGECOUNT_MASK;
682 for (
j = 0;
j < nforks;
j++)
744 (
errcode(ERRCODE_INVALID_TRANSACTION_STATE),
745 errmsg(
"cannot access temporary tables during a parallel operation")));
753 (
errcode(ERRCODE_OUT_OF_MEMORY),
754 errmsg(
"out of memory")));
759 for (
i = 0;
i < nbufs;
i++)
769 buf->buf_id = -
i - 2;
791 elog(
ERROR,
"could not initialize local buffer hash table");
809 int bufid = -buffer - 1;
817 if (adjust_usagecount &&
850 int buffid = -buffer - 1;
885 GUC_check_errdetail(
"\"temp_buffers\" cannot be changed after any temporary tables have been accessed in the session.");
903 static char *cur_block = NULL;
904 static int next_buf_in_block = 0;
905 static int num_bufs_in_block = 0;
906 static int total_bufs_allocated = 0;
913 if (next_buf_in_block >= num_bufs_in_block)
923 if (LocalBufferContext == NULL)
926 "LocalBufferContext",
930 num_bufs =
Max(num_bufs_in_block * 2, 16);
942 next_buf_in_block = 0;
943 num_bufs_in_block = num_bufs;
947 this_buf = cur_block + next_buf_in_block * BLCKSZ;
949 total_bufs_allocated++;
961 return (
Block) this_buf;
972#ifdef USE_ASSERT_CHECKING
975 int RefCountErrors = 0;
986 elog(
WARNING,
"local buffer refcount leak: %s", s);
992 Assert(RefCountErrors == 0);
bool pgaio_wref_valid(PgAioWaitRef *iow)
void pgaio_wref_clear(PgAioWaitRef *iow)
void pgaio_wref_wait(PgAioWaitRef *iow)
static void pg_atomic_unlocked_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
#define InvalidBlockNumber
#define BufferIsLocal(buffer)
#define BM_MAX_USAGE_COUNT
static void InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator, ForkNumber forkNum, BlockNumber blockNum)
#define BUF_USAGECOUNT_MASK
static ForkNumber BufTagGetForkNum(const BufferTag *tag)
static bool BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2)
static bool BufTagMatchesRelFileLocator(const BufferTag *tag, const RelFileLocator *rlocator)
#define BUF_STATE_GET_USAGECOUNT(state)
static void ClearBufferTag(BufferTag *tag)
static void ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
static void ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
#define BUF_USAGECOUNT_ONE
#define BUF_STATE_GET_REFCOUNT(state)
static RelFileLocator BufTagGetRelFileLocator(const BufferTag *tag)
static BufferDesc * GetLocalBufferDescriptor(uint32 id)
static Buffer BufferDescriptorGetBuffer(const BufferDesc *bdesc)
char * DebugPrintBufferRefcount(Buffer buffer)
#define BMR_GET_SMGR(bmr)
void PageSetChecksumInplace(Page page, BlockNumber blkno)
#define MemSet(start, val, len)
#define fprintf(file, fmt, msg)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define GUC_check_errdetail
Assert(PointerIsAligned(start, uint64))
#define IsParallelWorker()
BufferUsage pgBufferUsage
void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln)
void UnpinLocalBuffer(Buffer buffer)
bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait)
static HTAB * LocalBufHash
static int NLocalPinnedBuffers
void AtEOXact_LocalBuffers(bool isCommit)
#define LocalBufHdrGetBlock(bufHdr)
static void CheckForLocalBufferLeaks(void)
uint32 GetAdditionalLocalPinLimit(void)
static Block GetLocalBufferStorage(void)
static int nextFreeLocalBufId
bool check_temp_buffers(int *newval, void **extra, GucSource source)
void AtProcExit_LocalBuffers(void)
bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
static void InitLocalBuffers(void)
void LimitAdditionalLocalPins(uint32 *additional_pins)
uint32 GetLocalPinLimit(void)
static Buffer GetLocalVictimBuffer(void)
void MarkLocalBufferDirty(Buffer buffer)
void DropRelationAllLocalBuffers(RelFileLocator rlocator)
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint32 set_flag_bits, bool release_aio)
void InvalidateLocalBuffer(BufferDesc *bufHdr, bool check_unreferenced)
PrefetchBufferResult PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
BlockNumber ExtendBufferedRelLocal(BufferManagerRelation bmr, ForkNumber fork, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
Block * LocalBufferBlockPointers
void UnpinLocalBufferNoOwner(Buffer buffer)
void DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock)
BufferDesc * LocalBufferDescriptors
BufferDesc * LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum, bool *foundPtr)
void pfree(void *pointer)
void * MemoryContextAllocAligned(MemoryContext context, Size size, Size alignto, int flags)
MemoryContext TopMemoryContext
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
static rewind_source * source
instr_time pgstat_prepare_io_time(bool track_io_guc)
void pgstat_count_io_op(IOObject io_object, IOContext io_context, IOOp io_op, uint32 cnt, uint64 bytes)
void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time start_time, uint32 cnt, uint64 bytes)
#define relpath(rlocator, forknum)
#define relpathbackend(rlocator, backend, forknum)
ResourceOwner CurrentResourceOwner
void ResourceOwnerEnlarge(ResourceOwner owner)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
void smgrzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skipFsync)
bool smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks)
static void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
RelFileLocatorBackend smgr_rlocator