43#ifdef USE_ASSERT_CHECKING
44#include "catalog/pg_tablespace_d.h"
73#define BufHdrGetBlock(bufHdr) ((Block) (BufferBlocks + ((Size) (bufHdr)->buf_id) * BLCKSZ))
74#define BufferGetLSN(bufHdr) (PageGetLSN(BufHdrGetBlock(bufHdr)))
77#define LocalBufHdrGetBlock(bufHdr) \
78 LocalBufferBlockPointers[-((bufHdr)->buf_id + 2)]
81#define BUF_WRITTEN 0x01
82#define BUF_REUSABLE 0x02
84#define RELS_BSEARCH_THRESHOLD 20
92#define BUF_DROP_FULL_SCAN_THRESHOLD (uint64) (NBuffers / 32)
129#define REFCOUNT_ARRAY_ENTRIES 8
543 return ref->data.refcount;
589#define BufferIsPinned(bufnum) \
591 !BufferIsValid(bufnum) ? \
594 BufferIsLocal(bufnum) ? \
595 (LocalRefCount[-(bufnum) - 1] > 0) \
597 (GetPrivateRefCount(bufnum) > 0) \
655#ifdef USE_ASSERT_CHECKING
783 errmsg(
"cannot access temporary tables of other sessions")));
818 int b = -recent_buffer - 1;
924 errmsg(
"cannot access temporary tables of other sessions")));
931 forkNum, blockNum,
mode, strategy);
1008 if (
bmr.relpersistence ==
'\0')
1009 bmr.relpersistence =
bmr.rel->rd_rel->relpersistence;
1041 if (
bmr.relpersistence ==
'\0')
1042 bmr.relpersistence =
bmr.rel->rd_rel->relpersistence;
1324 persistence = rel->
rd_rel->relpersistence;
1334 forkNum, blockNum, strategy, &found);
1347 operation.
smgr = smgr;
1348 operation.
rel = rel;
1440#ifdef USE_ASSERT_CHECKING
1481 elog(
DEBUG2,
"limiting nblocks at %u from %u to %u",
1493 operation->
flags = flags;
1530 operation->
nblocks = *nblocks;
1629#ifdef USE_ASSERT_CHECKING
1761 elog(
ERROR,
"waiting for read operation that didn't read");
1867 int flags = operation->
flags;
2018 for (
int i = nblocks_done + 1;
i < operation->
nblocks;
i++)
2055 blocknum + nblocks_done,
2329 elog(
ERROR,
"buffer is pinned in InvalidateBuffer");
2523 if (strategy !=
NULL)
2584#ifdef USE_ASSERT_CHECKING
2649 limit =
Max(limit, 1);
2796 errmsg(
"cannot extend relation %s beyond %u blocks",
2860 (
errmsg(
"unexpected data beyond EOF in block %u of relation \"%s\"",
3134 if (
bufHdr->tag.blockNum == blockNum &&
3144 if (
bufHdr->tag.blockNum == blockNum &&
3216 if (strategy ==
NULL)
3262 ref->data.refcount++;
3342 int wait_backend_pgprocno =
buf->wait_backend_pgprocno;
3380 ref->data.refcount--;
3381 if (
ref->data.refcount == 0)
3421 ref->data.refcount++;
3438#define ST_SORT sort_checkpoint_bufferids
3439#define ST_ELEMENT_TYPE CkptSortItem
3440#define ST_COMPARE(a, b) ckpt_buforder_comparator(a, b)
3441#define ST_SCOPE static
3497 for (buf_id = 0; buf_id <
NBuffers; buf_id++)
3531 if (num_to_scan == 0)
3554 for (
i = 0;
i < num_to_scan;
i++)
3583 memset(s, 0,
sizeof(*s));
3820 elog(
DEBUG2,
"bgwriter ahead: bgw %u-%u strategy %u-%u delta=%ld lap=%d",
3832 elog(
DEBUG2,
"bgwriter ahead: bgw %u-%u strategy %u-%u delta=%ld lap=%d",
3845 elog(
DEBUG2,
"bgwriter behind: bgw %u-%u strategy %u-%u delta=%ld",
3862 elog(
DEBUG2,
"bgwriter initializing: strategy %u-%u",
3937 elog(
DEBUG2,
"bgwriter: alloc_est=%d too small, using min=%d + reusable_est=%d",
3983 elog(
DEBUG1,
"bgwriter: recent_alloc=%u smoothed=%.2f delta=%ld ahead=%d density=%.2f reusable_est=%d upcoming_est=%d scanned=%d wrote=%d reusable=%d",
4008 elog(
DEBUG2,
"bgwriter: cleaner density alloc=%u scan=%ld density=%.2f new smoothed=%.2f",
4175#ifdef USE_ASSERT_CHECKING
4215#ifdef USE_ASSERT_CHECKING
4324 result =
psprintf(
"[%03d] (rel=%s, blockNum=%u, flags=0x%" PRIx64 ", refcount=%u %d)",
4368 return bufHdr->tag.blockNum;
4446 reln->smgr_rlocator.locator.spcOid,
4447 reln->smgr_rlocator.locator.dbOid,
4448 reln->smgr_rlocator.locator.relNumber);
4540 reln->smgr_rlocator.locator.spcOid,
4541 reln->smgr_rlocator.locator.dbOid,
4542 reln->smgr_rlocator.locator.relNumber);
4849 for (
i = 0;
i < n && cached;
i++)
4876 for (
i = 0;
i < n;
i++)
4897 for (
i = 0;
i < n;
i++)
4898 locators[
i] = rels[
i]->smgr_rlocator.locator;
4926 for (
j = 0;
j < n;
j++)
4946 if (rlocator ==
NULL)
5047 if (
bufHdr->tag.dbOid != dbid)
5051 if (
bufHdr->tag.dbOid == dbid)
5177 for (
i = 0;
i < nrels;
i++)
5210 for (
j = 0;
j < nrels;
j++)
5328 for (blkno = 0; blkno < nblocks; blkno++)
5380 char relpersistence;
5385 relpersistence = permanent ?
5456 if (
bufHdr->tag.dbOid != dbid)
5464 if (
bufHdr->tag.dbOid == dbid &&
5545 ref->data.refcount++;
5601 bool delayChkptFlags =
false;
5653 delayChkptFlags =
true;
5686 if (delayChkptFlags)
6018 elog(
PANIC,
"cannot wait without a PGPROC structure");
6021 elog(
PANIC,
"queueing for lock while waiting on another one");
6489 elog(
ERROR,
"incorrect local pin count: %d",
6495 elog(
ERROR,
"incorrect local pin count: %d",
6580 elog(
ERROR,
"multiple backends attempting to wait for pincount 1");
7023 errmsg(
"could not write block %u of %s",
7027 errdetail(
"Multiple failures --- write error might be permanent.")));
7044 errcontext(
"writing block %u of relation \"%s\"",
7059 errcontext(
"writing block %u of relation \"%s\"",
7075 if (
n1.relNumber <
n2.relNumber)
7077 else if (
n1.relNumber >
n2.relNumber)
7080 if (
n1.dbOid <
n2.dbOid)
7082 else if (
n1.dbOid >
n2.dbOid)
7085 if (
n1.spcOid <
n2.spcOid)
7087 else if (
n1.spcOid >
n2.spcOid)
7188 if (
ba->blockNum <
bb->blockNum)
7190 if (
ba->blockNum >
bb->blockNum)
7206 if (
a->tsId <
b->tsId)
7208 else if (
a->tsId >
b->tsId)
7211 if (
a->relNumber <
b->relNumber)
7213 else if (
a->relNumber >
b->relNumber)
7216 else if (
a->forkNum <
b->forkNum)
7218 else if (
a->forkNum >
b->forkNum)
7221 else if (
a->blockNum <
b->blockNum)
7223 else if (
a->blockNum >
b->blockNum)
7240 if (
sa->progress <
sb->progress)
7242 else if (
sa->progress ==
sb->progress)
7292 pending->
tag = *tag;
7304#define ST_SORT sort_pending_writebacks
7305#define ST_ELEMENT_TYPE PendingWriteback
7306#define ST_COMPARE(a, b) buffertag_comparator(&a->tag, &b->tag)
7307#define ST_SCOPE static
7371 if (
cur->tag.blockNum ==
next->tag.blockNum)
7375 if (
cur->tag.blockNum + 1 !=
next->tag.blockNum)
7586 (*buffers_evicted)++;
7591 (*buffers_flushed)++;
7648 (*buffers_evicted)++;
7653 (*buffers_flushed)++;
7666 bool result =
false;
7793 (*buffers_dirtied)++;
7795 (*buffers_already_dirty)++;
7837 (*buffers_dirtied)++;
7839 (*buffers_already_dirty)++;
7863 uint8 handle_data_len;
7872 for (
int i = 0;
i < handle_data_len;
i++)
7977#define READV_COUNT_BITS 7
7978#define READV_COUNT_MASK ((1 << READV_COUNT_BITS) - 1)
8027 "PG_IOV_MAX is bigger than reserved space for error data");
8029 "PGAIO_RESULT_ERROR_BITS is insufficient for buffer_readv");
8074#ifdef USE_ASSERT_CHECKING
8095#undef READV_COUNT_BITS
8096#undef READV_COUNT_MASK
8105 uint8 flags,
bool failed,
bool is_temp,
8120#ifdef USE_ASSERT_CHECKING
8261 uint8 handle_data_len;
8391 errmsg(
"zeroing %u page(s) and ignoring %u checksum failure(s) among blocks %u..%u of relation \"%s\"",
8394 errdetail(
"Block %u held the first zeroed page.",
8396 errhint_plural(
"See server log for details about the other %d invalid block.",
8397 "See server log for details about the other %d invalid blocks.",
8412 msg_one =
_(
"invalid page in block %u of relation \"%s\"");
8413 msg_mult =
_(
"%u invalid pages among blocks %u..%u of relation \"%s\"");
8414 det_mult =
_(
"Block %u held the first invalid page.");
8415 hint_mult =
_(
"See server log for the other %u invalid block(s).");
8420 msg_one =
_(
"invalid page in block %u of relation \"%s\"; zeroing out page");
8421 msg_mult =
_(
"zeroing out %u invalid pages among blocks %u..%u of relation \"%s\"");
8422 det_mult =
_(
"Block %u held the first zeroed page.");
8423 hint_mult =
_(
"See server log for the other %u zeroed block(s).");
8428 msg_one =
_(
"ignoring checksum failure in block %u of relation \"%s\"");
8429 msg_mult =
_(
"ignoring %u checksum failures among blocks %u..%u of relation \"%s\"");
8430 det_mult =
_(
"Block %u held the first ignored page.");
8431 hint_mult =
_(
"See server log for the other %u ignored block(s).");
bool pgaio_wref_valid(PgAioWaitRef *iow)
PgAioHandle * pgaio_io_acquire(struct ResourceOwnerData *resowner, PgAioReturn *ret)
void pgaio_wref_clear(PgAioWaitRef *iow)
void pgaio_io_get_wref(PgAioHandle *ioh, PgAioWaitRef *iow)
void pgaio_io_set_flag(PgAioHandle *ioh, PgAioHandleFlags flag)
bool pgaio_have_staged(void)
bool pgaio_wref_check_done(PgAioWaitRef *iow)
ProcNumber pgaio_io_get_owner(PgAioHandle *ioh)
void pgaio_submit_staged(void)
void pgaio_wref_wait(PgAioWaitRef *iow)
void pgaio_io_release(PgAioHandle *ioh)
PgAioHandle * pgaio_io_acquire_nb(struct ResourceOwnerData *resowner, PgAioReturn *ret)
@ PGAIO_HCB_LOCAL_BUFFER_READV
@ PGAIO_HCB_SHARED_BUFFER_READV
@ PGAIO_HF_REFERENCES_LOCAL
void pgaio_io_set_handle_data_32(PgAioHandle *ioh, uint32 *data, uint8 len)
void pgaio_io_register_callbacks(PgAioHandle *ioh, PgAioHandleCallbackID cb_id, uint8 cb_data)
uint64 * pgaio_io_get_handle_data(PgAioHandle *ioh, uint8 *len)
void pgaio_result_report(PgAioResult result, const PgAioTargetData *target_data, int elevel)
PgAioTargetData * pgaio_io_get_target_data(PgAioHandle *ioh)
#define PGAIO_RESULT_ERROR_BITS
static bool pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 *expected, uint64 newval)
#define pg_write_barrier()
static void pg_atomic_unlocked_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
static uint64 pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
static uint64 pg_atomic_fetch_and_u64(volatile pg_atomic_uint64 *ptr, uint64 and_)
static uint64 pg_atomic_fetch_or_u64(volatile pg_atomic_uint64 *ptr, uint64 or_)
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
static uint64 pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
TimestampTz GetCurrentTimestamp(void)
Datum now(PG_FUNCTION_ARGS)
void binaryheap_build(binaryheap *heap)
void binaryheap_replace_first(binaryheap *heap, bh_node_type d)
bh_node_type binaryheap_first(binaryheap *heap)
bh_node_type binaryheap_remove_first(binaryheap *heap)
void binaryheap_free(binaryheap *heap)
void binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
#define binaryheap_empty(h)
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
#define BufferIsLocal(buffer)
CkptSortItem * CkptBufferIds
WritebackContext BackendWritebackContext
#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)
#define BM_LOCK_VAL_SHARED
static ConditionVariable * BufferDescriptorGetIOCV(const BufferDesc *bdesc)
static uint64 UnlockBufHdrExt(BufferDesc *desc, uint64 old_buf_state, uint64 set_bits, uint64 unset_bits, int refcount_change)
static bool BufferTagsEqual(const BufferTag *tag1, const BufferTag *tag2)
static RelFileNumber BufTagGetRelNumber(const BufferTag *tag)
static void UnlockBufHdr(BufferDesc *desc)
#define BM_LOCK_VAL_EXCLUSIVE
static bool BufTagMatchesRelFileLocator(const BufferTag *tag, const RelFileLocator *rlocator)
#define BM_PIN_COUNT_WAITER
#define BM_LOCK_WAKE_IN_PROGRESS
static void ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer)
#define BUF_STATE_GET_USAGECOUNT(state)
static void ResourceOwnerForgetBufferIO(ResourceOwner owner, Buffer buffer)
#define BM_IO_IN_PROGRESS
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 LWLock * BufMappingPartitionLock(uint32 hashcode)
static RelFileLocator BufTagGetRelFileLocator(const BufferTag *tag)
#define BM_LOCK_HAS_WAITERS
static BufferDesc * GetLocalBufferDescriptor(uint32 id)
static BufferDesc * GetBufferDescriptor(uint32 id)
#define BM_LOCK_VAL_SHARE_EXCLUSIVE
static Buffer BufferDescriptorGetBuffer(const BufferDesc *bdesc)
#define BM_CHECKPOINT_NEEDED
void BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
int BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
uint32 BufTableHashCode(BufferTag *tagPtr)
int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
static void ResOwnerReleaseBuffer(Datum res)
void CheckBufferIsPinnedOnce(Buffer buffer)
void FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels)
void IncrBufferRefCount(Buffer buffer)
void DropDatabaseBuffers(Oid dbid)
static int ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b)
static pg_attribute_always_inline PgAioResult buffer_readv_complete(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data, bool is_temp)
BlockNumber BufferGetBlockNumber(Buffer buffer)
static PrivateRefCountEntry * NewPrivateRefCountEntry(Buffer buffer)
static Buffer PrivateRefCountArrayKeys[REFCOUNT_ARRAY_ENTRIES]
static bool ReadBuffersCanStartIO(Buffer buffer, bool nowait)
void DropRelationBuffers(SMgrRelation smgr_reln, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock)
Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, BlockNumber blockNum)
static int ReservedRefCountSlot
static PgAioResult shared_buffer_readv_complete_local(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data)
static pg_attribute_always_inline bool StartReadBuffersImpl(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, int *nblocks, int flags, bool allow_forwarding)
static void CheckReadBuffersOperation(ReadBuffersOperation *operation, bool is_complete)
PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
static uint32 PrivateRefCountClock
static void FlushBuffer(BufferDesc *buf, SMgrRelation reln, IOObject io_object, IOContext io_context)
static void ResOwnerReleaseBufferIO(Datum res)
static PgAioResult local_buffer_readv_complete(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data)
bool StartReadBuffers(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, int *nblocks, int flags)
void EvictAllUnpinnedBuffers(int32 *buffers_evicted, int32 *buffers_flushed, int32 *buffers_skipped)
static void FlushUnlockedBuffer(BufferDesc *buf, SMgrRelation reln, IOObject io_object, IOContext io_context)
const ResourceOwnerDesc buffer_io_resowner_desc
#define BUF_DROP_FULL_SCAN_THRESHOLD
static void PinBuffer_Locked(BufferDesc *buf)
void EvictRelUnpinnedBuffers(Relation rel, int32 *buffers_evicted, int32 *buffers_flushed, int32 *buffers_skipped)
static pg_attribute_always_inline void buffer_readv_complete_one(PgAioTargetData *td, uint8 buf_off, Buffer buffer, uint8 flags, bool failed, bool is_temp, bool *buffer_invalid, bool *failed_checksum, bool *ignored_checksum, bool *zeroed_buffer)
static char * ResOwnerPrintBuffer(Datum res)
static void BufferLockAcquire(Buffer buffer, BufferDesc *buf_hdr, BufferLockMode mode)
static bool BufferLockAttempt(BufferDesc *buf_hdr, BufferLockMode mode)
static int buffertag_comparator(const BufferTag *ba, const BufferTag *bb)
bool IsBufferCleanupOK(Buffer buffer)
#define BufferGetLSN(bufHdr)
static char * ResOwnerPrintBufferIO(Datum res)
bool BufferIsLockedByMeInMode(Buffer buffer, BufferLockMode mode)
static void BufferLockDisown(Buffer buffer, BufferDesc *buf_hdr)
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
void AtEOXact_Buffers(bool isCommit)
static void AbortBufferIO(Buffer buffer)
const PgAioHandleCallbacks aio_shared_buffer_readv_cb
static void BufferLockUnlock(Buffer buffer, BufferDesc *buf_hdr)
BlockNumber ExtendBufferedRelBy(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, Buffer *buffers, uint32 *extended_by)
static Buffer ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
static void BufferLockWakeup(BufferDesc *buf_hdr, bool unlocked)
static void ProcessReadBuffersResult(ReadBuffersOperation *operation)
pg_noinline uint64 WaitBufHdrUnlocked(BufferDesc *buf)
static void ZeroAndLockBuffer(Buffer buffer, ReadBufferMode mode, bool already_valid)
static BufferDesc * BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, BlockNumber blockNum, BufferAccessStrategy strategy, bool *foundPtr, IOContext io_context)
static void CheckForBufferLeaks(void)
static bool ReadBuffersCanStartIOOnce(Buffer buffer, bool nowait)
void CreateAndCopyRelationData(RelFileLocator src_rlocator, RelFileLocator dst_rlocator, bool permanent)
void DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators)
static void BufferLockDequeueSelf(BufferDesc *buf_hdr)
static int rlocator_comparator(const void *p1, const void *p2)
static bool BufferLockHeldByMeInMode(BufferDesc *buf_hdr, BufferLockMode mode)
Buffer ExtendBufferedRelTo(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, BlockNumber extend_to, ReadBufferMode mode)
const PgAioHandleCallbacks aio_local_buffer_readv_cb
static bool InvalidateVictimBuffer(BufferDesc *buf_hdr)
static void AtProcExit_Buffers(int code, Datum arg)
static int ts_ckpt_progress_comparator(Datum a, Datum b, void *arg)
void BufferGetTag(Buffer buffer, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum)
#define BufHdrGetBlock(bufHdr)
static bool BufferLockConditional(Buffer buffer, BufferDesc *buf_hdr, BufferLockMode mode)
const ResourceOwnerDesc buffer_resowner_desc
static pg_attribute_always_inline void buffer_stage_common(PgAioHandle *ioh, bool is_write, bool is_temp)
void UnlockBuffer(Buffer buffer)
static void local_buffer_write_error_callback(void *arg)
static void BufferSync(int flags)
static bool AsyncReadBuffers(ReadBuffersOperation *operation, int *nblocks_progress)
static void local_buffer_readv_stage(PgAioHandle *ioh, uint8 cb_data)
char * DebugPrintBufferRefcount(Buffer buffer)
void CheckPointBuffers(int flags)
bool BufferIsDirty(Buffer buffer)
static uint32 MaxProportionalPins
static void BufferLockQueueSelf(BufferDesc *buf_hdr, BufferLockMode mode)
static BlockNumber ExtendBufferedRelShared(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
static int BufferLockDisownInternal(Buffer buffer, BufferDesc *buf_hdr)
bool BgBufferSync(WritebackContext *wb_context)
uint64 LockBufHdr(BufferDesc *desc)
static void WakePinCountWaiter(BufferDesc *buf)
bool BufferIsPermanent(Buffer buffer)
void MarkDirtyAllUnpinnedBuffers(int32 *buffers_dirtied, int32 *buffers_already_dirty, int32 *buffers_skipped)
#define REFCOUNT_ARRAY_ENTRIES
static void shared_buffer_readv_stage(PgAioHandle *ioh, uint8 cb_data)
static void BufferLockProcessRelease(BufferDesc *buf_hdr, BufferLockMode mode, uint64 lockstate)
PrefetchBufferResult PrefetchSharedBuffer(SMgrRelation smgr_reln, ForkNumber forkNum, BlockNumber blockNum)
static PgAioResult shared_buffer_readv_complete(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data)
static Buffer GetVictimBuffer(BufferAccessStrategy strategy, IOContext io_context)
bool ConditionalLockBuffer(Buffer buffer)
BlockNumber RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
void ReleaseBuffer(Buffer buffer)
bool BufferIsLockedByMe(Buffer buffer)
static bool PinBuffer(BufferDesc *buf, BufferAccessStrategy strategy, bool skip_if_not_valid)
static void FindAndDropRelationBuffers(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber nForkBlock, BlockNumber firstDelBlock)
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
void LockBufferInternal(Buffer buffer, BufferLockMode mode)
bool HoldingBufferPinThatDelaysRecovery(void)
bool MarkDirtyUnpinnedBuffer(Buffer buf, bool *buffer_already_dirty)
int checkpoint_flush_after
void UnlockReleaseBuffer(Buffer buffer)
static pg_attribute_always_inline Buffer PinBufferForBlock(Relation rel, SMgrRelation smgr, char persistence, ForkNumber forkNum, BlockNumber blockNum, BufferAccessStrategy strategy, bool *foundPtr)
static void UnpinBufferNoOwner(BufferDesc *buf)
static void shared_buffer_write_error_callback(void *arg)
void ScheduleBufferTagForWriteback(WritebackContext *wb_context, IOContext io_context, BufferTag *tag)
void WaitReadBuffers(ReadBuffersOperation *operation)
void WritebackContextInit(WritebackContext *context, int *max_pending)
void MarkBufferDirty(Buffer buffer)
#define BufferIsPinned(bufnum)
double bgwriter_lru_multiplier
static bool EvictUnpinnedBufferInternal(BufferDesc *desc, bool *buffer_flushed)
void LimitAdditionalPins(uint32 *additional_pins)
static void buffer_readv_report(PgAioResult result, const PgAioTargetData *td, int elevel)
static void ReservePrivateRefCountEntry(void)
static BufferDesc * PinCountWaitBuf
static pg_noinline PrivateRefCountEntry * GetPrivateRefCountEntrySlow(Buffer buffer, bool do_move)
static int32 GetPrivateRefCount(Buffer buffer)
static BlockNumber ExtendBufferedRelCommon(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
void LockBufferForCleanup(Buffer buffer)
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
void FlushRelationBuffers(Relation rel)
static uint64 BufferLockReleaseSub(BufferLockMode mode)
void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
static void ForgetPrivateRefCountEntry(PrivateRefCountEntry *ref)
bool EvictUnpinnedBuffer(Buffer buf, bool *buffer_flushed)
Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy, bool permanent)
bool ReadRecentBuffer(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, Buffer recent_buffer)
#define RELS_BSEARCH_THRESHOLD
int maintenance_io_concurrency
static void UnpinBuffer(BufferDesc *buf)
void FlushDatabaseBuffers(Oid dbid)
static void InvalidateBuffer(BufferDesc *buf)
static void RelationCopyStorageUsingBuffer(RelFileLocator srclocator, RelFileLocator dstlocator, ForkNumber forkNum, bool permanent)
int effective_io_concurrency
static PrivateRefCountEntry * GetPrivateRefCountEntry(Buffer buffer, bool do_move)
static bool BufferLockHeldByMe(BufferDesc *buf_hdr)
void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint64 set_flag_bits, bool forget_owner, bool release_aio)
bool StartBufferIO(BufferDesc *buf, bool forInput, bool nowait)
void MarkDirtyRelUnpinnedBuffers(Relation rel, int32 *buffers_dirtied, int32 *buffers_already_dirty, int32 *buffers_skipped)
bool StartReadBuffer(ReadBuffersOperation *operation, Buffer *buffer, BlockNumber blocknum, int flags)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
static bool MarkDirtyUnpinnedBufferInternal(Buffer buf, BufferDesc *desc, bool *buffer_already_dirty)
static struct PrivateRefCountEntry PrivateRefCountArray[REFCOUNT_ARRAY_ENTRIES]
static void buffer_readv_decode_error(PgAioResult result, bool *zeroed_any, bool *ignored_any, uint8 *zeroed_or_error_count, uint8 *checkfail_count, uint8 *first_off)
static int PrivateRefCountEntryLast
void InitBufferManagerAccess(void)
static void buffer_readv_encode_error(PgAioResult *result, bool is_temp, bool zeroed_any, bool ignored_any, uint8 error_count, uint8 zeroed_count, uint8 checkfail_count, uint8 first_error_off, uint8 first_zeroed_off, uint8 first_ignored_off)
static int SyncOneBuffer(int buf_id, bool skip_recently_used, WritebackContext *wb_context)
uint32 GetAdditionalPinLimit(void)
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
void TrackNewBufferPin(Buffer buf)
static HTAB * PrivateRefCountHash
static int32 PrivateRefCountOverflowed
bool ConditionalLockBufferForCleanup(Buffer buffer)
int bgwriter_lru_maxpages
static void WaitIO(BufferDesc *buf)
void FlushOneBuffer(Buffer buffer)
#define READ_BUFFERS_ZERO_ON_ERROR
static Page BufferGetPage(Buffer buffer)
#define DEFAULT_IO_COMBINE_LIMIT
static Block BufferGetBlock(Buffer buffer)
#define READ_BUFFERS_ISSUE_ADVICE
@ BUFFER_LOCK_SHARE_EXCLUSIVE
#define MAX_IO_COMBINE_LIMIT
#define DEFAULT_EFFECTIVE_IO_CONCURRENCY
#define READ_BUFFERS_IGNORE_CHECKSUM_FAILURES
#define DEFAULT_MAINTENANCE_IO_CONCURRENCY
static void LockBuffer(Buffer buffer, BufferLockMode mode)
#define BMR_GET_SMGR(bmr)
@ EB_CREATE_FORK_IF_NEEDED
#define READ_BUFFERS_SYNCHRONOUSLY
@ RBM_ZERO_AND_CLEANUP_LOCK
static bool BufferIsValid(Buffer bufnum)
bool ignore_checksum_failure
char * PageSetChecksumCopy(Page page, BlockNumber blkno)
bool PageIsVerified(PageData *page, BlockNumber blkno, int flags, bool *checksum_failure_p)
static bool PageIsNew(const PageData *page)
static void PageSetLSN(Page page, XLogRecPtr lsn)
static XLogRecPtr PageGetLSN(const PageData *page)
#define PIV_IGNORE_CHECKSUM_FAILURE
#define PG_USED_FOR_ASSERTS_ONLY
#define Assert(condition)
#define pg_attribute_always_inline
#define MemSet(start, val, len)
#define StaticAssertDecl(condition, errmessage)
bool IsCatalogRelationOid(Oid relid)
bool IsCatalogTextUniqueIndexOid(Oid relid)
void CheckpointWriteDelay(int flags, double progress)
bool ConditionVariableCancelSleep(void)
void ConditionVariableBroadcast(ConditionVariable *cv)
void ConditionVariablePrepareToSleep(ConditionVariable *cv)
void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
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)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
ErrorContextCallback * error_context_stack
int errhint_internal(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
int errhint_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
#define ereport(elevel,...)
#define palloc_array(type, count)
int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc)
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
BufferDesc * StrategyGetBuffer(BufferAccessStrategy strategy, uint64 *buf_state, bool *from_ring)
void FreeAccessStrategy(BufferAccessStrategy strategy)
IOContext IOContextForStrategy(BufferAccessStrategy strategy)
bool StrategyRejectBuffer(BufferAccessStrategy strategy, BufferDesc *buf, bool from_ring)
volatile sig_atomic_t ProcSignalBarrierPending
BufferUsage pgBufferUsage
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln)
void UnpinLocalBuffer(Buffer buffer)
bool StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool nowait)
void AtEOXact_LocalBuffers(bool isCommit)
void AtProcExit_LocalBuffers(void)
bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
void MarkLocalBufferDirty(Buffer buffer)
void DropRelationAllLocalBuffers(RelFileLocator rlocator)
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint64 set_flag_bits, bool release_aio)
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)
void UnpinLocalBufferNoOwner(Buffer buffer)
void DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock)
BufferDesc * LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum, bool *foundPtr)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
#define RESUME_INTERRUPTS()
#define START_CRIT_SECTION()
#define CHECK_FOR_INTERRUPTS()
#define HOLD_INTERRUPTS()
#define END_CRIT_SECTION()
#define ERRCODE_DATA_CORRUPTED
static PgChecksumMode mode
static int64 current_size
#define WRITEBACK_MAX_PENDING_FLUSHES
#define DEFAULT_BACKEND_FLUSH_AFTER
#define DEFAULT_CHECKPOINT_FLUSH_AFTER
#define DEFAULT_BGWRITER_FLUSH_AFTER
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define pgstat_count_buffer_read(rel)
#define pgstat_count_buffer_hit(rel)
PgStat_BgWriterStats PendingBgWriterStats
PgStat_CheckpointerStats PendingCheckpointerStats
void pgstat_prepare_report_checksum_failure(Oid dboid)
void pgstat_report_checksum_failures_in_db(Oid dboid, int failurecount)
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 qsort(a, b, c, d)
void PGSemaphoreUnlock(PGSemaphore sema)
void PGSemaphoreLock(PGSemaphore sema)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
static int32 DatumGetInt32(Datum X)
#define NUM_AUXILIARY_PROCS
#define GetPGProcByNumber(n)
#define DELAY_CHKPT_START
#define proclist_delete(list, procno, link_member)
static void proclist_init(proclist_head *list)
#define proclist_push_tail(list, procno, link_member)
#define proclist_foreach_modify(iter, lhead, link_member)
static bool proclist_is_empty(const proclist_head *list)
#define INVALID_PROC_NUMBER
void ProcessProcSignalBarrier(void)
@ PROCSIG_RECOVERY_CONFLICT_BUFFERPIN
void set_ps_display_remove_suffix(void)
void set_ps_display_suffix(const char *suffix)
char * psprintf(const char *fmt,...)
ReadStream * read_stream_begin_smgr_relation(int flags, BufferAccessStrategy strategy, SMgrRelation smgr, char smgr_persistence, ForkNumber forknum, ReadStreamBlockNumberCB callback, void *callback_private_data, size_t per_buffer_data_size)
Buffer read_stream_next_buffer(ReadStream *stream, void **per_buffer_data)
void read_stream_end(ReadStream *stream)
BlockNumber block_range_read_stream_cb(ReadStream *stream, void *callback_private_data, void *per_buffer_data)
#define READ_STREAM_USE_BATCHING
static unsigned hash(unsigned *uv, int n)
static SMgrRelation RelationGetSmgr(Relation rel)
#define RelationUsesLocalBuffers(relation)
#define RELATION_IS_OTHER_TEMP(relation)
#define RelationIsValid(relation)
#define RelFileLocatorBackendIsTemp(rlocator)
#define RelFileLocatorEquals(locator1, locator2)
#define relpath(rlocator, forknum)
#define relpathbackend(rlocator, backend, forknum)
#define relpathperm(rlocator, forknum)
ResourceOwner CurrentResourceOwner
void ResourceOwnerEnlarge(ResourceOwner owner)
#define RELEASE_PRIO_BUFFER_IOS
@ RESOURCE_RELEASE_BEFORE_LOCKS
#define RELEASE_PRIO_BUFFER_PINS
void perform_spin_delay(SpinDelayStatus *status)
void finish_spin_delay(SpinDelayStatus *status)
#define init_local_spin_delay(status)
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
void smgrstartreadv(PgAioHandle *ioh, SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void **buffers, BlockNumber nblocks)
void smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks)
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
BlockNumber smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum)
uint32 smgrmaxcombine(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
void smgrzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skipFsync)
void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
bool smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks)
static void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
void ProcSendSignal(ProcNumber procNumber)
int GetStartupBufferPinWaitBufId(void)
void SetStartupBufferPinWaitBufId(int bufid)
void ProcWaitForSignal(uint32 wait_event_info)
void ResolveRecoveryConflictWithBufferPin(void)
bool log_recovery_conflict_waits
void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
bool RelFileLocatorSkippingWAL(RelFileLocator rlocator)
SMgrRelation RelationCreateStorage(RelFileLocator rlocator, char relpersistence, bool register_delete)
void log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum)
BlockNumber last_exclusive
BlockNumber current_blocknum
int64 shared_blks_dirtied
int64 shared_blks_written
struct ErrorContextCallback * previous
void(* callback)(void *arg)
PgAioHandleCallbackStage stage
PgStat_Counter buf_written_clean
PgStat_Counter maxwritten_clean
PgStat_Counter buffers_written
BufferAccessStrategy strategy
char str[REL_PATH_STR_MAXLEN+1]
RelFileLocator rd_locator
RelFileLocatorBackend smgr_rlocator
static uint64 table_relation_size(Relation rel, ForkNumber forkNumber)
struct PgAioTargetData::@126 smgr
static void pgstat_report_wait_start(uint32 wait_event_info)
static void pgstat_report_wait_end(void)
static volatile sig_atomic_t waiting
static TimestampTz wakeup[NUM_WALRCV_WAKEUPS]
bool RecoveryInProgress(void)
bool XLogNeedsFlush(XLogRecPtr record)
CheckpointStatsData CheckpointStats
void XLogFlush(XLogRecPtr record)
#define CHECKPOINT_FLUSH_UNLOGGED
#define CHECKPOINT_END_OF_RECOVERY
#define CHECKPOINT_IS_SHUTDOWN
#define XLogHintBitIsNeeded()
#define XLogRecPtrIsValid(r)
#define InvalidXLogRecPtr
XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std)
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)