PostgreSQL Source Code git master
Loading...
Searching...
No Matches
bufmgr.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * bufmgr.c
4 * buffer manager interface routines
5 *
6 * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 *
10 * IDENTIFICATION
11 * src/backend/storage/buffer/bufmgr.c
12 *
13 *-------------------------------------------------------------------------
14 */
15/*
16 * Principal entry points:
17 *
18 * ReadBuffer() -- find or create a buffer holding the requested page,
19 * and pin it so that no one can destroy it while this process
20 * is using it.
21 *
22 * StartReadBuffer() -- as above, with separate wait step
23 * StartReadBuffers() -- multiple block version
24 * WaitReadBuffers() -- second step of above
25 *
26 * ReleaseBuffer() -- unpin a buffer
27 *
28 * MarkBufferDirty() -- mark a pinned buffer's contents as "dirty".
29 * The disk write is delayed until buffer replacement or checkpoint.
30 *
31 * See also these files:
32 * freelist.c -- chooses victim for buffer replacement
33 * buf_table.c -- manages the buffer lookup table
34 */
35#include "postgres.h"
36
37#include <sys/file.h>
38#include <unistd.h>
39
40#include "access/tableam.h"
41#include "access/xloginsert.h"
42#include "access/xlogutils.h"
43#ifdef USE_ASSERT_CHECKING
44#include "catalog/pg_tablespace_d.h"
45#endif
46#include "catalog/storage.h"
48#include "common/hashfn.h"
49#include "executor/instrument.h"
50#include "lib/binaryheap.h"
51#include "miscadmin.h"
52#include "pg_trace.h"
53#include "pgstat.h"
54#include "postmaster/bgwriter.h"
55#include "storage/aio.h"
57#include "storage/bufmgr.h"
58#include "storage/fd.h"
59#include "storage/ipc.h"
60#include "storage/lmgr.h"
61#include "storage/proc.h"
62#include "storage/proclist.h"
63#include "storage/procsignal.h"
64#include "storage/read_stream.h"
65#include "storage/smgr.h"
66#include "storage/standby.h"
67#include "utils/memdebug.h"
68#include "utils/ps_status.h"
69#include "utils/rel.h"
70#include "utils/resowner.h"
71#include "utils/timestamp.h"
72#include "utils/wait_event.h"
73
74
75/* Note: these two macros only work on shared buffers, not local ones! */
76#define BufHdrGetBlock(bufHdr) ((Block) (BufferBlocks + ((Size) (bufHdr)->buf_id) * BLCKSZ))
77#define BufferGetLSN(bufHdr) (PageGetLSN(BufHdrGetBlock(bufHdr)))
78
79/* Note: this macro only works on local buffers, not shared ones! */
80#define LocalBufHdrGetBlock(bufHdr) \
81 LocalBufferBlockPointers[-((bufHdr)->buf_id + 2)]
82
83/* Bits in SyncOneBuffer's return value */
84#define BUF_WRITTEN 0x01
85#define BUF_REUSABLE 0x02
86
87#define RELS_BSEARCH_THRESHOLD 20
88
89/*
90 * This is the size (in the number of blocks) above which we scan the
91 * entire buffer pool to remove the buffers for all the pages of relation
92 * being dropped. For the relations with size below this threshold, we find
93 * the buffers by doing lookups in BufMapping table.
94 */
95#define BUF_DROP_FULL_SCAN_THRESHOLD (uint64) (NBuffers / 32)
96
97/*
98 * This is separated out from PrivateRefCountEntry to allow for copying all
99 * the data members via struct assignment.
100 */
102{
103 /*
104 * How many times has the buffer been pinned by this backend.
105 */
107
108 /*
109 * Is the buffer locked by this backend? BUFFER_LOCK_UNLOCK indicates that
110 * the buffer is not locked.
111 */
114
116{
117 /*
118 * Note that this needs to be same as the entry's corresponding
119 * PrivateRefCountArrayKeys[i], if the entry is stored in the array. We
120 * store it in both places as this is used for the hashtable key and
121 * because it is more convenient (passing around a PrivateRefCountEntry
122 * suffices to identify the buffer) and faster (checking the keys array is
123 * faster when checking many entries, checking the entry is faster if just
124 * checking a single entry).
125 */
127
128 char status;
129
132
133#define SH_PREFIX refcount
134#define SH_ELEMENT_TYPE PrivateRefCountEntry
135#define SH_KEY_TYPE Buffer
136#define SH_KEY buffer
137#define SH_HASH_KEY(tb, key) murmurhash32((uint32) (key))
138#define SH_EQUAL(tb, a, b) ((a) == (b))
139#define SH_SCOPE static inline
140#define SH_DECLARE
141#define SH_DEFINE
142#include "lib/simplehash.h"
143
144/* 64 bytes, about the size of a cache line on common systems */
145#define REFCOUNT_ARRAY_ENTRIES 8
146
147/*
148 * Status of buffers to checkpoint for a particular tablespace, used
149 * internally in BufferSync.
150 */
151typedef struct CkptTsStatus
152{
153 /* oid of the tablespace */
155
156 /*
157 * Checkpoint progress for this tablespace. To make progress comparable
158 * between tablespaces the progress is, for each tablespace, measured as a
159 * number between 0 and the total number of to-be-checkpointed pages. Each
160 * page checkpointed in this tablespace increments this space's progress
161 * by progress_slice.
162 */
165
166 /* number of to-be checkpointed pages in this tablespace */
168 /* already processed pages in this tablespace */
170
171 /* current offset in CkptBufferIds for this tablespace */
172 int index;
174
175/*
176 * Type for array used to sort SMgrRelations
177 *
178 * FlushRelationsAllBuffers shares the same comparator function with
179 * DropRelationsAllBuffers. Pointer to this struct and RelFileLocator must be
180 * compatible.
181 */
182typedef struct SMgrSortArray
183{
184 RelFileLocator rlocator; /* This must be the first member */
187
188/* GUC variables */
192bool track_io_timing = false;
193
194/*
195 * How many buffers PrefetchBuffer callers should try to stay ahead of their
196 * ReadBuffer calls by. Zero means "never prefetch". This value is only used
197 * for buffers not belonging to tablespaces that have their
198 * effective_io_concurrency parameter set.
199 */
201
202/*
203 * Like effective_io_concurrency, but used by maintenance code paths that might
204 * benefit from a higher setting because they work on behalf of many sessions.
205 * Overridden by the tablespace setting of the same name.
206 */
208
209/*
210 * Limit on how many blocks should be handled in single I/O operations.
211 * StartReadBuffers() callers should respect it, as should other operations
212 * that call smgr APIs directly. It is computed as the minimum of underlying
213 * GUCs io_combine_limit_guc and io_max_combine_limit.
214 */
218
219/*
220 * GUC variables about triggering kernel writeback for buffers written; OS
221 * dependent defaults are set via the GUC mechanism.
222 */
226
227/* local state for LockBufferForCleanup */
229
230/*
231 * Backend-Private refcount management:
232 *
233 * Each buffer also has a private refcount that keeps track of the number of
234 * times the buffer is pinned in the current process. This is so that the
235 * shared refcount needs to be modified only once if a buffer is pinned more
236 * than once by an individual backend. It's also used to check that no
237 * buffers are still pinned at the end of transactions and when exiting. We
238 * also use this mechanism to track whether this backend has a buffer locked,
239 * and, if so, in what mode.
240 *
241 *
242 * To avoid - as we used to - requiring an array with NBuffers entries to keep
243 * track of local buffers, we use a small sequentially searched array
244 * (PrivateRefCountArrayKeys, with the corresponding data stored in
245 * PrivateRefCountArray) and an overflow hash table (PrivateRefCountHash) to
246 * keep track of backend local pins.
247 *
248 * Until no more than REFCOUNT_ARRAY_ENTRIES buffers are pinned at once, all
249 * refcounts are kept track of in the array; after that, new array entries
250 * displace old ones into the hash table. That way a frequently used entry
251 * can't get "stuck" in the hashtable while infrequent ones clog the array.
252 *
253 * Note that in most scenarios the number of pinned buffers will not exceed
254 * REFCOUNT_ARRAY_ENTRIES.
255 *
256 *
257 * To enter a buffer into the refcount tracking mechanism first reserve a free
258 * entry using ReservePrivateRefCountEntry() and then later, if necessary,
259 * fill it with NewPrivateRefCountEntry(). That split lets us avoid doing
260 * memory allocations in NewPrivateRefCountEntry() which can be important
261 * because in some scenarios it's called with a spinlock held...
262 */
268static int ReservedRefCountSlot = -1;
270
272
273static void ReservePrivateRefCountEntry(void);
278
279/* ResourceOwner callbacks to hold in-progress I/Os and buffer pins */
280static void ResOwnerReleaseBufferIO(Datum res);
281static char *ResOwnerPrintBufferIO(Datum res);
282static void ResOwnerReleaseBuffer(Datum res);
283static char *ResOwnerPrintBuffer(Datum res);
284
286{
287 .name = "buffer io",
288 .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
289 .release_priority = RELEASE_PRIO_BUFFER_IOS,
290 .ReleaseResource = ResOwnerReleaseBufferIO,
291 .DebugPrint = ResOwnerPrintBufferIO
292};
293
295{
296 .name = "buffer",
297 .release_phase = RESOURCE_RELEASE_BEFORE_LOCKS,
298 .release_priority = RELEASE_PRIO_BUFFER_PINS,
299 .ReleaseResource = ResOwnerReleaseBuffer,
300 .DebugPrint = ResOwnerPrintBuffer
301};
302
303/*
304 * Ensure that the PrivateRefCountArray has sufficient space to store one more
305 * entry. This has to be called before using NewPrivateRefCountEntry() to fill
306 * a new entry - but it's perfectly fine to not use a reserved entry.
307 */
308static void
310{
311 /* Already reserved (or freed), nothing to do */
312 if (ReservedRefCountSlot != -1)
313 return;
314
315 /*
316 * First search for a free entry the array, that'll be sufficient in the
317 * majority of cases.
318 */
319 {
320 int i;
321
322 for (i = 0; i < REFCOUNT_ARRAY_ENTRIES; i++)
323 {
325 {
327
328 /*
329 * We could return immediately, but iterating till the end of
330 * the array allows compiler-autovectorization.
331 */
332 }
333 }
334
335 if (ReservedRefCountSlot != -1)
336 return;
337 }
338
339 /*
340 * No luck. All array entries are full. Move one array entry into the hash
341 * table.
342 */
343 {
344 /*
345 * Move entry from the current clock position in the array into the
346 * hashtable. Use that slot.
347 */
348 int victim_slot;
351 bool found;
352
353 /* select victim slot */
357
358 /* Better be used, otherwise we shouldn't get here. */
362
363 /* enter victim array entry into hashtable */
366 &found);
367 Assert(!found);
368 /* move data from the entry in the array to the hash entry */
369 hashent->data = victim_entry->data;
370
371 /* clear the now free array slot */
373 victim_entry->buffer = InvalidBuffer;
374
375 /* clear the whole data member, just for future proofing */
376 memset(&victim_entry->data, 0, sizeof(victim_entry->data));
377 victim_entry->data.refcount = 0;
378 victim_entry->data.lockmode = BUFFER_LOCK_UNLOCK;
379
381 }
382}
383
384/*
385 * Fill a previously reserved refcount entry.
386 */
389{
391
392 /* only allowed to be called when a reservation has been made */
394
395 /* use up the reserved entry */
397
398 /* and fill it */
400 res->buffer = buffer;
401 res->data.refcount = 0;
403
404 /* update cache for the next lookup */
406
408
409 return res;
410}
411
412/*
413 * Slow-path for GetPrivateRefCountEntry(). This is big enough to not be worth
414 * inlining. This particularly seems to be true if the compiler is capable of
415 * auto-vectorizing the code, as that imposes additional stack-alignment
416 * requirements etc.
417 */
420{
422 int match = -1;
423 int i;
424
425 /*
426 * First search for references in the array, that'll be sufficient in the
427 * majority of cases.
428 */
429 for (i = 0; i < REFCOUNT_ARRAY_ENTRIES; i++)
430 {
432 {
433 match = i;
434 /* see ReservePrivateRefCountEntry() for why we don't return */
435 }
436 }
437
438 if (likely(match != -1))
439 {
440 /* update cache for the next lookup */
442
443 return &PrivateRefCountArray[match];
444 }
445
446 /*
447 * By here we know that the buffer, if already pinned, isn't residing in
448 * the array.
449 *
450 * Only look up the buffer in the hashtable if we've previously overflowed
451 * into it.
452 */
454 return NULL;
455
457
458 if (res == NULL)
459 return NULL;
460 else if (!do_move)
461 {
462 /* caller doesn't want us to move the hash entry into the array */
463 return res;
464 }
465 else
466 {
467 /* move buffer from hashtable into the free array slot */
470
471 /* Save data and delete from hashtable while res is still valid */
472 data = res->data;
476
477 /* Ensure there's a free array slot */
479
480 /* Use up the reserved slot */
484 Assert(free->buffer == InvalidBuffer);
485
486 /* and fill it */
487 free->buffer = buffer;
488 free->data = data;
490 /* update cache for the next lookup */
492
494
495 return free;
496 }
497}
498
499/*
500 * Return the PrivateRefCount entry for the passed buffer.
501 *
502 * Returns NULL if a buffer doesn't have a refcount entry. Otherwise, if
503 * do_move is true, and the entry resides in the hashtable the entry is
504 * optimized for frequent access by moving it to the array.
505 */
506static inline PrivateRefCountEntry *
508{
511
512 /*
513 * It's very common to look up the same buffer repeatedly. To make that
514 * fast, we have a one-entry cache.
515 *
516 * In contrast to the loop in GetPrivateRefCountEntrySlow(), here it
517 * faster to check PrivateRefCountArray[].buffer, as in the case of a hit
518 * fewer addresses are computed and fewer cachelines are accessed. Whereas
519 * in GetPrivateRefCountEntrySlow()'s case, checking
520 * PrivateRefCountArrayKeys saves a lot of memory accesses.
521 */
522 if (likely(PrivateRefCountEntryLast != -1) &&
524 {
526 }
527
528 /*
529 * The code for the cached lookup is small enough to be worth inlining
530 * into the caller. In the miss case however, that empirically doesn't
531 * seem worth it.
532 */
534}
535
536/*
537 * Returns how many times the passed buffer is pinned by this backend.
538 *
539 * Only works for shared memory buffers!
540 */
541static inline int32
543{
545
548
549 /*
550 * Not moving the entry - that's ok for the current users, but we might
551 * want to change this one day.
552 */
554
555 if (ref == NULL)
556 return 0;
557 return ref->data.refcount;
558}
559
560/*
561 * Release resources used to track the reference count of a buffer which we no
562 * longer have pinned and don't want to pin again immediately.
563 */
564static void
566{
567 Assert(ref->data.refcount == 0);
568 Assert(ref->data.lockmode == BUFFER_LOCK_UNLOCK);
569
570 if (ref >= &PrivateRefCountArray[0] &&
572 {
573 ref->buffer = InvalidBuffer;
575
576
577 /*
578 * Mark the just used entry as reserved - in many scenarios that
579 * allows us to avoid ever having to search the array/hash for free
580 * entries.
581 */
583 }
584 else
585 {
589 }
590}
591
592/*
593 * BufferIsPinned
594 * True iff the buffer is pinned (also checks for valid buffer number).
595 *
596 * NOTE: what we check here is that *this* backend holds a pin on
597 * the buffer. We do not care whether some other backend does.
598 */
599#define BufferIsPinned(bufnum) \
600( \
601 !BufferIsValid(bufnum) ? \
602 false \
603 : \
604 BufferIsLocal(bufnum) ? \
605 (LocalRefCount[-(bufnum) - 1] > 0) \
606 : \
607 (GetPrivateRefCount(bufnum) > 0) \
608)
609
610
613 ForkNumber forkNum, BlockNumber blockNum,
617 BufferAccessStrategy strategy,
618 uint32 flags,
621 Buffer *buffers,
625 BufferAccessStrategy strategy,
626 uint32 flags,
629 Buffer *buffers,
631static bool PinBuffer(BufferDesc *buf, BufferAccessStrategy strategy,
632 bool skip_if_not_valid);
633static void PinBuffer_Locked(BufferDesc *buf);
634static void UnpinBuffer(BufferDesc *buf);
635static void UnpinBufferNoOwner(BufferDesc *buf);
636static void BufferSync(int flags);
637static int SyncOneBuffer(int buf_id, bool skip_recently_used,
639static void WaitIO(BufferDesc *buf);
640static void AbortBufferIO(Buffer buffer);
641static void shared_buffer_write_error_callback(void *arg);
642static void local_buffer_write_error_callback(void *arg);
643static inline BufferDesc *BufferAlloc(SMgrRelation smgr,
644 char relpersistence,
645 ForkNumber forkNum,
646 BlockNumber blockNum,
647 BufferAccessStrategy strategy,
650static void CheckReadBuffersOperation(ReadBuffersOperation *operation, bool is_complete);
651
654 Relation rel, char persistence, SMgrRelation smgr,
655 ForkNumber forknum, BlockNumber blocknum);
661static void FindAndDropRelationBuffers(RelFileLocator rlocator,
662 ForkNumber forkNum,
667 ForkNumber forkNum, bool permanent);
668static void AtProcExit_Buffers(int code, Datum arg);
669static void CheckForBufferLeaks(void);
670#ifdef USE_ASSERT_CHECKING
672#endif
673static int rlocator_comparator(const void *p1, const void *p2);
674static inline int buffertag_comparator(const BufferTag *ba, const BufferTag *bb);
675static inline int ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b);
676static int ts_ckpt_progress_comparator(Datum a, Datum b, void *arg);
677
683static inline void BufferLockDisown(Buffer buffer, BufferDesc *buf_hdr);
691
692
693/*
694 * Implementation of PrefetchBuffer() for shared buffers.
695 */
698 ForkNumber forkNum,
699 BlockNumber blockNum)
700{
702 BufferTag newTag; /* identity of requested block */
703 uint32 newHash; /* hash value for newTag */
704 LWLock *newPartitionLock; /* buffer partition lock for it */
705 int buf_id;
706
707 Assert(BlockNumberIsValid(blockNum));
708
709 /* create a tag so we can lookup the buffer */
710 InitBufferTag(&newTag, &smgr_reln->smgr_rlocator.locator,
711 forkNum, blockNum);
712
713 /* determine its hash code and partition lock ID */
716
717 /* see if the block is in the buffer pool already */
719 buf_id = BufTableLookup(&newTag, newHash);
721
722 /* If not in buffers, initiate prefetch */
723 if (buf_id < 0)
724 {
725#ifdef USE_PREFETCH
726 /*
727 * Try to initiate an asynchronous read. This returns false in
728 * recovery if the relation file doesn't exist.
729 */
730 if ((io_direct_flags & IO_DIRECT_DATA) == 0 &&
731 smgrprefetch(smgr_reln, forkNum, blockNum, 1))
732 {
733 result.initiated_io = true;
734 }
735#endif /* USE_PREFETCH */
736 }
737 else
738 {
739 /*
740 * Report the buffer it was in at that time. The caller may be able
741 * to avoid a buffer table lookup, but it's not pinned and it must be
742 * rechecked!
743 */
744 result.recent_buffer = buf_id + 1;
745 }
746
747 /*
748 * If the block *is* in buffers, we do nothing. This is not really ideal:
749 * the block might be just about to be evicted, which would be stupid
750 * since we know we are going to need it soon. But the only easy answer
751 * is to bump the usage_count, which does not seem like a great solution:
752 * when the caller does ultimately touch the block, usage_count would get
753 * bumped again, resulting in too much favoritism for blocks that are
754 * involved in a prefetch sequence. A real fix would involve some
755 * additional per-buffer state, and it's not clear that there's enough of
756 * a problem to justify that.
757 */
758
759 return result;
760}
761
762/*
763 * PrefetchBuffer -- initiate asynchronous read of a block of a relation
764 *
765 * This is named by analogy to ReadBuffer but doesn't actually allocate a
766 * buffer. Instead it tries to ensure that a future ReadBuffer for the given
767 * block will not be delayed by the I/O. Prefetching is optional.
768 *
769 * There are three possible outcomes:
770 *
771 * 1. If the block is already cached, the result includes a valid buffer that
772 * could be used by the caller to avoid the need for a later buffer lookup, but
773 * it's not pinned, so the caller must recheck it.
774 *
775 * 2. If the kernel has been asked to initiate I/O, the initiated_io member is
776 * true. Currently there is no way to know if the data was already cached by
777 * the kernel and therefore didn't really initiate I/O, and no way to know when
778 * the I/O completes other than using synchronous ReadBuffer().
779 *
780 * 3. Otherwise, the buffer wasn't already cached by PostgreSQL, and
781 * USE_PREFETCH is not defined (this build doesn't support prefetching due to
782 * lack of a kernel facility), direct I/O is enabled, or the underlying
783 * relation file wasn't found and we are in recovery. (If the relation file
784 * wasn't found and we are not in recovery, an error is raised).
785 */
788{
790 Assert(BlockNumberIsValid(blockNum));
791
793 {
794 /* see comments in ReadBuffer_common */
798 errmsg("cannot access temporary tables of other sessions")));
799
800 /* pass it off to localbuf.c */
801 return PrefetchLocalBuffer(RelationGetSmgr(reln), forkNum, blockNum);
802 }
803 else
804 {
805 /* pass it to the shared buffer version */
806 return PrefetchSharedBuffer(RelationGetSmgr(reln), forkNum, blockNum);
807 }
808}
809
810/*
811 * ReadRecentBuffer -- try to pin a block in a recently observed buffer
812 *
813 * Compared to ReadBuffer(), this avoids a buffer mapping lookup when it's
814 * successful. Return true if the buffer is valid and still has the expected
815 * tag. In that case, the buffer is pinned and the usage count is bumped.
816 */
817bool
819 Buffer recent_buffer)
820{
822 BufferTag tag;
824
825 Assert(BufferIsValid(recent_buffer));
826
829 InitBufferTag(&tag, &rlocator, forkNum, blockNum);
830
831 if (BufferIsLocal(recent_buffer))
832 {
833 int b = -recent_buffer - 1;
834
837
838 /* Is it still valid and holding the right tag? */
839 if ((buf_state & BM_VALID) && BufferTagsEqual(&tag, &bufHdr->tag))
840 {
841 PinLocalBuffer(bufHdr, true);
842
844
845 return true;
846 }
847 }
848 else
849 {
850 bufHdr = GetBufferDescriptor(recent_buffer - 1);
851
852 /*
853 * Is it still valid and holding the right tag? We do an unlocked tag
854 * comparison first, to make it unlikely that we'll increment the
855 * usage counter of the wrong buffer, if someone calls us with a very
856 * out of date recent_buffer. Then we'll check it again if we get the
857 * pin.
858 */
859 if (BufferTagsEqual(&tag, &bufHdr->tag) &&
860 PinBuffer(bufHdr, NULL, true))
861 {
862 if (BufferTagsEqual(&tag, &bufHdr->tag))
863 {
865 return true;
866 }
868 }
869 }
870
871 return false;
872}
873
874/*
875 * ReadBuffer -- a shorthand for ReadBufferExtended, for reading from main
876 * fork with RBM_NORMAL mode and default strategy.
877 */
878Buffer
883
884/*
885 * ReadBufferExtended -- returns a buffer containing the requested
886 * block of the requested relation. If the blknum
887 * requested is P_NEW, extend the relation file and
888 * allocate a new block. (Caller is responsible for
889 * ensuring that only one backend tries to extend a
890 * relation at the same time!)
891 *
892 * Returns: the buffer number for the buffer containing
893 * the block read. The returned buffer has been pinned.
894 * Does not return on error --- elog's instead.
895 *
896 * Assume when this function is called, that reln has been opened already.
897 *
898 * In RBM_NORMAL mode, the page is read from disk, and the page header is
899 * validated. An error is thrown if the page header is not valid. (But
900 * note that an all-zero page is considered "valid"; see
901 * PageIsVerified().)
902 *
903 * RBM_ZERO_ON_ERROR is like the normal mode, but if the page header is not
904 * valid, the page is zeroed instead of throwing an error. This is intended
905 * for non-critical data, where the caller is prepared to repair errors.
906 *
907 * In RBM_ZERO_AND_LOCK mode, if the page isn't in buffer cache already, it's
908 * filled with zeros instead of reading it from disk. Useful when the caller
909 * is going to fill the page from scratch, since this saves I/O and avoids
910 * unnecessary failure if the page-on-disk has corrupt page headers.
911 * The page is returned locked to ensure that the caller has a chance to
912 * initialize the page before it's made visible to others.
913 * Caution: do not use this mode to read a page that is beyond the relation's
914 * current physical EOF; that is likely to cause problems in md.c when
915 * the page is modified and written out. P_NEW is OK, though.
916 *
917 * RBM_ZERO_AND_CLEANUP_LOCK is the same as RBM_ZERO_AND_LOCK, but acquires
918 * a cleanup-strength lock on the page.
919 *
920 * RBM_NORMAL_NO_LOG mode is treated the same as RBM_NORMAL here.
921 *
922 * If strategy is not NULL, a nondefault buffer access strategy is used.
923 * See buffer/README for details.
924 */
925inline Buffer
928{
929 Buffer buf;
930
931 /*
932 * Read the buffer, and update pgstat counters to reflect a cache hit or
933 * miss. The other-session temp-relation check is enforced by
934 * ReadBuffer_common().
935 */
937 forkNum, blockNum, mode, strategy);
938
939 return buf;
940}
941
942
943/*
944 * ReadBufferWithoutRelcache -- like ReadBufferExtended, but doesn't require
945 * a relcache entry for the relation.
946 *
947 * Pass permanent = true for a RELPERSISTENCE_PERMANENT relation, and
948 * permanent = false for a RELPERSISTENCE_UNLOGGED relation. This function
949 * cannot be used for temporary relations (and making that work might be
950 * difficult, unless we only want to read temporary relations for our own
951 * ProcNumber).
952 */
953Buffer
956 BufferAccessStrategy strategy, bool permanent)
957{
958 SMgrRelation smgr = smgropen(rlocator, INVALID_PROC_NUMBER);
959
960 return ReadBuffer_common(NULL, smgr,
962 forkNum, blockNum,
963 mode, strategy);
964}
965
966/*
967 * Convenience wrapper around ExtendBufferedRelBy() extending by one block.
968 */
969Buffer
971 ForkNumber forkNum,
972 BufferAccessStrategy strategy,
973 uint32 flags)
974{
975 Buffer buf;
976 uint32 extend_by = 1;
977
978 ExtendBufferedRelBy(bmr, forkNum, strategy, flags, extend_by,
979 &buf, &extend_by);
980
981 return buf;
982}
983
984/*
985 * Extend relation by multiple blocks.
986 *
987 * Tries to extend the relation by extend_by blocks. Depending on the
988 * availability of resources the relation may end up being extended by a
989 * smaller number of pages (unless an error is thrown, always by at least one
990 * page). *extended_by is updated to the number of pages the relation has been
991 * extended to.
992 *
993 * buffers needs to be an array that is at least extend_by long. Upon
994 * completion, the first extend_by array elements will point to a pinned
995 * buffer.
996 *
997 * If EB_LOCK_FIRST is part of flags, the first returned buffer is
998 * locked. This is useful for callers that want a buffer that is guaranteed to
999 * be empty.
1000 */
1004 BufferAccessStrategy strategy,
1005 uint32 flags,
1007 Buffer *buffers,
1009{
1010 Assert((bmr.rel != NULL) != (bmr.smgr != NULL));
1011 Assert(bmr.smgr == NULL || bmr.relpersistence != '\0');
1012 Assert(extend_by > 0);
1013
1014 if (bmr.relpersistence == '\0')
1015 bmr.relpersistence = bmr.rel->rd_rel->relpersistence;
1016
1017 return ExtendBufferedRelCommon(bmr, fork, strategy, flags,
1019 buffers, extended_by);
1020}
1021
1022/*
1023 * Extend the relation so it is at least extend_to blocks large, return buffer
1024 * (extend_to - 1).
1025 *
1026 * This is useful for callers that want to write a specific page, regardless
1027 * of the current size of the relation (e.g. useful for visibilitymap and for
1028 * crash recovery).
1029 */
1030Buffer
1033 BufferAccessStrategy strategy,
1034 uint32 flags,
1037{
1039 uint32 extended_by = 0;
1041 Buffer buffers[64];
1042
1043 Assert((bmr.rel != NULL) != (bmr.smgr != NULL));
1044 Assert(bmr.smgr == NULL || bmr.relpersistence != '\0');
1046
1047 if (bmr.relpersistence == '\0')
1048 bmr.relpersistence = bmr.rel->rd_rel->relpersistence;
1049
1050 /*
1051 * If desired, create the file if it doesn't exist. If
1052 * smgr_cached_nblocks[fork] is positive then it must exist, no need for
1053 * an smgrexists call.
1054 */
1055 if ((flags & EB_CREATE_FORK_IF_NEEDED) &&
1056 (BMR_GET_SMGR(bmr)->smgr_cached_nblocks[fork] == 0 ||
1057 BMR_GET_SMGR(bmr)->smgr_cached_nblocks[fork] == InvalidBlockNumber) &&
1059 {
1061
1062 /* recheck, fork might have been created concurrently */
1065
1067 }
1068
1069 /*
1070 * If requested, invalidate size cache, so that smgrnblocks asks the
1071 * kernel.
1072 */
1073 if (flags & EB_CLEAR_SIZE_CACHE)
1074 BMR_GET_SMGR(bmr)->smgr_cached_nblocks[fork] = InvalidBlockNumber;
1075
1076 /*
1077 * Estimate how many pages we'll need to extend by. This avoids acquiring
1078 * unnecessarily many victim buffers.
1079 */
1081
1082 /*
1083 * Since no-one else can be looking at the page contents yet, there is no
1084 * difference between an exclusive lock and a cleanup-strength lock. Note
1085 * that we pass the original mode to ReadBuffer_common() below, when
1086 * falling back to reading the buffer to a concurrent relation extension.
1087 */
1089 flags |= EB_LOCK_TARGET;
1090
1091 while (current_size < extend_to)
1092 {
1093 uint32 num_pages = lengthof(buffers);
1095
1096 if ((uint64) current_size + num_pages > extend_to)
1097 num_pages = extend_to - current_size;
1098
1099 first_block = ExtendBufferedRelCommon(bmr, fork, strategy, flags,
1100 num_pages, extend_to,
1101 buffers, &extended_by);
1102
1104 Assert(num_pages != 0 || current_size >= extend_to);
1105
1106 for (uint32 i = 0; i < extended_by; i++)
1107 {
1108 if (first_block + i != extend_to - 1)
1109 ReleaseBuffer(buffers[i]);
1110 else
1111 buffer = buffers[i];
1112 }
1113 }
1114
1115 /*
1116 * It's possible that another backend concurrently extended the relation.
1117 * In that case read the buffer.
1118 *
1119 * XXX: Should we control this via a flag?
1120 */
1121 if (buffer == InvalidBuffer)
1122 {
1123 Assert(extended_by == 0);
1124 buffer = ReadBuffer_common(bmr.rel, BMR_GET_SMGR(bmr), bmr.relpersistence,
1125 fork, extend_to - 1, mode, strategy);
1126 }
1127
1128 return buffer;
1129}
1130
1131/*
1132 * Lock and optionally zero a buffer, as part of the implementation of
1133 * RBM_ZERO_AND_LOCK or RBM_ZERO_AND_CLEANUP_LOCK. The buffer must be already
1134 * pinned. If the buffer is not already valid, it is zeroed and made valid.
1135 */
1136static void
1138{
1140 bool need_to_zero;
1143
1145
1146 if (already_valid)
1147 {
1148 /*
1149 * If the caller already knew the buffer was valid, we can skip some
1150 * header interaction. The caller just wants to lock the buffer.
1151 */
1152 need_to_zero = false;
1153 }
1154 else
1155 {
1156 if (isLocalBuf)
1157 {
1158 /* Simple case for non-shared buffers. */
1160 sbres = StartLocalBufferIO(bufHdr, true, true, NULL);
1161 }
1162 else
1163 {
1164 /*
1165 * Take BM_IO_IN_PROGRESS, or discover that BM_VALID has been set
1166 * concurrently. Even though we aren't doing I/O, that ensures
1167 * that we don't zero a page that someone else has pinned. An
1168 * exclusive content lock wouldn't be enough, because readers are
1169 * allowed to drop the content lock after determining that a tuple
1170 * is visible (see buffer access rules in README).
1171 */
1173 sbres = StartSharedBufferIO(bufHdr, true, true, NULL);
1174 }
1175
1178 }
1179
1180 if (need_to_zero)
1181 {
1183
1184 /*
1185 * Grab the buffer content lock before marking the page as valid, to
1186 * make sure that no other backend sees the zeroed page before the
1187 * caller has had a chance to initialize it.
1188 *
1189 * Since no-one else can be looking at the page contents yet, there is
1190 * no difference between an exclusive lock and a cleanup-strength
1191 * lock. (Note that we cannot use LockBuffer() or
1192 * LockBufferForCleanup() here, because they assert that the buffer is
1193 * already valid.)
1194 */
1195 if (!isLocalBuf)
1197
1198 /* Set BM_VALID, terminate IO, and wake up any waiters */
1199 if (isLocalBuf)
1200 TerminateLocalBufferIO(bufHdr, false, BM_VALID, false);
1201 else
1202 TerminateBufferIO(bufHdr, false, BM_VALID, true, false);
1203 }
1204 else if (!isLocalBuf)
1205 {
1206 /*
1207 * The buffer is valid, so we can't zero it. The caller still expects
1208 * the page to be locked on return.
1209 */
1210 if (mode == RBM_ZERO_AND_LOCK)
1212 else
1214 }
1215}
1216
1217/*
1218 * Pin a buffer for a given block. *foundPtr is set to true if the block was
1219 * already present, or false if more work is required to either read it in or
1220 * zero it.
1221 */
1224 SMgrRelation smgr,
1225 char persistence,
1226 ForkNumber forkNum,
1227 BlockNumber blockNum,
1228 BufferAccessStrategy strategy,
1231 bool *foundPtr)
1232{
1234
1235 Assert(blockNum != P_NEW);
1236
1237 /* Persistence should be set before */
1238 Assert((persistence == RELPERSISTENCE_TEMP ||
1239 persistence == RELPERSISTENCE_PERMANENT ||
1240 persistence == RELPERSISTENCE_UNLOGGED));
1241
1242 TRACE_POSTGRESQL_BUFFER_READ_START(forkNum, blockNum,
1246 smgr->smgr_rlocator.backend);
1247
1248 if (persistence == RELPERSISTENCE_TEMP)
1249 bufHdr = LocalBufferAlloc(smgr, forkNum, blockNum, foundPtr);
1250 else
1251 bufHdr = BufferAlloc(smgr, persistence, forkNum, blockNum,
1252 strategy, foundPtr, io_context);
1253
1254 if (*foundPtr)
1255 TrackBufferHit(io_object, io_context, rel, persistence, smgr, forkNum, blockNum);
1256
1257 if (rel)
1258 {
1259 /*
1260 * While pgBufferUsage's "read" counter isn't bumped unless we reach
1261 * WaitReadBuffers() (so, not for hits, and not for buffers that are
1262 * zeroed instead), the per-relation stats always count them.
1263 */
1265 }
1266
1268}
1269
1270/*
1271 * ReadBuffer_common -- common logic for all ReadBuffer variants
1272 *
1273 * smgr is required, rel is optional unless using P_NEW.
1274 */
1277 ForkNumber forkNum,
1279 BufferAccessStrategy strategy)
1280{
1282 Buffer buffer;
1283 int flags;
1284 char persistence;
1285
1286 /*
1287 * Reject attempts to read non-local temporary relations; we would be
1288 * likely to get wrong data since we have no visibility into the owning
1289 * session's local buffers. This is the canonical place for the check,
1290 * covering the ReadBufferExtended() entry point and any other caller that
1291 * supplies a Relation.
1292 */
1293 if (rel && RELATION_IS_OTHER_TEMP(rel))
1294 ereport(ERROR,
1296 errmsg("cannot access temporary tables of other sessions")));
1297
1298 /*
1299 * Backward compatibility path, most code should use ExtendBufferedRel()
1300 * instead, as acquiring the extension lock inside ExtendBufferedRel()
1301 * scales a lot better.
1302 */
1303 if (unlikely(blockNum == P_NEW))
1304 {
1306
1307 /*
1308 * Since no-one else can be looking at the page contents yet, there is
1309 * no difference between an exclusive lock and a cleanup-strength
1310 * lock.
1311 */
1313 flags |= EB_LOCK_FIRST;
1314
1315 return ExtendBufferedRel(BMR_REL(rel), forkNum, strategy, flags);
1316 }
1317
1318 if (rel)
1319 persistence = rel->rd_rel->relpersistence;
1320 else
1321 persistence = smgr_persistence;
1322
1325 {
1326 bool found;
1329
1330 if (persistence == RELPERSISTENCE_TEMP)
1331 {
1334 }
1335 else
1336 {
1337 io_context = IOContextForStrategy(strategy);
1339 }
1340
1341 buffer = PinBufferForBlock(rel, smgr, persistence,
1342 forkNum, blockNum, strategy,
1343 io_object, io_context, &found);
1344 ZeroAndLockBuffer(buffer, mode, found);
1345 return buffer;
1346 }
1347
1348 /*
1349 * Signal that we are going to immediately wait. If we're immediately
1350 * waiting, there is no benefit in actually executing the IO
1351 * asynchronously, it would just add dispatch overhead.
1352 */
1354 if (mode == RBM_ZERO_ON_ERROR)
1356 operation.smgr = smgr;
1357 operation.rel = rel;
1358 operation.persistence = persistence;
1359 operation.forknum = forkNum;
1360 operation.strategy = strategy;
1362 &buffer,
1363 blockNum,
1364 flags))
1366
1367 return buffer;
1368}
1369
1370static pg_always_inline bool
1372 Buffer *buffers,
1373 BlockNumber blockNum,
1374 int *nblocks,
1375 int flags,
1376 bool allow_forwarding)
1377{
1378 int actual_nblocks = *nblocks;
1379 int maxcombine = 0;
1380 bool did_start_io;
1383
1384 Assert(*nblocks == 1 || allow_forwarding);
1385 Assert(*nblocks > 0);
1386 Assert(*nblocks <= MAX_IO_COMBINE_LIMIT);
1387
1388 /* see comments in ReadBuffer_common */
1389 if (operation->rel && RELATION_IS_OTHER_TEMP(operation->rel))
1390 ereport(ERROR,
1392 errmsg("cannot access temporary tables of other sessions")));
1393
1394 if (operation->persistence == RELPERSISTENCE_TEMP)
1395 {
1398 }
1399 else
1400 {
1403 }
1404
1405 for (int i = 0; i < actual_nblocks; ++i)
1406 {
1407 bool found;
1408
1409 if (allow_forwarding && buffers[i] != InvalidBuffer)
1410 {
1412
1413 /*
1414 * This is a buffer that was pinned by an earlier call to
1415 * StartReadBuffers(), but couldn't be handled in one operation at
1416 * that time. The operation was split, and the caller has passed
1417 * an already pinned buffer back to us to handle the rest of the
1418 * operation. It must continue at the expected block number.
1419 */
1420 Assert(BufferGetBlockNumber(buffers[i]) == blockNum + i);
1421
1422 /*
1423 * It might be an already valid buffer (a hit) that followed the
1424 * final contiguous block of an earlier I/O (a miss) marking the
1425 * end of it, or a buffer that some other backend has since made
1426 * valid by performing the I/O for us, in which case we can handle
1427 * it as a hit now. It is safe to check for a BM_VALID flag with
1428 * a relaxed load, because we got a fresh view of it while pinning
1429 * it in the previous call.
1430 *
1431 * On the other hand if we don't see BM_VALID yet, it must be an
1432 * I/O that was split by the previous call and we need to try to
1433 * start a new I/O from this block. We're also racing against any
1434 * other backend that might start the I/O or even manage to mark
1435 * it BM_VALID after this check, but StartBufferIO() will handle
1436 * those cases.
1437 */
1438 if (BufferIsLocal(buffers[i]))
1439 bufHdr = GetLocalBufferDescriptor(-buffers[i] - 1);
1440 else
1441 bufHdr = GetBufferDescriptor(buffers[i] - 1);
1443 found = pg_atomic_read_u64(&bufHdr->state) & BM_VALID;
1444 }
1445 else
1446 {
1447 buffers[i] = PinBufferForBlock(operation->rel,
1448 operation->smgr,
1449 operation->persistence,
1450 operation->forknum,
1451 blockNum + i,
1452 operation->strategy,
1454 &found);
1455 }
1456
1457 if (found)
1458 {
1459 /*
1460 * We have a hit. If it's the first block in the requested range,
1461 * we can return it immediately and report that WaitReadBuffers()
1462 * does not need to be called. If the initial value of *nblocks
1463 * was larger, the caller will have to call again for the rest.
1464 */
1465 if (i == 0)
1466 {
1467 *nblocks = 1;
1468
1469#ifdef USE_ASSERT_CHECKING
1470
1471 /*
1472 * Initialize enough of ReadBuffersOperation to make
1473 * CheckReadBuffersOperation() work. Outside of assertions
1474 * that's not necessary when no IO is issued.
1475 */
1476 operation->buffers = buffers;
1477 operation->blocknum = blockNum;
1478 operation->nblocks = 1;
1479 operation->nblocks_done = 1;
1481#endif
1482 return false;
1483 }
1484
1485 /*
1486 * Otherwise we already have an I/O to perform, but this block
1487 * can't be included as it is already valid. Split the I/O here.
1488 * There may or may not be more blocks requiring I/O after this
1489 * one, we haven't checked, but they can't be contiguous with this
1490 * one in the way. We'll leave this buffer pinned, forwarding it
1491 * to the next call, avoiding the need to unpin it here and re-pin
1492 * it in the next call.
1493 */
1494 actual_nblocks = i;
1495 break;
1496 }
1497 else
1498 {
1499 /*
1500 * Check how many blocks we can cover with the same IO. The smgr
1501 * implementation might e.g. be limited due to a segment boundary.
1502 */
1503 if (i == 0 && actual_nblocks > 1)
1504 {
1506 operation->forknum,
1507 blockNum);
1509 {
1510 elog(DEBUG2, "limiting nblocks at %u from %u to %u",
1511 blockNum, actual_nblocks, maxcombine);
1513 }
1514 }
1515 }
1516 }
1517 *nblocks = actual_nblocks;
1518
1519 /* Populate information needed for I/O. */
1520 operation->buffers = buffers;
1521 operation->blocknum = blockNum;
1522 operation->flags = flags;
1523 operation->nblocks = actual_nblocks;
1524 operation->nblocks_done = 0;
1525 pgaio_wref_clear(&operation->io_wref);
1526
1527 /*
1528 * When using AIO, start the IO in the background. If not, issue prefetch
1529 * requests if desired by the caller.
1530 *
1531 * The reason we have a dedicated path for IOMETHOD_SYNC here is to
1532 * de-risk the introduction of AIO somewhat. It's a large architectural
1533 * change, with lots of chances for unanticipated performance effects.
1534 *
1535 * Use of IOMETHOD_SYNC already leads to not actually performing IO
1536 * asynchronously, but without the check here we'd execute IO earlier than
1537 * we used to. Eventually this IOMETHOD_SYNC specific path should go away.
1538 */
1539 if (io_method != IOMETHOD_SYNC)
1540 {
1541 /*
1542 * Try to start IO asynchronously. It's possible that no IO needs to
1543 * be started, if another backend already performed the IO.
1544 *
1545 * Note that if an IO is started, it might not cover the entire
1546 * requested range, e.g. because an intermediary block has been read
1547 * in by another backend. In that case any "trailing" buffers we
1548 * already pinned above will be "forwarded" by read_stream.c to the
1549 * next call to StartReadBuffers().
1550 *
1551 * This is signalled to the caller by decrementing *nblocks *and*
1552 * reducing operation->nblocks. The latter is done here, but not below
1553 * WaitReadBuffers(), as in WaitReadBuffers() we can't "shorten" the
1554 * overall read size anymore, we need to retry until done in its
1555 * entirety or until failed.
1556 */
1558
1559 operation->nblocks = *nblocks;
1560 }
1561 else
1562 {
1564
1565 if (flags & READ_BUFFERS_ISSUE_ADVICE)
1566 {
1567 /*
1568 * In theory we should only do this if PinBufferForBlock() had to
1569 * allocate new buffers above. That way, if two calls to
1570 * StartReadBuffers() were made for the same blocks before
1571 * WaitReadBuffers(), only the first would issue the advice.
1572 * That'd be a better simulation of true asynchronous I/O, which
1573 * would only start the I/O once, but isn't done here for
1574 * simplicity.
1575 */
1576 smgrprefetch(operation->smgr,
1577 operation->forknum,
1578 blockNum,
1580 }
1581
1582 /*
1583 * Indicate that WaitReadBuffers() should be called. WaitReadBuffers()
1584 * will initiate the necessary IO.
1585 */
1586 did_start_io = true;
1587 }
1588
1590
1591 return did_start_io;
1592}
1593
1594/*
1595 * Begin reading a range of blocks beginning at blockNum and extending for
1596 * *nblocks. *nblocks and the buffers array are in/out parameters. On entry,
1597 * the buffers elements covered by *nblocks must hold either InvalidBuffer or
1598 * buffers forwarded by an earlier call to StartReadBuffers() that was split
1599 * and is now being continued. On return, *nblocks holds the number of blocks
1600 * accepted by this operation. If it is less than the original number then
1601 * this operation has been split, but buffer elements up to the original
1602 * requested size may hold forwarded buffers to be used for a continuing
1603 * operation. The caller must either start a new I/O beginning at the block
1604 * immediately following the blocks accepted by this call and pass those
1605 * buffers back in, or release them if it chooses not to. It shouldn't make
1606 * any other use of or assumptions about forwarded buffers.
1607 *
1608 * If false is returned, no I/O is necessary and the buffers covered by
1609 * *nblocks on exit are valid and ready to be accessed. If true is returned,
1610 * an I/O has been started, and WaitReadBuffers() must be called with the same
1611 * operation object before the buffers covered by *nblocks on exit can be
1612 * accessed. Along with the operation object, the caller-supplied array of
1613 * buffers must remain valid until WaitReadBuffers() is called, and any
1614 * forwarded buffers must also be preserved for a continuing call unless
1615 * they are explicitly released.
1616 */
1617bool
1619 Buffer *buffers,
1620 BlockNumber blockNum,
1621 int *nblocks,
1622 int flags)
1623{
1624 return StartReadBuffersImpl(operation, buffers, blockNum, nblocks, flags,
1625 true /* expect forwarded buffers */ );
1626}
1627
1628/*
1629 * Single block version of the StartReadBuffers(). This might save a few
1630 * instructions when called from another translation unit, because it is
1631 * specialized for nblocks == 1.
1632 *
1633 * This version does not support "forwarded" buffers: they cannot be created
1634 * by reading only one block and *buffer is ignored on entry.
1635 */
1636bool
1638 Buffer *buffer,
1639 BlockNumber blocknum,
1640 int flags)
1641{
1642 int nblocks = 1;
1643 bool result;
1644
1645 result = StartReadBuffersImpl(operation, buffer, blocknum, &nblocks, flags,
1646 false /* single block, no forwarding */ );
1647 Assert(nblocks == 1); /* single block can't be short */
1648
1649 return result;
1650}
1651
1652/*
1653 * Perform sanity checks on the ReadBuffersOperation.
1654 */
1655static void
1657{
1658#ifdef USE_ASSERT_CHECKING
1659 Assert(operation->nblocks_done <= operation->nblocks);
1660 Assert(!is_complete || operation->nblocks == operation->nblocks_done);
1661
1662 for (int i = 0; i < operation->nblocks; i++)
1663 {
1664 Buffer buffer = operation->buffers[i];
1668
1669 Assert(BufferGetBlockNumber(buffer) == operation->blocknum + i);
1671
1672 if (i < operation->nblocks_done)
1674 }
1675#endif
1676}
1677
1678/*
1679 * We track various stats related to buffer hits. Because this is done in a
1680 * few separate places, this helper exists for convenience.
1681 */
1682static pg_always_inline void
1684 Relation rel, char persistence, SMgrRelation smgr,
1685 ForkNumber forknum, BlockNumber blocknum)
1686{
1688 blocknum,
1692 smgr->smgr_rlocator.backend,
1693 true);
1694
1695 if (persistence == RELPERSISTENCE_TEMP)
1697 else
1699
1701
1702 if (VacuumCostActive)
1704
1705 if (rel)
1707}
1708
1709/*
1710 * Helper for WaitReadBuffers() that processes the results of a readv
1711 * operation, raising an error if necessary.
1712 */
1713static void
1715{
1716 PgAioReturn *aio_ret = &operation->io_return;
1718 int newly_read_blocks = 0;
1719
1720 Assert(pgaio_wref_valid(&operation->io_wref));
1721 Assert(aio_ret->result.status != PGAIO_RS_UNKNOWN);
1722
1723 /*
1724 * SMGR reports the number of blocks successfully read as the result of
1725 * the IO operation. Thus we can simply add that to ->nblocks_done.
1726 */
1727
1728 if (likely(rs != PGAIO_RS_ERROR))
1729 newly_read_blocks = aio_ret->result.result;
1730
1731 if (rs == PGAIO_RS_ERROR || rs == PGAIO_RS_WARNING)
1732 pgaio_result_report(aio_ret->result, &aio_ret->target_data,
1733 rs == PGAIO_RS_ERROR ? ERROR : WARNING);
1734 else if (aio_ret->result.status == PGAIO_RS_PARTIAL)
1735 {
1736 /*
1737 * We'll retry, so we just emit a debug message to the server log (or
1738 * not even that in prod scenarios).
1739 */
1740 pgaio_result_report(aio_ret->result, &aio_ret->target_data, DEBUG1);
1741 elog(DEBUG3, "partial read, will retry");
1742 }
1743
1746
1747 operation->nblocks_done += newly_read_blocks;
1748
1749 Assert(operation->nblocks_done <= operation->nblocks);
1750}
1751
1752/*
1753 * Wait for the IO operation initiated by StartReadBuffers() et al to
1754 * complete.
1755 *
1756 * Returns true if we needed to wait for the IO operation, false otherwise.
1757 */
1758bool
1760{
1761 PgAioReturn *aio_ret = &operation->io_return;
1764 bool needed_wait = false;
1765
1766 if (operation->persistence == RELPERSISTENCE_TEMP)
1767 {
1770 }
1771 else
1772 {
1775 }
1776
1777 /*
1778 * If we get here without an IO operation having been issued, the
1779 * io_method == IOMETHOD_SYNC path must have been used. Otherwise the
1780 * caller should not have called WaitReadBuffers().
1781 *
1782 * In the case of IOMETHOD_SYNC, we start - as we used to before the
1783 * introducing of AIO - the IO in WaitReadBuffers(). This is done as part
1784 * of the retry logic below, no extra code is required.
1785 *
1786 * This path is expected to eventually go away.
1787 */
1788 if (!pgaio_wref_valid(&operation->io_wref) && io_method != IOMETHOD_SYNC)
1789 elog(ERROR, "waiting for read operation that didn't read");
1790
1791 /*
1792 * To handle partial reads, and IOMETHOD_SYNC, we re-issue IO until we're
1793 * done. We may need multiple retries, not just because we could get
1794 * multiple partial reads, but also because some of the remaining
1795 * to-be-read buffers may have been read in by other backends, limiting
1796 * the IO size.
1797 */
1798 while (true)
1799 {
1801
1803
1804 /*
1805 * If there is an IO associated with the operation, we may need to
1806 * wait for it.
1807 */
1808 if (pgaio_wref_valid(&operation->io_wref))
1809 {
1810 /*
1811 * Track the time spent waiting for the IO to complete. As
1812 * tracking a wait even if we don't actually need to wait
1813 *
1814 * a) is not cheap, due to the timestamping overhead
1815 *
1816 * b) reports some time as waiting, even if we never waited
1817 *
1818 * we first check if we already know the IO is complete.
1819 *
1820 * Note that operation->io_return is uninitialized for foreign IO,
1821 * so we cannot use the cheaper PGAIO_RS_UNKNOWN pre-check.
1822 */
1823 if ((operation->foreign_io || aio_ret->result.status == PGAIO_RS_UNKNOWN) &&
1824 !pgaio_wref_check_done(&operation->io_wref))
1825 {
1827
1828 pgaio_wref_wait(&operation->io_wref);
1829 needed_wait = true;
1830
1831 /*
1832 * The IO operation itself was already counted earlier, in
1833 * AsyncReadBuffers(), this just accounts for the wait time.
1834 */
1836 io_start, 0, 0);
1837 }
1838 else
1839 {
1841 }
1842
1843 if (unlikely(operation->foreign_io))
1844 {
1845 Buffer buffer = operation->buffers[operation->nblocks_done];
1850
1851 if (buf_state & BM_VALID)
1852 {
1853 BlockNumber blocknum = operation->blocknum + operation->nblocks_done;
1854
1855 operation->nblocks_done += 1;
1856 Assert(operation->nblocks_done <= operation->nblocks);
1857
1858 /*
1859 * Track this as a 'hit' for this backend. The backend
1860 * performing the IO will track it as a 'read'.
1861 */
1863 operation->rel, operation->persistence,
1864 operation->smgr, operation->forknum,
1865 blocknum);
1866 }
1867
1868 /*
1869 * If the foreign IO failed and left the buffer invalid,
1870 * nblocks_done is not incremented. The retry loop below will
1871 * call AsyncReadBuffers() which will attempt the IO itself.
1872 */
1873 }
1874 else
1875 {
1876 /*
1877 * We now are sure the IO completed. Check the results. This
1878 * includes reporting on errors if there were any.
1879 */
1881 }
1882 }
1883
1884 /*
1885 * Most of the time, the one IO we already started, will read in
1886 * everything. But we need to deal with partial reads and buffers not
1887 * needing IO anymore.
1888 */
1889 if (operation->nblocks_done == operation->nblocks)
1890 break;
1891
1893
1894 /*
1895 * If the IO completed only partially, we need to perform additional
1896 * work, consider that a form of having had to wait.
1897 */
1898 needed_wait = true;
1899
1900 /*
1901 * This may only complete the IO partially, either because some
1902 * buffers were already valid, or because of a partial read.
1903 *
1904 * NB: In contrast to after the AsyncReadBuffers() call in
1905 * StartReadBuffers(), we do *not* reduce
1906 * ReadBuffersOperation->nblocks here, callers expect the full
1907 * operation to be completed at this point (as more operations may
1908 * have been queued).
1909 */
1911 }
1912
1914
1915 /* NB: READ_DONE tracepoint was already executed in completion callback */
1916 return needed_wait;
1917}
1918
1919/*
1920 * Initiate IO for the ReadBuffersOperation
1921 *
1922 * This function only starts a single IO at a time. The size of the IO may be
1923 * limited to below the to-be-read blocks, if one of the buffers has
1924 * concurrently been read in. If the first to-be-read buffer is already valid,
1925 * no IO will be issued.
1926 *
1927 * To support retries after partial reads, the first operation->nblocks_done
1928 * buffers are skipped.
1929 *
1930 * On return *nblocks_progress is updated to reflect the number of buffers
1931 * affected by the call. If the first buffer is valid, *nblocks_progress is
1932 * set to 1 and operation->nblocks_done is incremented.
1933 *
1934 * Returns true if IO was initiated or is already in progress (foreign IO),
1935 * false if the buffer was already valid.
1936 */
1937static bool
1939{
1940 Buffer *buffers = &operation->buffers[0];
1941 int flags = operation->flags;
1942 ForkNumber forknum = operation->forknum;
1943 char persistence = operation->persistence;
1944 int16 nblocks_done = operation->nblocks_done;
1945 BlockNumber blocknum = operation->blocknum + nblocks_done;
1946 Buffer *io_buffers = &operation->buffers[nblocks_done];
1947 int io_buffers_len = 0;
1949 uint32 ioh_flags = 0;
1955
1956 if (persistence == RELPERSISTENCE_TEMP)
1957 {
1960 }
1961 else
1962 {
1965 }
1966
1967 /*
1968 * When this IO is executed synchronously, either because the caller will
1969 * immediately block waiting for the IO or because IOMETHOD_SYNC is used,
1970 * the AIO subsystem needs to know.
1971 */
1972 if (flags & READ_BUFFERS_SYNCHRONOUSLY)
1974
1975 if (persistence == RELPERSISTENCE_TEMP)
1977
1978 /*
1979 * If zero_damaged_pages is enabled, add the READ_BUFFERS_ZERO_ON_ERROR
1980 * flag. The reason for that is that, hopefully, zero_damaged_pages isn't
1981 * set globally, but on a per-session basis. The completion callback,
1982 * which may be run in other processes, e.g. in IO workers, may have a
1983 * different value of the zero_damaged_pages GUC.
1984 *
1985 * XXX: We probably should eventually use a different flag for
1986 * zero_damaged_pages, so we can report different log levels / error codes
1987 * for zero_damaged_pages and ZERO_ON_ERROR.
1988 */
1991
1992 /*
1993 * For the same reason as with zero_damaged_pages we need to use this
1994 * backend's ignore_checksum_failure value.
1995 */
1998
1999
2000 /*
2001 * To be allowed to report stats in the local completion callback we need
2002 * to prepare to report stats now. This ensures we can safely report the
2003 * checksum failure even in a critical section.
2004 */
2005 pgstat_prepare_report_checksum_failure(operation->smgr->smgr_rlocator.locator.dbOid);
2006
2007 /*
2008 * We must get an IO handle before StartBufferIO(), as pgaio_io_acquire()
2009 * might block, which we don't want after setting IO_IN_PROGRESS. If we
2010 * don't need to do the IO, we'll release the handle.
2011 *
2012 * If we need to wait for IO before we can get a handle, submit
2013 * already-staged IO first, so that other backends don't need to wait.
2014 * There wouldn't be a deadlock risk, as pgaio_io_acquire() just needs to
2015 * wait for already submitted IO, which doesn't require additional locks,
2016 * but it could still cause undesirable waits.
2017 *
2018 * A secondary benefit is that this would allow us to measure the time in
2019 * pgaio_io_acquire() without causing undue timer overhead in the common,
2020 * non-blocking, case. However, currently the pgstats infrastructure
2021 * doesn't really allow that, as it a) asserts that an operation can't
2022 * have time without operations b) doesn't have an API to report
2023 * "accumulated" time.
2024 */
2026 if (unlikely(!ioh))
2027 {
2030 }
2031
2032 operation->foreign_io = false;
2033 pgaio_wref_clear(&operation->io_wref);
2034
2035 /*
2036 * Try to start IO on the first buffer in a new run of blocks. If AIO is
2037 * in progress, be it in this backend or another backend, we just
2038 * associate the wait reference with the operation and wait in
2039 * WaitReadBuffers(). This turns out to be important for performance in
2040 * two workloads:
2041 *
2042 * 1) A read stream that has to read the same block multiple times within
2043 * the readahead distance. This can happen e.g. for the table accesses of
2044 * an index scan.
2045 *
2046 * 2) Concurrent scans by multiple backends on the same relation.
2047 *
2048 * If we were to synchronously wait for the in-progress IO, we'd not be
2049 * able to keep enough I/O in flight.
2050 *
2051 * If we do find there is ongoing I/O for the buffer, we set up a 1-block
2052 * ReadBuffersOperation that WaitReadBuffers then can wait on.
2053 *
2054 * It's possible that another backend has started IO on the buffer but not
2055 * yet set its wait reference. In this case, we have no choice but to wait
2056 * for either the wait reference to be valid or the IO to be done.
2057 */
2058 status = StartBufferIO(buffers[nblocks_done], true, true,
2059 &operation->io_wref);
2061 {
2063 *nblocks_progress = 1;
2065 {
2066 /*
2067 * Someone has already completed this block, we're done.
2068 *
2069 * When IO is necessary, ->nblocks_done is updated in
2070 * ProcessReadBuffersResult(), but that is not called if no IO is
2071 * necessary. Thus update here.
2072 */
2073 operation->nblocks_done += 1;
2074 Assert(operation->nblocks_done <= operation->nblocks);
2075
2076 Assert(!pgaio_wref_valid(&operation->io_wref));
2077
2078 /*
2079 * Report and track this as a 'hit' for this backend, even though
2080 * it must have started out as a miss in PinBufferForBlock(). The
2081 * other backend will track this as a 'read'.
2082 */
2084 operation->rel, operation->persistence,
2085 operation->smgr, operation->forknum,
2086 blocknum);
2087 return false;
2088 }
2089
2090 /* The IO is already in-progress */
2092 Assert(pgaio_wref_valid(&operation->io_wref));
2093 operation->foreign_io = true;
2094
2095 return true;
2096 }
2097
2098 Assert(io_buffers[0] == buffers[nblocks_done]);
2099 io_pages[0] = BufferGetBlock(buffers[nblocks_done]);
2100 io_buffers_len = 1;
2101
2102 /*
2103 * NB: As little code as possible should be added between the
2104 * StartBufferIO() above, the further StartBufferIO()s below and the
2105 * smgrstartreadv(), as some of the buffers are now marked as
2106 * IO_IN_PROGRESS and will thus cause other backends to wait.
2107 */
2108
2109 /*
2110 * How many neighboring-on-disk blocks can we scatter-read into other
2111 * buffers at the same time? In this case we don't wait if we see an I/O
2112 * already in progress (see comment above).
2113 */
2114 for (int i = nblocks_done + 1; i < operation->nblocks; i++)
2115 {
2116 /* Must be consecutive block numbers. */
2117 Assert(BufferGetBlockNumber(buffers[i - 1]) ==
2118 BufferGetBlockNumber(buffers[i]) - 1);
2119
2120 status = StartBufferIO(buffers[i], true, false, NULL);
2122 break;
2123
2124 Assert(io_buffers[io_buffers_len] == buffers[i]);
2125
2126 io_pages[io_buffers_len++] = BufferGetBlock(buffers[i]);
2127 }
2128
2129 /* get a reference to wait for in WaitReadBuffers() */
2130 pgaio_io_get_wref(ioh, &operation->io_wref);
2131
2132 /* provide the list of buffers to the completion callbacks */
2134
2136 persistence == RELPERSISTENCE_TEMP ?
2139 flags);
2140
2142
2143 /* ---
2144 * Even though we're trying to issue IO asynchronously, track the time
2145 * in smgrstartreadv():
2146 * - if io_method == IOMETHOD_SYNC, we will always perform the IO
2147 * immediately
2148 * - the io method might not support the IO (e.g. worker IO for a temp
2149 * table)
2150 * ---
2151 */
2153 smgrstartreadv(ioh, operation->smgr, forknum,
2154 blocknum,
2158
2159 if (persistence == RELPERSISTENCE_TEMP)
2161 else
2163
2164 /*
2165 * Track vacuum cost when issuing IO, not after waiting for it. Otherwise
2166 * we could end up issuing a lot of IO in a short timespan, despite a low
2167 * cost limit.
2168 */
2169 if (VacuumCostActive)
2171
2173
2174 return true;
2175}
2176
2177/*
2178 * BufferAlloc -- subroutine for PinBufferForBlock. Handles lookup of a shared
2179 * buffer. If no buffer exists already, selects a replacement victim and
2180 * evicts the old page, but does NOT read in new page.
2181 *
2182 * "strategy" can be a buffer replacement strategy object, or NULL for
2183 * the default strategy. The selected buffer's usage_count is advanced when
2184 * using the default strategy, but otherwise possibly not (see PinBuffer).
2185 *
2186 * The returned buffer is pinned and is already marked as holding the
2187 * desired page. If it already did have the desired page, *foundPtr is
2188 * set true. Otherwise, *foundPtr is set false.
2189 *
2190 * io_context is passed as an output parameter to avoid calling
2191 * IOContextForStrategy() when there is a shared buffers hit and no IO
2192 * statistics need be captured.
2193 *
2194 * No locks are held either at entry or exit.
2195 */
2197BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
2198 BlockNumber blockNum,
2199 BufferAccessStrategy strategy,
2201{
2202 BufferTag newTag; /* identity of requested block */
2203 uint32 newHash; /* hash value for newTag */
2204 LWLock *newPartitionLock; /* buffer partition lock for it */
2205 int existing_buf_id;
2209 uint64 set_bits = 0;
2210
2211 /* Make sure we will have room to remember the buffer pin */
2214
2215 /* create a tag so we can lookup the buffer */
2216 InitBufferTag(&newTag, &smgr->smgr_rlocator.locator, forkNum, blockNum);
2217
2218 /* determine its hash code and partition lock ID */
2221
2222 /* see if the block is in the buffer pool already */
2225 if (existing_buf_id >= 0)
2226 {
2227 BufferDesc *buf;
2228 bool valid;
2229
2230 /*
2231 * Found it. Now, pin the buffer so no one can steal it from the
2232 * buffer pool, and check to see if the correct data has been loaded
2233 * into the buffer.
2234 */
2236
2237 valid = PinBuffer(buf, strategy, false);
2238
2239 /* Can release the mapping lock as soon as we've pinned it */
2241
2242 *foundPtr = true;
2243
2244 if (!valid)
2245 {
2246 /*
2247 * We can only get here if (a) someone else is still reading in
2248 * the page, (b) a previous read attempt failed, or (c) someone
2249 * called StartReadBuffers() but not yet WaitReadBuffers().
2250 */
2251 *foundPtr = false;
2252 }
2253
2254 return buf;
2255 }
2256
2257 /*
2258 * Didn't find it in the buffer pool. We'll have to initialize a new
2259 * buffer. Remember to unlock the mapping lock while doing the work.
2260 */
2262
2263 /*
2264 * Acquire a victim buffer. Somebody else might try to do the same, we
2265 * don't hold any conflicting locks. If so we'll have to undo our work
2266 * later.
2267 */
2270
2271 /*
2272 * Try to make a hashtable entry for the buffer under its new tag. If
2273 * somebody else inserted another buffer for the tag, we'll release the
2274 * victim buffer we acquired and use the already inserted one.
2275 */
2278 if (existing_buf_id >= 0)
2279 {
2281 bool valid;
2282
2283 /*
2284 * Got a collision. Someone has already done what we were about to do.
2285 * We'll just handle this as if it were found in the buffer pool in
2286 * the first place. First, give up the buffer we were planning to
2287 * use.
2288 *
2289 * We could do this after releasing the partition lock, but then we'd
2290 * have to call ResourceOwnerEnlarge() & ReservePrivateRefCountEntry()
2291 * before acquiring the lock, for the rare case of such a collision.
2292 */
2294
2295 /* remaining code should match code at top of routine */
2296
2298
2299 valid = PinBuffer(existing_buf_hdr, strategy, false);
2300
2301 /* Can release the mapping lock as soon as we've pinned it */
2303
2304 *foundPtr = true;
2305
2306 if (!valid)
2307 {
2308 /*
2309 * We can only get here if (a) someone else is still reading in
2310 * the page, (b) a previous read attempt failed, or (c) someone
2311 * called StartReadBuffers() but not yet WaitReadBuffers().
2312 */
2313 *foundPtr = false;
2314 }
2315
2316 return existing_buf_hdr;
2317 }
2318
2319 /*
2320 * Need to lock the buffer header too in order to change its tag.
2321 */
2323
2324 /* some sanity checks while we hold the buffer header lock */
2327
2328 victim_buf_hdr->tag = newTag;
2329
2330 /*
2331 * Make sure BM_PERMANENT is set for buffers that must be written at every
2332 * checkpoint. Unlogged buffers only need to be written at shutdown
2333 * checkpoints, except for their "init" forks, which need to be treated
2334 * just like permanent relations.
2335 */
2337 if (relpersistence == RELPERSISTENCE_PERMANENT || forkNum == INIT_FORKNUM)
2339
2341 set_bits, 0, 0);
2342
2344
2345 /*
2346 * Buffer contents are currently invalid.
2347 */
2348 *foundPtr = false;
2349
2350 return victim_buf_hdr;
2351}
2352
2353/*
2354 * InvalidateBuffer -- mark a shared buffer invalid.
2355 *
2356 * The buffer header spinlock must be held at entry. We drop it before
2357 * returning. (This is sane because the caller must have locked the
2358 * buffer in order to be sure it should be dropped.)
2359 *
2360 * This is used only in contexts such as dropping a relation. We assume
2361 * that no other backend could possibly be interested in using the page,
2362 * so the only reason the buffer might be pinned is if someone else is
2363 * trying to write it out. We have to let them finish before we can
2364 * reclaim the buffer.
2365 *
2366 * The buffer could get reclaimed by someone else while we are waiting
2367 * to acquire the necessary locks; if so, don't mess it up.
2368 */
2369static void
2371{
2373 uint32 oldHash; /* hash value for oldTag */
2374 LWLock *oldPartitionLock; /* buffer partition lock for it */
2377
2378 /* Save the original buffer tag before dropping the spinlock */
2379 oldTag = buf->tag;
2380
2382
2383 /*
2384 * Need to compute the old tag's hashcode and partition lock ID. XXX is it
2385 * worth storing the hashcode in BufferDesc so we need not recompute it
2386 * here? Probably not.
2387 */
2390
2391retry:
2392
2393 /*
2394 * Acquire exclusive mapping lock in preparation for changing the buffer's
2395 * association.
2396 */
2398
2399 /* Re-lock the buffer header */
2401
2402 /* If it's changed while we were waiting for lock, do nothing */
2403 if (!BufferTagsEqual(&buf->tag, &oldTag))
2404 {
2407 return;
2408 }
2409
2410 /*
2411 * We assume the reason for it to be pinned is that either we were
2412 * asynchronously reading the page in before erroring out or someone else
2413 * is flushing the page out. Wait for the IO to finish. (This could be
2414 * an infinite loop if the refcount is messed up... it would be nice to
2415 * time out after awhile, but there seems no way to be sure how many loops
2416 * may be needed. Note that if the other guy has pinned the buffer but
2417 * not yet done StartBufferIO, WaitIO will fall through and we'll
2418 * effectively be busy-looping here.)
2419 */
2421 {
2424 /* safety check: should definitely not be our *own* pin */
2426 elog(ERROR, "buffer is pinned in InvalidateBuffer");
2427 WaitIO(buf);
2428 goto retry;
2429 }
2430
2431 /*
2432 * An invalidated buffer should not have any backends waiting to lock the
2433 * buffer, therefore BM_LOCK_WAKE_IN_PROGRESS should not be set.
2434 */
2436
2437 /*
2438 * Clear out the buffer's tag and flags. We must do this to ensure that
2439 * linear scans of the buffer array don't think the buffer is valid.
2440 */
2442 ClearBufferTag(&buf->tag);
2443
2445 0,
2447 0);
2448
2449 /*
2450 * Remove the buffer from the lookup hashtable, if it was in there.
2451 */
2452 if (oldFlags & BM_TAG_VALID)
2454
2455 /*
2456 * Done with mapping lock.
2457 */
2459}
2460
2461/*
2462 * Helper routine for GetVictimBuffer()
2463 *
2464 * Needs to be called on a buffer with a valid tag, pinned, but without the
2465 * buffer header spinlock held.
2466 *
2467 * Returns true if the buffer can be reused, in which case the buffer is only
2468 * pinned by this backend and marked as invalid, false otherwise.
2469 */
2470static bool
2472{
2474 uint32 hash;
2476 BufferTag tag;
2477
2479
2480 /* have buffer pinned, so it's safe to read tag without lock */
2481 tag = buf_hdr->tag;
2482
2483 hash = BufTableHashCode(&tag);
2485
2487
2488 /* lock the buffer header */
2490
2491 /*
2492 * We have the buffer pinned nobody else should have been able to unset
2493 * this concurrently.
2494 */
2497 Assert(BufferTagsEqual(&buf_hdr->tag, &tag));
2498
2499 /*
2500 * If somebody else pinned the buffer since, or even worse, dirtied it,
2501 * give up on this buffer: It's clearly in use.
2502 */
2504 {
2506
2509
2510 return false;
2511 }
2512
2513 /*
2514 * An invalidated buffer should not have any backends waiting to lock the
2515 * buffer, therefore BM_LOCK_WAKE_IN_PROGRESS should not be set.
2516 */
2518
2519 /*
2520 * Clear out the buffer's tag and flags and usagecount. This is not
2521 * strictly required, as BM_TAG_VALID/BM_VALID needs to be checked before
2522 * doing anything with the buffer. But currently it's beneficial, as the
2523 * cheaper pre-check for several linear scans of shared buffers use the
2524 * tag (see e.g. FlushDatabaseBuffers()).
2525 */
2526 ClearBufferTag(&buf_hdr->tag);
2528 0,
2530 0);
2531
2533
2534 /* finally delete buffer from the buffer mapping table */
2535 BufTableDelete(&tag, hash);
2536
2538
2543
2544 return true;
2545}
2546
2547static Buffer
2549{
2551 Buffer buf;
2553 bool from_ring;
2554
2555 /*
2556 * Ensure, before we pin a victim buffer, that there's a free refcount
2557 * entry and resource owner slot for the pin.
2558 */
2561
2562 /* we return here if a prospective victim buffer gets used concurrently */
2563again:
2564
2565 /*
2566 * Select a victim buffer. The buffer is returned pinned and owned by
2567 * this backend.
2568 */
2571
2572 /*
2573 * We shouldn't have any other pins for this buffer.
2574 */
2576
2577 /*
2578 * If the buffer was dirty, try to write it out. There is a race
2579 * condition here, another backend could dirty the buffer between
2580 * StrategyGetBuffer() checking that it is not in use and invalidating the
2581 * buffer below. That's addressed by InvalidateVictimBuffer() verifying
2582 * that the buffer is not dirty.
2583 */
2584 if (buf_state & BM_DIRTY)
2585 {
2588
2589 /*
2590 * We need a share-exclusive lock on the buffer contents to write it
2591 * out (else we might write invalid data, eg because someone else is
2592 * compacting the page contents while we write). We must use a
2593 * conditional lock acquisition here to avoid deadlock. Even though
2594 * the buffer was not pinned (and therefore surely not locked) when
2595 * StrategyGetBuffer returned it, someone else could have pinned and
2596 * (share-)exclusive-locked it by the time we get here. If we try to
2597 * get the lock unconditionally, we'd block waiting for them; if they
2598 * later block waiting for us, deadlock ensues. (This has been
2599 * observed to happen when two backends are both trying to split btree
2600 * index pages, and the second one just happens to be trying to split
2601 * the page the first one got from StrategyGetBuffer.)
2602 */
2604 {
2605 /*
2606 * Someone else has locked the buffer, so give it up and loop back
2607 * to get another one.
2608 */
2610 goto again;
2611 }
2612
2613 /*
2614 * If using a nondefault strategy, and this victim came from the
2615 * strategy ring, let the strategy decide whether to reject it when
2616 * reusing it would require a WAL flush. This only applies to
2617 * permanent buffers; unlogged buffers can have fake LSNs, so
2618 * XLogNeedsFlush() is not meaningful for them.
2619 *
2620 * We need to hold the content lock in at least share-exclusive mode
2621 * to safely inspect the page LSN, so this couldn't have been done
2622 * inside StrategyGetBuffer().
2623 */
2624 if (strategy && from_ring &&
2628 {
2630 goto again;
2631 }
2632
2633 /* OK, do the I/O */
2636
2638 &buf_hdr->tag);
2639 }
2640
2641
2642 if (buf_state & BM_VALID)
2643 {
2644 /*
2645 * When a BufferAccessStrategy is in use, blocks evicted from shared
2646 * buffers are counted as IOOP_EVICT in the corresponding context
2647 * (e.g. IOCONTEXT_BULKWRITE). Shared buffers are evicted by a
2648 * strategy in two cases: 1) while initially claiming buffers for the
2649 * strategy ring 2) to replace an existing strategy ring buffer
2650 * because it is pinned or in use and cannot be reused.
2651 *
2652 * Blocks evicted from buffers already in the strategy ring are
2653 * counted as IOOP_REUSE in the corresponding strategy context.
2654 *
2655 * At this point, we can accurately count evictions and reuses,
2656 * because we have successfully claimed the valid buffer. Previously,
2657 * we may have been forced to release the buffer due to concurrent
2658 * pinners or erroring out.
2659 */
2661 from_ring ? IOOP_REUSE : IOOP_EVICT, 1, 0);
2662 }
2663
2664 /*
2665 * If the buffer has an entry in the buffer mapping table, delete it. This
2666 * can fail because another backend could have pinned or dirtied the
2667 * buffer.
2668 */
2670 {
2672 goto again;
2673 }
2674
2675 /* a final set of sanity checks */
2676#ifdef USE_ASSERT_CHECKING
2678
2681
2683#endif
2684
2685 return buf;
2686}
2687
2688/*
2689 * Return the maximum number of buffers that a backend should try to pin once,
2690 * to avoid exceeding its fair share. This is the highest value that
2691 * GetAdditionalPinLimit() could ever return. Note that it may be zero on a
2692 * system with a very small buffer pool relative to max_connections.
2693 */
2694uint32
2696{
2697 return MaxProportionalPins;
2698}
2699
2700/*
2701 * Return the maximum number of additional buffers that this backend should
2702 * pin if it wants to stay under the per-backend limit, considering the number
2703 * of buffers it has already pinned. Unlike LimitAdditionalPins(), the limit
2704 * return by this function can be zero.
2705 */
2706uint32
2708{
2710
2711 /*
2712 * We get the number of "overflowed" pins for free, but don't know the
2713 * number of pins in PrivateRefCountArray. The cost of calculating that
2714 * exactly doesn't seem worth it, so just assume the max.
2715 */
2717
2718 /* Is this backend already holding more than its fair share? */
2720 return 0;
2721
2723}
2724
2725/*
2726 * Limit the number of pins a batch operation may additionally acquire, to
2727 * avoid running out of pinnable buffers.
2728 *
2729 * One additional pin is always allowed, on the assumption that the operation
2730 * requires at least one to make progress.
2731 */
2732void
2734{
2735 uint32 limit;
2736
2737 if (*additional_pins <= 1)
2738 return;
2739
2740 limit = GetAdditionalPinLimit();
2741 limit = Max(limit, 1);
2742 if (limit < *additional_pins)
2743 *additional_pins = limit;
2744}
2745
2746/*
2747 * Logic shared between ExtendBufferedRelBy(), ExtendBufferedRelTo(). Just to
2748 * avoid duplicating the tracing and relpersistence related logic.
2749 */
2750static BlockNumber
2753 BufferAccessStrategy strategy,
2754 uint32 flags,
2757 Buffer *buffers,
2759{
2761
2763 BMR_GET_SMGR(bmr)->smgr_rlocator.locator.spcOid,
2764 BMR_GET_SMGR(bmr)->smgr_rlocator.locator.dbOid,
2765 BMR_GET_SMGR(bmr)->smgr_rlocator.locator.relNumber,
2766 BMR_GET_SMGR(bmr)->smgr_rlocator.backend,
2767 extend_by);
2768
2769 if (bmr.relpersistence == RELPERSISTENCE_TEMP)
2770 {
2771 /*
2772 * Reject attempts to extend non-local temporary relations; we have no
2773 * ability to transfer about-to-be-created local buffers into the
2774 * owning session's local buffers. This is the canonical place for
2775 * the check, covering any attempt to extend a non-local temporary
2776 * relation.
2777 */
2778 if (bmr.rel && RELATION_IS_OTHER_TEMP(bmr.rel))
2779 ereport(ERROR,
2781 errmsg("cannot access temporary tables of other sessions")));
2782
2785 buffers, &extend_by);
2786 }
2787 else
2788 first_block = ExtendBufferedRelShared(bmr, fork, strategy, flags,
2790 buffers, &extend_by);
2792
2794 BMR_GET_SMGR(bmr)->smgr_rlocator.locator.spcOid,
2795 BMR_GET_SMGR(bmr)->smgr_rlocator.locator.dbOid,
2796 BMR_GET_SMGR(bmr)->smgr_rlocator.locator.relNumber,
2797 BMR_GET_SMGR(bmr)->smgr_rlocator.backend,
2798 *extended_by,
2799 first_block);
2800
2801 return first_block;
2802}
2803
2804/*
2805 * Implementation of ExtendBufferedRelBy() and ExtendBufferedRelTo() for
2806 * shared buffers.
2807 */
2808static BlockNumber
2811 BufferAccessStrategy strategy,
2812 uint32 flags,
2815 Buffer *buffers,
2817{
2821
2823
2824 /*
2825 * Acquire victim buffers for extension without holding extension lock.
2826 * Writing out victim buffers is the most expensive part of extending the
2827 * relation, particularly when doing so requires WAL flushes. Zeroing out
2828 * the buffers is also quite expensive, so do that before holding the
2829 * extension lock as well.
2830 *
2831 * These pages are pinned by us and not valid. While we hold the pin they
2832 * can't be acquired as victim buffers by another backend.
2833 */
2834 for (uint32 i = 0; i < extend_by; i++)
2835 {
2837
2838 buffers[i] = GetVictimBuffer(strategy, io_context);
2840
2841 /* new buffers are zero-filled */
2842 MemSet(buf_block, 0, BLCKSZ);
2843 }
2844
2845 /*
2846 * Lock relation against concurrent extensions, unless requested not to.
2847 *
2848 * We use the same extension lock for all forks. That's unnecessarily
2849 * restrictive, but currently extensions for forks don't happen often
2850 * enough to make it worth locking more granularly.
2851 *
2852 * Note that another backend might have extended the relation by the time
2853 * we get the lock.
2854 */
2855 if (!(flags & EB_SKIP_EXTENSION_LOCK))
2857
2858 /*
2859 * If requested, invalidate size cache, so that smgrnblocks asks the
2860 * kernel.
2861 */
2862 if (flags & EB_CLEAR_SIZE_CACHE)
2863 BMR_GET_SMGR(bmr)->smgr_cached_nblocks[fork] = InvalidBlockNumber;
2864
2866
2867 /*
2868 * Now that we have the accurate relation size, check if the caller wants
2869 * us to extend to only up to a specific size. If there were concurrent
2870 * extensions, we might have acquired too many buffers and need to release
2871 * them.
2872 */
2874 {
2876
2878 extend_by = 0;
2879 else if ((uint64) first_block + extend_by > extend_upto)
2881
2882 for (uint32 i = extend_by; i < orig_extend_by; i++)
2883 {
2884 BufferDesc *buf_hdr = GetBufferDescriptor(buffers[i] - 1);
2885
2887 }
2888
2889 if (extend_by == 0)
2890 {
2891 if (!(flags & EB_SKIP_EXTENSION_LOCK))
2894 return first_block;
2895 }
2896 }
2897
2898 /* Fail if relation is already at maximum possible length */
2900 ereport(ERROR,
2902 errmsg("cannot extend relation %s beyond %u blocks",
2903 relpath(BMR_GET_SMGR(bmr)->smgr_rlocator, fork).str,
2904 MaxBlockNumber)));
2905
2906 /*
2907 * Insert buffers into buffer table, mark as IO_IN_PROGRESS.
2908 *
2909 * This needs to happen before we extend the relation, because as soon as
2910 * we do, other backends can start to read in those pages.
2911 */
2912 for (uint32 i = 0; i < extend_by; i++)
2913 {
2914 Buffer victim_buf = buffers[i];
2916 BufferTag tag;
2917 uint32 hash;
2919 int existing_id;
2920
2921 /* in case we need to pin an existing buffer below */
2924
2925 InitBufferTag(&tag, &BMR_GET_SMGR(bmr)->smgr_rlocator.locator, fork,
2926 first_block + i);
2927 hash = BufTableHashCode(&tag);
2929
2931
2933
2934 /*
2935 * We get here only in the corner case where we are trying to extend
2936 * the relation but we found a pre-existing buffer. This can happen
2937 * because a prior attempt at extending the relation failed, and
2938 * because mdread doesn't complain about reads beyond EOF (when
2939 * zero_damaged_pages is ON) and so a previous attempt to read a block
2940 * beyond EOF could have left a "valid" zero-filled buffer.
2941 *
2942 * This has also been observed when relation was overwritten by
2943 * external process. Since the legitimate cases should always have
2944 * left a zero-filled buffer, complain if not PageIsNew.
2945 */
2946 if (existing_id >= 0)
2947 {
2950 bool valid;
2951
2952 /*
2953 * Pin the existing buffer before releasing the partition lock,
2954 * preventing it from being evicted.
2955 */
2956 valid = PinBuffer(existing_hdr, strategy, false);
2957
2960
2963
2964 if (valid && !PageIsNew((Page) buf_block))
2965 ereport(ERROR,
2966 (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
2967 existing_hdr->tag.blockNum,
2968 relpath(BMR_GET_SMGR(bmr)->smgr_rlocator, fork).str)));
2969
2970 /*
2971 * We *must* do smgr[zero]extend before succeeding, else the page
2972 * will not be reserved by the kernel, and the next P_NEW call
2973 * will decide to return the same page. Clear the BM_VALID bit,
2974 * do StartSharedBufferIO() and proceed.
2975 *
2976 * Loop to handle the very small possibility that someone re-sets
2977 * BM_VALID between our clearing it and StartSharedBufferIO
2978 * inspecting it.
2979 */
2980 while (true)
2981 {
2983
2985
2987
2989 break;
2990 }
2991 }
2992 else
2993 {
2995 uint64 set_bits = 0;
2996
2998
2999 /* some sanity checks while we hold the buffer header lock */
3002
3003 victim_buf_hdr->tag = tag;
3004
3006 if (bmr.relpersistence == RELPERSISTENCE_PERMANENT || fork == INIT_FORKNUM)
3008
3010 set_bits, 0,
3011 0);
3012
3014
3015 /* XXX: could combine the locked operations in it with the above */
3017 }
3018 }
3019
3021
3022 /*
3023 * Note: if smgrzeroextend fails, we will end up with buffers that are
3024 * allocated but not marked BM_VALID. The next relation extension will
3025 * still select the same block number (because the relation didn't get any
3026 * longer on disk) and so future attempts to extend the relation will find
3027 * the same buffers (if they have not been recycled) but come right back
3028 * here to try smgrzeroextend again.
3029 *
3030 * We don't need to set checksum for all-zero pages.
3031 */
3033
3034 /*
3035 * Release the file-extension lock; it's now OK for someone else to extend
3036 * the relation some more.
3037 *
3038 * We remove IO_IN_PROGRESS after this, as waking up waiting backends can
3039 * take noticeable time.
3040 */
3041 if (!(flags & EB_SKIP_EXTENSION_LOCK))
3043
3045 io_start, 1, extend_by * BLCKSZ);
3046
3047 /* Set BM_VALID, terminate IO, and wake up any waiters */
3048 for (uint32 i = 0; i < extend_by; i++)
3049 {
3050 Buffer buf = buffers[i];
3052 bool lock = false;
3053
3054 if (flags & EB_LOCK_FIRST && i == 0)
3055 lock = true;
3056 else if (flags & EB_LOCK_TARGET)
3057 {
3059 if (first_block + i + 1 == extend_upto)
3060 lock = true;
3061 }
3062
3063 if (lock)
3065
3066 TerminateBufferIO(buf_hdr, false, BM_VALID, true, false);
3067 }
3068
3070
3072
3073 return first_block;
3074}
3075
3076/*
3077 * BufferIsLockedByMe
3078 *
3079 * Checks if this backend has the buffer locked in any mode.
3080 *
3081 * Buffer must be pinned.
3082 */
3083bool
3085{
3087
3089
3090 if (BufferIsLocal(buffer))
3091 {
3092 /* Content locks are not maintained for local buffers. */
3093 return true;
3094 }
3095 else
3096 {
3098 return BufferLockHeldByMe(bufHdr);
3099 }
3100}
3101
3102/*
3103 * BufferIsLockedByMeInMode
3104 *
3105 * Checks if this backend has the buffer locked in the specified mode.
3106 *
3107 * Buffer must be pinned.
3108 */
3109bool
3111{
3113
3115
3116 if (BufferIsLocal(buffer))
3117 {
3118 /* Content locks are not maintained for local buffers. */
3119 return true;
3120 }
3121 else
3122 {
3125 }
3126}
3127
3128/*
3129 * BufferIsDirty
3130 *
3131 * Checks if buffer is already dirty.
3132 *
3133 * Buffer must be pinned and [share-]exclusive-locked. (Without such a lock,
3134 * the result may be stale before it's returned.)
3135 */
3136bool
3138{
3140
3142
3143 if (BufferIsLocal(buffer))
3144 {
3145 int bufid = -buffer - 1;
3146
3148 /* Content locks are not maintained for local buffers. */
3149 }
3150 else
3151 {
3155 }
3156
3157 return pg_atomic_read_u64(&bufHdr->state) & BM_DIRTY;
3158}
3159
3160/*
3161 * MarkBufferDirty
3162 *
3163 * Marks buffer contents as dirty (actual write happens later).
3164 *
3165 * Buffer must be pinned and exclusive-locked. (If caller does not hold
3166 * exclusive lock, then somebody could be in process of writing the buffer,
3167 * leading to risk of bad data written to disk.)
3168 */
3169void
3171{
3175
3176 if (!BufferIsValid(buffer))
3177 elog(ERROR, "bad buffer ID: %d", buffer);
3178
3179 if (BufferIsLocal(buffer))
3180 {
3182 return;
3183 }
3184
3186
3189
3190 /*
3191 * NB: We have to wait for the buffer header spinlock to be not held, as
3192 * TerminateBufferIO() relies on the spinlock.
3193 */
3195 for (;;)
3196 {
3199
3201
3204
3206 buf_state))
3207 break;
3208 }
3209
3210 /*
3211 * If the buffer was not dirty already, do vacuum accounting.
3212 */
3213 if (!(old_buf_state & BM_DIRTY))
3214 {
3216 if (VacuumCostActive)
3218 }
3219}
3220
3221/*
3222 * ReleaseAndReadBuffer -- combine ReleaseBuffer() and ReadBuffer()
3223 *
3224 * Formerly, this saved one cycle of acquiring/releasing the BufMgrLock
3225 * compared to calling the two routines separately. Now it's mainly just
3226 * a convenience function. However, if the passed buffer is valid and
3227 * already contains the desired block, we just return it as-is; and that
3228 * does save considerable work compared to a full release and reacquire.
3229 *
3230 * Note: it is OK to pass buffer == InvalidBuffer, indicating that no old
3231 * buffer actually needs to be released. This case is the same as ReadBuffer,
3232 * but can save some tests in the caller.
3233 */
3234Buffer
3236 Relation relation,
3237 BlockNumber blockNum)
3238{
3239 ForkNumber forkNum = MAIN_FORKNUM;
3241
3242 if (BufferIsValid(buffer))
3243 {
3245 if (BufferIsLocal(buffer))
3246 {
3248 if (bufHdr->tag.blockNum == blockNum &&
3249 BufTagMatchesRelFileLocator(&bufHdr->tag, &relation->rd_locator) &&
3250 BufTagGetForkNum(&bufHdr->tag) == forkNum)
3251 return buffer;
3253 }
3254 else
3255 {
3257 /* we have pin, so it's ok to examine tag without spinlock */
3258 if (bufHdr->tag.blockNum == blockNum &&
3259 BufTagMatchesRelFileLocator(&bufHdr->tag, &relation->rd_locator) &&
3260 BufTagGetForkNum(&bufHdr->tag) == forkNum)
3261 return buffer;
3263 }
3264 }
3265
3266 return ReadBuffer(relation, blockNum);
3267}
3268
3269/*
3270 * PinBuffer -- make buffer unavailable for replacement.
3271 *
3272 * For the default access strategy, the buffer's usage_count is incremented
3273 * when we first pin it; for other strategies we just make sure the usage_count
3274 * isn't zero. (The idea of the latter is that we don't want synchronized
3275 * heap scans to inflate the count, but we need it to not be zero to discourage
3276 * other backends from stealing buffers from our ring. As long as we cycle
3277 * through the ring faster than the global clock-sweep cycles, buffers in
3278 * our ring won't be chosen as victims for replacement by other backends.)
3279 *
3280 * This should be applied only to shared buffers, never local ones.
3281 *
3282 * Since buffers are pinned/unpinned very frequently, pin buffers without
3283 * taking the buffer header lock; instead update the state variable in loop of
3284 * CAS operations. Hopefully it's just a single CAS.
3285 *
3286 * Note that ResourceOwnerEnlarge() and ReservePrivateRefCountEntry()
3287 * must have been done already.
3288 *
3289 * Returns true if buffer is BM_VALID, else false. This provision allows
3290 * some callers to avoid an extra spinlock cycle. If skip_if_not_valid is
3291 * true, then a false return value also indicates that the buffer was
3292 * (recently) invalid and has not been pinned.
3293 */
3294static bool
3296 bool skip_if_not_valid)
3297{
3299 bool result;
3301
3304
3305 ref = GetPrivateRefCountEntry(b, true);
3306
3307 if (ref == NULL)
3308 {
3311
3313 for (;;)
3314 {
3316 return false;
3317
3318 /*
3319 * We're not allowed to increase the refcount while the buffer
3320 * header spinlock is held. Wait for the lock to be released.
3321 */
3323 {
3325
3326 /* perform checks at the top of the loop again */
3327 continue;
3328 }
3329
3331
3332 /* increase refcount */
3334
3335 if (strategy == NULL)
3336 {
3337 /* Default case: increase usagecount unless already max. */
3340 }
3341 else
3342 {
3343 /*
3344 * Ring buffers shouldn't evict others from pool. Thus we
3345 * don't make usagecount more than 1.
3346 */
3349 }
3350
3352 buf_state))
3353 {
3354 result = (buf_state & BM_VALID) != 0;
3355
3357 break;
3358 }
3359 }
3360 }
3361 else
3362 {
3363 /*
3364 * If we previously pinned the buffer, it is likely to be valid, but
3365 * it may not be if StartReadBuffers() was called and
3366 * WaitReadBuffers() hasn't been called yet. We'll check by loading
3367 * the flags without locking. This is racy, but it's OK to return
3368 * false spuriously: when WaitReadBuffers() calls StartBufferIO(),
3369 * it'll see that it's now valid.
3370 *
3371 * Note: We deliberately avoid a Valgrind client request here.
3372 * Individual access methods can optionally superimpose buffer page
3373 * client requests on top of our client requests to enforce that
3374 * buffers are only accessed while locked (and pinned). It's possible
3375 * that the buffer page is legitimately non-accessible here. We
3376 * cannot meddle with that.
3377 */
3378 result = (pg_atomic_read_u64(&buf->state) & BM_VALID) != 0;
3379
3380 Assert(ref->data.refcount > 0);
3381 ref->data.refcount++;
3383 }
3384
3385 return result;
3386}
3387
3388/*
3389 * PinBuffer_Locked -- as above, but caller already locked the buffer header.
3390 * The spinlock is released before return.
3391 *
3392 * As this function is called with the spinlock held, the caller has to
3393 * previously call ReservePrivateRefCountEntry() and
3394 * ResourceOwnerEnlarge(CurrentResourceOwner);
3395 *
3396 * Currently, no callers of this function want to modify the buffer's
3397 * usage_count at all, so there's no need for a strategy parameter.
3398 * Also we don't bother with a BM_VALID test (the caller could check that for
3399 * itself).
3400 *
3401 * Also all callers only ever use this function when it's known that the
3402 * buffer can't have a preexisting pin by this backend. That allows us to skip
3403 * searching the private refcount array & hash, which is a boon, because the
3404 * spinlock is still held.
3405 *
3406 * Note: use of this routine is frequently mandatory, not just an optimization
3407 * to save a spin lock/unlock cycle, because we need to pin a buffer before
3408 * its state can change under us.
3409 */
3410static void
3412{
3414
3415 /*
3416 * As explained, We don't expect any preexisting pins. That allows us to
3417 * manipulate the PrivateRefCount after releasing the spinlock
3418 */
3420
3421 /*
3422 * Since we hold the buffer spinlock, we can update the buffer state and
3423 * release the lock in one operation.
3424 */
3426
3428 0, 0, 1);
3429
3431}
3432
3433/*
3434 * Support for waking up another backend that is waiting for the cleanup lock
3435 * to be released using BM_PIN_COUNT_WAITER.
3436 *
3437 * See LockBufferForCleanup().
3438 *
3439 * Expected to be called just after releasing a buffer pin (in a BufferDesc,
3440 * not just reducing the backend-local pincount for the buffer).
3441 */
3442static void
3444{
3445 /*
3446 * Acquire the buffer header lock, re-check that there's a waiter. Another
3447 * backend could have unpinned this buffer, and already woken up the
3448 * waiter.
3449 *
3450 * There's no danger of the buffer being replaced after we unpinned it
3451 * above, as it's pinned by the waiter. The waiter removes
3452 * BM_PIN_COUNT_WAITER if it stops waiting for a reason other than this
3453 * backend waking it up.
3454 */
3456
3459 {
3460 /* we just released the last pin other than the waiter's */
3461 int wait_backend_pgprocno = buf->wait_backend_pgprocno;
3462
3465 0);
3466 ProcSendSignal(wait_backend_pgprocno);
3467 }
3468 else
3470}
3471
3472/*
3473 * UnpinBuffer -- make buffer available for replacement.
3474 *
3475 * This should be applied only to shared buffers, never local ones. This
3476 * always adjusts CurrentResourceOwner.
3477 */
3478static void
3486
3487static void
3489{
3492
3494
3495 /* not moving as we're likely deleting it soon anyway */
3496 ref = GetPrivateRefCountEntry(b, false);
3497 Assert(ref != NULL);
3498 Assert(ref->data.refcount > 0);
3499 ref->data.refcount--;
3500 if (ref->data.refcount == 0)
3501 {
3503
3504 /*
3505 * Mark buffer non-accessible to Valgrind.
3506 *
3507 * Note that the buffer may have already been marked non-accessible
3508 * within access method code that enforces that buffers are only
3509 * accessed while a buffer lock is held.
3510 */
3512
3513 /*
3514 * I'd better not still hold the buffer content lock. Can't use
3515 * BufferIsLockedByMe(), as that asserts the buffer is pinned.
3516 */
3518
3519 /* decrement the shared reference count */
3521
3522 /* Support LockBufferForCleanup() */
3525
3527 }
3528}
3529
3530/*
3531 * Set up backend-local tracking of a buffer pinned the first time by this
3532 * backend.
3533 */
3534inline void
3536{
3538
3540 ref->data.refcount++;
3541
3543
3544 /*
3545 * This is the first pin for this page by this backend, mark its page as
3546 * defined to valgrind. While the page contents might not actually be
3547 * valid yet, we don't currently guarantee that such pages are marked
3548 * undefined or non-accessible.
3549 *
3550 * It's not necessarily the prettiest to do this here, but otherwise we'd
3551 * need this block of code in multiple places.
3552 */
3554 BLCKSZ);
3555}
3556
3557#define ST_SORT sort_checkpoint_bufferids
3558#define ST_ELEMENT_TYPE CkptSortItem
3559#define ST_COMPARE(a, b) ckpt_buforder_comparator(a, b)
3560#define ST_SCOPE static
3561#define ST_DEFINE
3562#include "lib/sort_template.h"
3563
3564/*
3565 * BufferSync -- Write out all dirty buffers in the pool.
3566 *
3567 * This is called at checkpoint time to write out all dirty shared buffers.
3568 * The checkpoint request flags should be passed in. If CHECKPOINT_FAST is
3569 * set, we disable delays between writes; if CHECKPOINT_IS_SHUTDOWN,
3570 * CHECKPOINT_END_OF_RECOVERY or CHECKPOINT_FLUSH_UNLOGGED is set, we write
3571 * even unlogged buffers, which are otherwise skipped. The remaining flags
3572 * currently have no effect here.
3573 */
3574static void
3575BufferSync(int flags)
3576{
3578 int buf_id;
3579 int num_to_scan;
3580 int num_spaces;
3581 int num_processed;
3582 int num_written;
3584 Oid last_tsid;
3586 int i;
3587 uint64 mask = BM_DIRTY;
3589
3590 /*
3591 * Unless this is a shutdown checkpoint or we have been explicitly told,
3592 * we write only permanent, dirty buffers. But at shutdown or end of
3593 * recovery, we write all dirty buffers.
3594 */
3597 mask |= BM_PERMANENT;
3598
3599 /*
3600 * Loop over all buffers, and mark the ones that need to be written with
3601 * BM_CHECKPOINT_NEEDED. Count them as we go (num_to_scan), so that we
3602 * can estimate how much work needs to be done.
3603 *
3604 * This allows us to write only those pages that were dirty when the
3605 * checkpoint began, and not those that get dirtied while it proceeds.
3606 * Whenever a page with BM_CHECKPOINT_NEEDED is written out, either by us
3607 * later in this function, or by normal backends or the bgwriter cleaning
3608 * scan, the flag is cleared. Any buffer dirtied after this point won't
3609 * have the flag set.
3610 *
3611 * Note that if we fail to write some buffer, we may leave buffers with
3612 * BM_CHECKPOINT_NEEDED still set. This is OK since any such buffer would
3613 * certainly need to be written for the next checkpoint attempt, too.
3614 */
3615 num_to_scan = 0;
3616 for (buf_id = 0; buf_id < NBuffers; buf_id++)
3617 {
3619 uint64 set_bits = 0;
3620
3621 /*
3622 * Header spinlock is enough to examine BM_DIRTY, see comment in
3623 * SyncOneBuffer.
3624 */
3626
3627 if ((buf_state & mask) == mask)
3628 {
3629 CkptSortItem *item;
3630
3632
3633 item = &CkptBufferIds[num_to_scan++];
3634 item->buf_id = buf_id;
3635 item->tsId = bufHdr->tag.spcOid;
3636 item->relNumber = BufTagGetRelNumber(&bufHdr->tag);
3637 item->forkNum = BufTagGetForkNum(&bufHdr->tag);
3638 item->blockNum = bufHdr->tag.blockNum;
3639 }
3640
3642 set_bits, 0,
3643 0);
3644
3645 /* Check for barrier events in case NBuffers is large. */
3648 }
3649
3650 if (num_to_scan == 0)
3651 return; /* nothing to do */
3652
3654
3656
3657 /*
3658 * Sort buffers that need to be written to reduce the likelihood of random
3659 * IO. The sorting is also important for the implementation of balancing
3660 * writes between tablespaces. Without balancing writes we'd potentially
3661 * end up writing to the tablespaces one-by-one; possibly overloading the
3662 * underlying system.
3663 */
3665
3666 num_spaces = 0;
3667
3668 /*
3669 * Allocate progress status for each tablespace with buffers that need to
3670 * be flushed. This requires the to-be-flushed array to be sorted.
3671 */
3673 for (i = 0; i < num_to_scan; i++)
3674 {
3675 CkptTsStatus *s;
3676 Oid cur_tsid;
3677
3679
3680 /*
3681 * Grow array of per-tablespace status structs, every time a new
3682 * tablespace is found.
3683 */
3685 {
3686 Size sz;
3687
3688 num_spaces++;
3689
3690 /*
3691 * Not worth adding grow-by-power-of-2 logic here - even with a
3692 * few hundred tablespaces this should be fine.
3693 */
3694 sz = sizeof(CkptTsStatus) * num_spaces;
3695
3696 if (per_ts_stat == NULL)
3698 else
3700
3701 s = &per_ts_stat[num_spaces - 1];
3702 memset(s, 0, sizeof(*s));
3703 s->tsId = cur_tsid;
3704
3705 /*
3706 * The first buffer in this tablespace. As CkptBufferIds is sorted
3707 * by tablespace all (s->num_to_scan) buffers in this tablespace
3708 * will follow afterwards.
3709 */
3710 s->index = i;
3711
3712 /*
3713 * progress_slice will be determined once we know how many buffers
3714 * are in each tablespace, i.e. after this loop.
3715 */
3716
3718 }
3719 else
3720 {
3721 s = &per_ts_stat[num_spaces - 1];
3722 }
3723
3724 s->num_to_scan++;
3725
3726 /* Check for barrier events. */
3729 }
3730
3731 Assert(num_spaces > 0);
3732
3733 /*
3734 * Build a min-heap over the write-progress in the individual tablespaces,
3735 * and compute how large a portion of the total progress a single
3736 * processed buffer is.
3737 */
3740 NULL);
3741
3742 for (i = 0; i < num_spaces; i++)
3743 {
3745
3746 ts_stat->progress_slice = (float8) num_to_scan / ts_stat->num_to_scan;
3747
3749 }
3750
3752
3753 /*
3754 * Iterate through to-be-checkpointed buffers and write the ones (still)
3755 * marked with BM_CHECKPOINT_NEEDED. The writes are balanced between
3756 * tablespaces; otherwise the sorting would lead to only one tablespace
3757 * receiving writes at a time, making inefficient use of the hardware.
3758 */
3759 num_processed = 0;
3760 num_written = 0;
3761 while (!binaryheap_empty(ts_heap))
3762 {
3766
3767 buf_id = CkptBufferIds[ts_stat->index].buf_id;
3768 Assert(buf_id != -1);
3769
3770 bufHdr = GetBufferDescriptor(buf_id);
3771
3772 num_processed++;
3773
3774 /*
3775 * We don't need to acquire the lock here, because we're only looking
3776 * at a single bit. It's possible that someone else writes the buffer
3777 * and clears the flag right after we check, but that doesn't matter
3778 * since SyncOneBuffer will then do nothing. However, there is a
3779 * further race condition: it's conceivable that between the time we
3780 * examine the bit here and the time SyncOneBuffer acquires the lock,
3781 * someone else not only wrote the buffer but replaced it with another
3782 * page and dirtied it. In that improbable case, SyncOneBuffer will
3783 * write the buffer though we didn't need to. It doesn't seem worth
3784 * guarding against this, though.
3785 */
3787 {
3788 if (SyncOneBuffer(buf_id, false, &wb_context) & BUF_WRITTEN)
3789 {
3792 num_written++;
3793 }
3794 }
3795
3796 /*
3797 * Measure progress independent of actually having to flush the buffer
3798 * - otherwise writing become unbalanced.
3799 */
3800 ts_stat->progress += ts_stat->progress_slice;
3801 ts_stat->num_scanned++;
3802 ts_stat->index++;
3803
3804 /* Have all the buffers from the tablespace been processed? */
3805 if (ts_stat->num_scanned == ts_stat->num_to_scan)
3806 {
3808 }
3809 else
3810 {
3811 /* update heap with the new progress */
3813 }
3814
3815 /*
3816 * Sleep to throttle our I/O rate.
3817 *
3818 * (This will check for barrier events even if it doesn't sleep.)
3819 */
3820 CheckpointWriteDelay(flags, (double) num_processed / num_to_scan);
3821 }
3822
3823 /*
3824 * Issue all pending flushes. Only checkpointer calls BufferSync(), so
3825 * IOContext will always be IOCONTEXT_NORMAL.
3826 */
3828
3830 per_ts_stat = NULL;
3832
3833 /*
3834 * Update checkpoint statistics. As noted above, this doesn't include
3835 * buffers written by other backends or bgwriter scan.
3836 */
3838
3840}
3841
3842/*
3843 * BgBufferSync -- Write out some dirty buffers in the pool.
3844 *
3845 * This is called periodically by the background writer process.
3846 *
3847 * Returns true if it's appropriate for the bgwriter process to go into
3848 * low-power hibernation mode. (This happens if the strategy clock-sweep
3849 * has been "lapped" and no buffer allocations have occurred recently,
3850 * or if the bgwriter has been effectively disabled by setting
3851 * bgwriter_lru_maxpages to 0.)
3852 */
3853bool
3855{
3856 /* info obtained from freelist.c */
3857 int strategy_buf_id;
3860
3861 /*
3862 * Information saved between calls so we can determine the strategy
3863 * point's advance rate and avoid scanning already-cleaned buffers.
3864 */
3865 static bool saved_info_valid = false;
3866 static int prev_strategy_buf_id;
3868 static int next_to_clean;
3869 static uint32 next_passes;
3870
3871 /* Moving averages of allocation rate and clean-buffer density */
3872 static float smoothed_alloc = 0;
3873 static float smoothed_density = 10.0;
3874
3875 /* Potentially these could be tunables, but for now, not */
3876 float smoothing_samples = 16;
3877 float scan_whole_pool_milliseconds = 120000.0;
3878
3879 /* Used to compute how far we scan ahead */
3880 long strategy_delta;
3881 int bufs_to_lap;
3882 int bufs_ahead;
3883 float scans_per_alloc;
3886 int min_scan_buffers;
3887
3888 /* Variables for the scanning loop proper */
3889 int num_to_scan;
3890 int num_written;
3891 int reusable_buffers;
3892
3893 /* Variables for final smoothed_density update */
3894 long new_strategy_delta;
3896
3897 /*
3898 * Find out where the clock-sweep currently is, and how many buffer
3899 * allocations have happened since our last call.
3900 */
3902
3903 /* Report buffer alloc counts to pgstat */
3905
3906 /*
3907 * If we're not running the LRU scan, just stop after doing the stats
3908 * stuff. We mark the saved state invalid so that we can recover sanely
3909 * if LRU scan is turned back on later.
3910 */
3911 if (bgwriter_lru_maxpages <= 0)
3912 {
3913 saved_info_valid = false;
3914 return true;
3915 }
3916
3917 /*
3918 * Compute strategy_delta = how many buffers have been scanned by the
3919 * clock-sweep since last time. If first time through, assume none. Then
3920 * see if we are still ahead of the clock-sweep, and if so, how many
3921 * buffers we could scan before we'd catch up with it and "lap" it. Note:
3922 * weird-looking coding of xxx_passes comparisons are to avoid bogus
3923 * behavior when the passes counts wrap around.
3924 */
3925 if (saved_info_valid)
3926 {
3928
3931
3932 Assert(strategy_delta >= 0);
3933
3934 if ((int32) (next_passes - strategy_passes) > 0)
3935 {
3936 /* we're one pass ahead of the strategy point */
3938#ifdef BGW_DEBUG
3939 elog(DEBUG2, "bgwriter ahead: bgw %u-%u strategy %u-%u delta=%ld lap=%d",
3943#endif
3944 }
3945 else if (next_passes == strategy_passes &&
3947 {
3948 /* on same pass, but ahead or at least not behind */
3950#ifdef BGW_DEBUG
3951 elog(DEBUG2, "bgwriter ahead: bgw %u-%u strategy %u-%u delta=%ld lap=%d",
3955#endif
3956 }
3957 else
3958 {
3959 /*
3960 * We're behind, so skip forward to the strategy point and start
3961 * cleaning from there.
3962 */
3963#ifdef BGW_DEBUG
3964 elog(DEBUG2, "bgwriter behind: bgw %u-%u strategy %u-%u delta=%ld",
3968#endif
3972 }
3973 }
3974 else
3975 {
3976 /*
3977 * Initializing at startup or after LRU scanning had been off. Always
3978 * start at the strategy point.
3979 */
3980#ifdef BGW_DEBUG
3981 elog(DEBUG2, "bgwriter initializing: strategy %u-%u",
3983#endif
3984 strategy_delta = 0;
3988 }
3989
3990 /* Update saved info for next time */
3993 saved_info_valid = true;
3994
3995 /*
3996 * Compute how many buffers had to be scanned for each new allocation, ie,
3997 * 1/density of reusable buffers, and track a moving average of that.
3998 *
3999 * If the strategy point didn't move, we don't update the density estimate
4000 */
4001 if (strategy_delta > 0 && recent_alloc > 0)
4002 {
4006 }
4007
4008 /*
4009 * Estimate how many reusable buffers there are between the current
4010 * strategy point and where we've scanned ahead to, based on the smoothed
4011 * density estimate.
4012 */
4015
4016 /*
4017 * Track a moving average of recent buffer allocations. Here, rather than
4018 * a true average we want a fast-attack, slow-decline behavior: we
4019 * immediately follow any increase.
4020 */
4021 if (smoothed_alloc <= (float) recent_alloc)
4023 else
4026
4027 /* Scale the estimate by a GUC to allow more aggressive tuning. */
4029
4030 /*
4031 * If recent_alloc remains at zero for many cycles, smoothed_alloc will
4032 * eventually underflow to zero, and the underflows produce annoying
4033 * kernel warnings on some platforms. Once upcoming_alloc_est has gone to
4034 * zero, there's no point in tracking smaller and smaller values of
4035 * smoothed_alloc, so just reset it to exactly zero to avoid this
4036 * syndrome. It will pop back up as soon as recent_alloc increases.
4037 */
4038 if (upcoming_alloc_est == 0)
4039 smoothed_alloc = 0;
4040
4041 /*
4042 * Even in cases where there's been little or no buffer allocation
4043 * activity, we want to make a small amount of progress through the buffer
4044 * cache so that as many reusable buffers as possible are clean after an
4045 * idle period.
4046 *
4047 * (scan_whole_pool_milliseconds / BgWriterDelay) computes how many times
4048 * the BGW will be called during the scan_whole_pool time; slice the
4049 * buffer pool into that many sections.
4050 */
4052
4054 {
4055#ifdef BGW_DEBUG
4056 elog(DEBUG2, "bgwriter: alloc_est=%d too small, using min=%d + reusable_est=%d",
4058#endif
4060 }
4061
4062 /*
4063 * Now write out dirty reusable buffers, working forward from the
4064 * next_to_clean point, until we have lapped the strategy scan, or cleaned
4065 * enough buffers to match our estimate of the next cycle's allocation
4066 * requirements, or hit the bgwriter_lru_maxpages limit.
4067 */
4068
4069 num_to_scan = bufs_to_lap;
4070 num_written = 0;
4072
4073 /* Execute the LRU scan */
4074 while (num_to_scan > 0 && reusable_buffers < upcoming_alloc_est)
4075 {
4077 wb_context);
4078
4079 if (++next_to_clean >= NBuffers)
4080 {
4081 next_to_clean = 0;
4082 next_passes++;
4083 }
4084 num_to_scan--;
4085
4086 if (sync_state & BUF_WRITTEN)
4087 {
4090 {
4092 break;
4093 }
4094 }
4095 else if (sync_state & BUF_REUSABLE)
4097 }
4098
4100
4101#ifdef BGW_DEBUG
4102 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",
4105 bufs_to_lap - num_to_scan,
4108#endif
4109
4110 /*
4111 * Consider the above scan as being like a new allocation scan.
4112 * Characterize its density and update the smoothed one based on it. This
4113 * effectively halves the moving average period in cases where both the
4114 * strategy and the background writer are doing some useful scanning,
4115 * which is helpful because a long memory isn't as desirable on the
4116 * density estimates.
4117 */
4118 new_strategy_delta = bufs_to_lap - num_to_scan;
4120 if (new_strategy_delta > 0 && new_recent_alloc > 0)
4121 {
4125
4126#ifdef BGW_DEBUG
4127 elog(DEBUG2, "bgwriter: cleaner density alloc=%u scan=%ld density=%.2f new smoothed=%.2f",
4130#endif
4131 }
4132
4133 /* Return true if OK to hibernate */
4134 return (bufs_to_lap == 0 && recent_alloc == 0);
4135}
4136
4137/*
4138 * SyncOneBuffer -- process a single buffer during syncing.
4139 *
4140 * If skip_recently_used is true, we don't write currently-pinned buffers, nor
4141 * buffers marked recently used, as these are not replacement candidates.
4142 *
4143 * Returns a bitmask containing the following flag bits:
4144 * BUF_WRITTEN: we wrote the buffer.
4145 * BUF_REUSABLE: buffer is available for replacement, ie, it has
4146 * pin count 0 and usage count 0.
4147 *
4148 * (BUF_WRITTEN could be set in error if FlushBuffer finds the buffer clean
4149 * after locking it, but we don't care all that much.)
4150 */
4151static int
4153{
4155 int result = 0;
4157 BufferTag tag;
4158
4159 /* Make sure we can handle the pin */
4162
4163 /*
4164 * Check whether buffer needs writing.
4165 *
4166 * We can make this check without taking the buffer content lock so long
4167 * as we mark pages dirty in access methods *before* logging changes with
4168 * XLogInsert(): if someone marks the buffer dirty just after our check we
4169 * don't worry because our checkpoint.redo points before log record for
4170 * upcoming changes and so we are not required to write such dirty buffer.
4171 */
4173
4176 {
4178 }
4179 else if (skip_recently_used)
4180 {
4181 /* Caller told us not to write recently-used buffers */
4183 return result;
4184 }
4185
4186 if (!(buf_state & BM_VALID) || !(buf_state & BM_DIRTY))
4187 {
4188 /* It's clean, so nothing to do */
4190 return result;
4191 }
4192
4193 /*
4194 * Pin it, share-exclusive-lock it, write it. (FlushBuffer will do
4195 * nothing if the buffer is clean by the time we've locked it.)
4196 */
4198
4200
4201 tag = bufHdr->tag;
4202
4204
4205 /*
4206 * SyncOneBuffer() is only called by checkpointer and bgwriter, so
4207 * IOContext will always be IOCONTEXT_NORMAL.
4208 */
4210
4211 return result | BUF_WRITTEN;
4212}
4213
4214/*
4215 * AtEOXact_Buffers - clean up at end of transaction.
4216 *
4217 * As of PostgreSQL 8.0, buffer pins should get released by the
4218 * ResourceOwner mechanism. This routine is just a debugging
4219 * cross-check that no pins remain.
4220 */
4221void
4230
4231/*
4232 * Initialize access to shared buffer pool
4233 *
4234 * This is called during backend startup (whether standalone or under the
4235 * postmaster). It sets up for this backend's access to the already-existing
4236 * buffer pool.
4237 */
4238void
4240{
4241 /*
4242 * An advisory limit on the number of pins each backend should hold, based
4243 * on shared_buffers and the maximum number of connections possible.
4244 * That's very pessimistic, but outside toy-sized shared_buffers it should
4245 * allow plenty of pins. LimitAdditionalPins() and
4246 * GetAdditionalPinLimit() can be used to check the remaining balance.
4247 */
4249
4252
4254
4255 /*
4256 * AtProcExit_Buffers needs LWLock access, and thereby has to be called at
4257 * the corresponding phase of backend shutdown.
4258 */
4259 Assert(MyProc != NULL);
4261}
4262
4263/*
4264 * During backend exit, ensure that we released all shared-buffer locks and
4265 * assert that we have no remaining pins.
4266 */
4267static void
4269{
4270 UnlockBuffers();
4271
4273
4274 /* localbuf.c needs a chance too */
4276}
4277
4278/*
4279 * CheckForBufferLeaks - ensure this backend holds no buffer pins
4280 *
4281 * As of PostgreSQL 8.0, buffer pins should get released by the
4282 * ResourceOwner mechanism. This routine is just a debugging
4283 * cross-check that no pins remain.
4284 */
4285static void
4287{
4288#ifdef USE_ASSERT_CHECKING
4289 int RefCountErrors = 0;
4291 int i;
4292 char *s;
4293
4294 /* check the array */
4295 for (i = 0; i < REFCOUNT_ARRAY_ENTRIES; i++)
4296 {
4298 {
4299 res = &PrivateRefCountArray[i];
4300
4302 elog(WARNING, "buffer refcount leak: %s", s);
4303 pfree(s);
4304
4306 }
4307 }
4308
4309 /* if necessary search the hash */
4311 {
4312 refcount_iterator iter;
4313
4315 while ((res = refcount_iterate(PrivateRefCountHash, &iter)) != NULL)
4316 {
4318 elog(WARNING, "buffer refcount leak: %s", s);
4319 pfree(s);
4321 }
4322 }
4323
4324 Assert(RefCountErrors == 0);
4325#endif
4326}
4327
4328#ifdef USE_ASSERT_CHECKING
4329/*
4330 * Check for exclusive-locked catalog buffers. This is the core of
4331 * AssertCouldGetRelation().
4332 *
4333 * A backend would self-deadlock on the content lock if the catalog scan read
4334 * the exclusive-locked buffer. The main threat is exclusive-locked buffers
4335 * of catalogs used in relcache, because a catcache search on any catalog may
4336 * build that catalog's relcache entry. We don't have an inventory of
4337 * catalogs relcache uses, so just check buffers of most catalogs.
4338 *
4339 * It's better to minimize waits while holding an exclusive buffer lock, so it
4340 * would be nice to broaden this check not to be catalog-specific. However,
4341 * bttextcmp() accesses pg_collation, and non-core opclasses might similarly
4342 * read tables. That is deadlock-free as long as there's no loop in the
4343 * dependency graph: modifying table A may cause an opclass to read table B,
4344 * but it must not cause a read of table A.
4345 */
4346void
4348{
4350
4351 /* check the array */
4352 for (int i = 0; i < REFCOUNT_ARRAY_ENTRIES; i++)
4353 {
4355 {
4356 res = &PrivateRefCountArray[i];
4357
4358 if (res->buffer == InvalidBuffer)
4359 continue;
4360
4362 }
4363 }
4364
4365 /* if necessary search the hash */
4367 {
4368 refcount_iterator iter;
4369
4371 while ((res = refcount_iterate(PrivateRefCountHash, &iter)) != NULL)
4372 {
4374 }
4375 }
4376}
4377
4378static void
4380{
4382 BufferTag tag;
4383 Oid relid;
4384
4386 return;
4387
4388 tag = bufHdr->tag;
4389
4390 /*
4391 * This relNumber==relid assumption holds until a catalog experiences
4392 * VACUUM FULL or similar. After a command like that, relNumber will be
4393 * in the normal (non-catalog) range, and we lose the ability to detect
4394 * hazardous access to that catalog. Calling RelidByRelfilenumber() would
4395 * close that gap, but RelidByRelfilenumber() might then deadlock with a
4396 * held lock.
4397 */
4398 relid = tag.relNumber;
4399
4400 if (IsCatalogTextUniqueIndexOid(relid)) /* see comments at the callee */
4401 return;
4402
4404}
4405#endif
4406
4407
4408/*
4409 * Helper routine to issue warnings when a buffer is unexpectedly pinned
4410 */
4411char *
4413{
4414 BufferDesc *buf;
4416 char *result;
4417 ProcNumber backend;
4419
4421 if (BufferIsLocal(buffer))
4422 {
4425 backend = MyProcNumber;
4426 }
4427 else
4428 {
4431 backend = INVALID_PROC_NUMBER;
4432 }
4433
4434 /* theoretically we should lock the bufHdr here */
4435 buf_state = pg_atomic_read_u64(&buf->state);
4436
4437 result = psprintf("[%03d] (rel=%s, blockNum=%u, flags=0x%" PRIx64 ", refcount=%u %d)",
4438 buffer,
4440 BufTagGetForkNum(&buf->tag)).str,
4441 buf->tag.blockNum, buf_state & BUF_FLAG_MASK,
4443 return result;
4444}
4445
4446/*
4447 * CheckPointBuffers
4448 *
4449 * Flush all dirty blocks in buffer pool to disk at checkpoint time.
4450 *
4451 * Note: temporary relations do not participate in checkpoints, so they don't
4452 * need to be flushed.
4453 */
4454void
4456{
4457 BufferSync(flags);
4458}
4459
4460/*
4461 * BufferGetBlockNumber
4462 * Returns the block number associated with a buffer.
4463 *
4464 * Note:
4465 * Assumes that the buffer is valid and pinned, else the
4466 * value may be obsolete immediately...
4467 */
4470{
4472
4474
4475 if (BufferIsLocal(buffer))
4477 else
4479
4480 /* pinned, so OK to read tag without spinlock */
4481 return bufHdr->tag.blockNum;
4482}
4483
4484/*
4485 * BufferGetTag
4486 * Returns the relfilelocator, fork number and block number associated with
4487 * a buffer.
4488 */
4489void
4492{
4494
4495 /* Do the same checks as BufferGetBlockNumber. */
4497
4498 if (BufferIsLocal(buffer))
4500 else
4502
4503 /* pinned, so OK to read tag without spinlock */
4504 *rlocator = BufTagGetRelFileLocator(&bufHdr->tag);
4505 *forknum = BufTagGetForkNum(&bufHdr->tag);
4506 *blknum = bufHdr->tag.blockNum;
4507}
4508
4509/*
4510 * FlushBuffer
4511 * Physically write out a shared buffer.
4512 *
4513 * NOTE: this actually just passes the buffer contents to the kernel; the
4514 * real write to disk won't happen until the kernel feels like it. This
4515 * is okay from our point of view since we can redo the changes from WAL.
4516 * However, we will need to force the changes to disk via fsync before
4517 * we can checkpoint WAL.
4518 *
4519 * The caller must hold a pin on the buffer and have
4520 * (share-)exclusively-locked the buffer contents.
4521 *
4522 * If the caller has an smgr reference for the buffer's relation, pass it
4523 * as the second parameter. If not, pass NULL.
4524 */
4525static void
4528{
4530 ErrorContextCallback errcallback;
4533
4536
4537 /*
4538 * Try to start an I/O operation. If StartBufferIO returns false, then
4539 * someone else flushed the buffer before we could, so we need not do
4540 * anything.
4541 */
4542 if (StartSharedBufferIO(buf, false, true, NULL) == BUFFER_IO_ALREADY_DONE)
4543 return;
4544
4545 /* Setup error traceback support for ereport() */
4547 errcallback.arg = buf;
4548 errcallback.previous = error_context_stack;
4549 error_context_stack = &errcallback;
4550
4551 /* Find smgr relation for buffer */
4552 if (reln == NULL)
4554
4556 buf->tag.blockNum,
4557 reln->smgr_rlocator.locator.spcOid,
4558 reln->smgr_rlocator.locator.dbOid,
4559 reln->smgr_rlocator.locator.relNumber);
4560
4561 /*
4562 * As we hold at least a share-exclusive lock on the buffer, the LSN
4563 * cannot change during the flush (and thus can't be torn).
4564 */
4566
4567 /*
4568 * Force XLOG flush up to buffer's LSN. This implements the basic WAL
4569 * rule that log updates must hit disk before any of the data-file changes
4570 * they describe do.
4571 *
4572 * However, this rule does not apply to unlogged relations, which will be
4573 * lost after a crash anyway. Most unlogged relation pages do not bear
4574 * LSNs since we never emit WAL records for them, and therefore flushing
4575 * up through the buffer LSN would be useless, but harmless. However,
4576 * some index AMs use LSNs internally to detect concurrent page
4577 * modifications, and therefore unlogged index pages bear "fake" LSNs
4578 * generated by XLogGetFakeLSN. It is unlikely but possible that the fake
4579 * LSN counter could advance past the WAL insertion point; and if it did
4580 * happen, attempting to flush WAL through that location would fail, with
4581 * disastrous system-wide consequences. To make sure that can't happen,
4582 * skip the flush if the buffer isn't permanent.
4583 */
4584 if (pg_atomic_read_u64(&buf->state) & BM_PERMANENT)
4586
4587 /*
4588 * Now it's safe to write the buffer to disk. Note that no one else should
4589 * have been able to write it, while we were busy with log flushing,
4590 * because we got the exclusive right to perform I/O by setting the
4591 * BM_IO_IN_PROGRESS bit.
4592 */
4594
4595 /* Update page checksum if desired. */
4596 PageSetChecksum((Page) bufBlock, buf->tag.blockNum);
4597
4599
4601 BufTagGetForkNum(&buf->tag),
4602 buf->tag.blockNum,
4603 bufBlock,
4604 false);
4605
4606 /*
4607 * When a strategy is in use, only flushes of dirty buffers already in the
4608 * strategy ring are counted as strategy writes (IOCONTEXT
4609 * [BULKREAD|BULKWRITE|VACUUM] IOOP_WRITE) for the purpose of IO
4610 * statistics tracking.
4611 *
4612 * If a shared buffer initially added to the ring must be flushed before
4613 * being used, this is counted as an IOCONTEXT_NORMAL IOOP_WRITE.
4614 *
4615 * If a shared buffer which was added to the ring later because the
4616 * current strategy buffer is pinned or in use or because all strategy
4617 * buffers were dirty and rejected (for BAS_BULKREAD operations only)
4618 * requires flushing, this is counted as an IOCONTEXT_NORMAL IOOP_WRITE
4619 * (from_ring will be false).
4620 *
4621 * When a strategy is not in use, the write can only be a "regular" write
4622 * of a dirty shared buffer (IOCONTEXT_NORMAL IOOP_WRITE).
4623 */
4626
4628
4629 /*
4630 * Mark the buffer as clean and end the BM_IO_IN_PROGRESS state.
4631 */
4632 TerminateBufferIO(buf, true, 0, true, false);
4633
4635 buf->tag.blockNum,
4636 reln->smgr_rlocator.locator.spcOid,
4637 reln->smgr_rlocator.locator.dbOid,
4638 reln->smgr_rlocator.locator.relNumber);
4639
4640 /* Pop the error context stack */
4641 error_context_stack = errcallback.previous;
4642}
4643
4644/*
4645 * Convenience wrapper around FlushBuffer() that locks/unlocks the buffer
4646 * before/after calling FlushBuffer().
4647 */
4648static void
4658
4659/*
4660 * RelationGetNumberOfBlocksInFork
4661 * Determines the current number of pages in the specified relation fork.
4662 *
4663 * Note that the accuracy of the result will depend on the details of the
4664 * relation's storage. For builtin AMs it'll be accurate, but for external AMs
4665 * it might not be.
4666 */
4669{
4670 if (RELKIND_HAS_TABLE_AM(relation->rd_rel->relkind))
4671 {
4672 /*
4673 * Not every table AM uses BLCKSZ wide fixed size blocks. Therefore
4674 * tableam returns the size in bytes - but for the purpose of this
4675 * routine, we want the number of blocks. Therefore divide, rounding
4676 * up.
4677 */
4679
4680 szbytes = table_relation_size(relation, forkNum);
4681
4682 return (szbytes + (BLCKSZ - 1)) / BLCKSZ;
4683 }
4684 else if (RELKIND_HAS_STORAGE(relation->rd_rel->relkind))
4685 {
4686 return smgrnblocks(RelationGetSmgr(relation), forkNum);
4687 }
4688 else
4689 Assert(false);
4690
4691 return 0; /* keep compiler quiet */
4692}
4693
4694/*
4695 * BufferIsPermanent
4696 * Determines whether a buffer will potentially still be around after
4697 * a crash. Caller must hold a buffer pin.
4698 */
4699bool
4701{
4703
4704 /* Local buffers are used only for temp relations. */
4705 if (BufferIsLocal(buffer))
4706 return false;
4707
4708 /* Make sure we've got a real buffer, and that we hold a pin on it. */
4711
4712 /*
4713 * BM_PERMANENT can't be changed while we hold a pin on the buffer, so we
4714 * need not bother with the buffer header spinlock. Even if someone else
4715 * changes the buffer header state while we're doing this, the state is
4716 * changed atomically, so we'll read the old value or the new value, but
4717 * not random garbage.
4718 */
4720 return (pg_atomic_read_u64(&bufHdr->state) & BM_PERMANENT) != 0;
4721}
4722
4723/*
4724 * BufferGetLSNAtomic
4725 * Retrieves the LSN of the buffer atomically.
4726 *
4727 * This is necessary for some callers who may only hold a share lock on
4728 * the buffer. A share lock allows a concurrent backend to set hint bits
4729 * on the page, which in turn may require a WAL record to be emitted.
4730 *
4731 * On platforms with 8 byte atomic reads/writes, we don't need to do any
4732 * additional locking. On platforms not supporting such 8 byte atomic
4733 * reads/writes, we need to actually take the header lock.
4734 */
4737{
4738 /* Make sure we've got a real buffer, and that we hold a pin on it. */
4741
4742#ifdef PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY
4744#else
4745 {
4746 char *page = BufferGetPage(buffer);
4748 XLogRecPtr lsn;
4749
4750 /*
4751 * If we don't need locking for correctness, fastpath out.
4752 */
4754 return PageGetLSN(page);
4755
4758 lsn = PageGetLSN(page);
4760
4761 return lsn;
4762 }
4763#endif
4764}
4765
4766/* ---------------------------------------------------------------------
4767 * DropRelationBuffers
4768 *
4769 * This function removes from the buffer pool all the pages of the
4770 * specified relation forks that have block numbers >= firstDelBlock.
4771 * (In particular, with firstDelBlock = 0, all pages are removed.)
4772 * Dirty pages are simply dropped, without bothering to write them
4773 * out first. Therefore, this is NOT rollback-able, and so should be
4774 * used only with extreme caution!
4775 *
4776 * Currently, this is called only from smgr.c when the underlying file
4777 * is about to be deleted or truncated (firstDelBlock is needed for
4778 * the truncation case). The data in the affected pages would therefore
4779 * be deleted momentarily anyway, and there is no point in writing it.
4780 * It is the responsibility of higher-level code to ensure that the
4781 * deletion or truncation does not lose any data that could be needed
4782 * later. It is also the responsibility of higher-level code to ensure
4783 * that no other process could be trying to load more pages of the
4784 * relation into buffers.
4785 * --------------------------------------------------------------------
4786 */
4787void
4790{
4791 int i;
4792 int j;
4793 RelFileLocatorBackend rlocator;
4796
4797 rlocator = smgr_reln->smgr_rlocator;
4798
4799 /* If it's a local relation, it's localbuf.c's problem. */
4800 if (RelFileLocatorBackendIsTemp(rlocator))
4801 {
4802 if (rlocator.backend == MyProcNumber)
4803 DropRelationLocalBuffers(rlocator.locator, forkNum, nforks,
4805
4806 return;
4807 }
4808
4809 /*
4810 * To remove all the pages of the specified relation forks from the buffer
4811 * pool, we need to scan the entire buffer pool but we can optimize it by
4812 * finding the buffers from BufMapping table provided we know the exact
4813 * size of each fork of the relation. The exact size is required to ensure
4814 * that we don't leave any buffer for the relation being dropped as
4815 * otherwise the background writer or checkpointer can lead to a PANIC
4816 * error while flushing buffers corresponding to files that don't exist.
4817 *
4818 * To know the exact size, we rely on the size cached for each fork by us
4819 * during recovery which limits the optimization to recovery and on
4820 * standbys but we can easily extend it once we have shared cache for
4821 * relation size.
4822 *
4823 * In recovery, we cache the value returned by the first lseek(SEEK_END)
4824 * and the future writes keeps the cached value up-to-date. See
4825 * smgrextend. It is possible that the value of the first lseek is smaller
4826 * than the actual number of existing blocks in the file due to buggy
4827 * Linux kernels that might not have accounted for the recent write. But
4828 * that should be fine because there must not be any buffers after that
4829 * file size.
4830 */
4831 for (i = 0; i < nforks; i++)
4832 {
4833 /* Get the number of blocks for a relation's fork */
4835
4837 {
4839 break;
4840 }
4841
4842 /* calculate the number of blocks to be invalidated */
4844 }
4845
4846 /*
4847 * We apply the optimization iff the total number of blocks to invalidate
4848 * is below the BUF_DROP_FULL_SCAN_THRESHOLD.
4849 */
4852 {
4853 for (j = 0; j < nforks; j++)
4854 FindAndDropRelationBuffers(rlocator.locator, forkNum[j],
4856 return;
4857 }
4858
4859 for (i = 0; i < NBuffers; i++)
4860 {
4862
4863 /*
4864 * We can make this a tad faster by prechecking the buffer tag before
4865 * we attempt to lock the buffer; this saves a lot of lock
4866 * acquisitions in typical cases. It should be safe because the
4867 * caller must have AccessExclusiveLock on the relation, or some other
4868 * reason to be certain that no one is loading new pages of the rel
4869 * into the buffer pool. (Otherwise we might well miss such pages
4870 * entirely.) Therefore, while the tag might be changing while we
4871 * look at it, it can't be changing *to* a value we care about, only
4872 * *away* from such a value. So false negatives are impossible, and
4873 * false positives are safe because we'll recheck after getting the
4874 * buffer lock.
4875 *
4876 * We could check forkNum and blockNum as well as the rlocator, but
4877 * the incremental win from doing so seems small.
4878 */
4879 if (!BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator.locator))
4880 continue;
4881
4883
4884 for (j = 0; j < nforks; j++)
4885 {
4886 if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator.locator) &&
4887 BufTagGetForkNum(&bufHdr->tag) == forkNum[j] &&
4888 bufHdr->tag.blockNum >= firstDelBlock[j])
4889 {
4890 InvalidateBuffer(bufHdr); /* releases spinlock */
4891 break;
4892 }
4893 }
4894 if (j >= nforks)
4896 }
4897}
4898
4899/* ---------------------------------------------------------------------
4900 * DropRelationsAllBuffers
4901 *
4902 * This function removes from the buffer pool all the pages of all
4903 * forks of the specified relations. It's equivalent to calling
4904 * DropRelationBuffers once per fork per relation with firstDelBlock = 0.
4905 * --------------------------------------------------------------------
4906 */
4907void
4909{
4910 int i;
4911 int n = 0;
4912 SMgrRelation *rels;
4913 BlockNumber (*block)[MAX_FORKNUM + 1];
4916 bool cached = true;
4917 bool use_bsearch;
4918
4919 if (nlocators == 0)
4920 return;
4921
4922 rels = palloc_array(SMgrRelation, nlocators); /* non-local relations */
4923
4924 /* If it's a local relation, it's localbuf.c's problem. */
4925 for (i = 0; i < nlocators; i++)
4926 {
4927 if (RelFileLocatorBackendIsTemp(smgr_reln[i]->smgr_rlocator))
4928 {
4929 if (smgr_reln[i]->smgr_rlocator.backend == MyProcNumber)
4930 DropRelationAllLocalBuffers(smgr_reln[i]->smgr_rlocator.locator);
4931 }
4932 else
4933 rels[n++] = smgr_reln[i];
4934 }
4935
4936 /*
4937 * If there are no non-local relations, then we're done. Release the
4938 * memory and return.
4939 */
4940 if (n == 0)
4941 {
4942 pfree(rels);
4943 return;
4944 }
4945
4946 /*
4947 * This is used to remember the number of blocks for all the relations
4948 * forks.
4949 */
4950 block = (BlockNumber (*)[MAX_FORKNUM + 1])
4951 palloc(sizeof(BlockNumber) * n * (MAX_FORKNUM + 1));
4952
4953 /*
4954 * We can avoid scanning the entire buffer pool if we know the exact size
4955 * of each of the given relation forks. See DropRelationBuffers.
4956 */
4957 for (i = 0; i < n && cached; i++)
4958 {
4959 for (int j = 0; j <= MAX_FORKNUM; j++)
4960 {
4961 /* Get the number of blocks for a relation's fork. */
4962 block[i][j] = smgrnblocks_cached(rels[i], j);
4963
4964 /* We need to only consider the relation forks that exists. */
4965 if (block[i][j] == InvalidBlockNumber)
4966 {
4967 if (!smgrexists(rels[i], j))
4968 continue;
4969 cached = false;
4970 break;
4971 }
4972
4973 /* calculate the total number of blocks to be invalidated */
4974 nBlocksToInvalidate += block[i][j];
4975 }
4976 }
4977
4978 /*
4979 * We apply the optimization iff the total number of blocks to invalidate
4980 * is below the BUF_DROP_FULL_SCAN_THRESHOLD.
4981 */
4983 {
4984 for (i = 0; i < n; i++)
4985 {
4986 for (int j = 0; j <= MAX_FORKNUM; j++)
4987 {
4988 /* ignore relation forks that doesn't exist */
4989 if (!BlockNumberIsValid(block[i][j]))
4990 continue;
4991
4992 /* drop all the buffers for a particular relation fork */
4993 FindAndDropRelationBuffers(rels[i]->smgr_rlocator.locator,
4994 j, block[i][j], 0);
4995 }
4996 }
4997
4998 pfree(block);
4999 pfree(rels);
5000 return;
5001 }
5002
5003 pfree(block);
5004 locators = palloc_array(RelFileLocator, n); /* non-local relations */
5005 for (i = 0; i < n; i++)
5006 locators[i] = rels[i]->smgr_rlocator.locator;
5007
5008 /*
5009 * For low number of relations to drop just use a simple walk through, to
5010 * save the bsearch overhead. The threshold to use is rather a guess than
5011 * an exactly determined value, as it depends on many factors (CPU and RAM
5012 * speeds, amount of shared buffers etc.).
5013 */
5015
5016 /* sort the list of rlocators if necessary */
5017 if (use_bsearch)
5019
5020 for (i = 0; i < NBuffers; i++)
5021 {
5022 RelFileLocator *rlocator = NULL;
5024
5025 /*
5026 * As in DropRelationBuffers, an unlocked precheck should be safe and
5027 * saves some cycles.
5028 */
5029
5030 if (!use_bsearch)
5031 {
5032 int j;
5033
5034 for (j = 0; j < n; j++)
5035 {
5037 {
5038 rlocator = &locators[j];
5039 break;
5040 }
5041 }
5042 }
5043 else
5044 {
5045 RelFileLocator locator;
5046
5047 locator = BufTagGetRelFileLocator(&bufHdr->tag);
5048 rlocator = bsearch(&locator,
5049 locators, n, sizeof(RelFileLocator),
5051 }
5052
5053 /* buffer doesn't belong to any of the given relfilelocators; skip it */
5054 if (rlocator == NULL)
5055 continue;
5056
5058 if (BufTagMatchesRelFileLocator(&bufHdr->tag, rlocator))
5059 InvalidateBuffer(bufHdr); /* releases spinlock */
5060 else
5062 }
5063
5064 pfree(locators);
5065 pfree(rels);
5066}
5067
5068/* ---------------------------------------------------------------------
5069 * FindAndDropRelationBuffers
5070 *
5071 * This function performs look up in BufMapping table and removes from the
5072 * buffer pool all the pages of the specified relation fork that has block
5073 * number >= firstDelBlock. (In particular, with firstDelBlock = 0, all
5074 * pages are removed.)
5075 * --------------------------------------------------------------------
5076 */
5077static void
5081{
5082 BlockNumber curBlock;
5083
5084 for (curBlock = firstDelBlock; curBlock < nForkBlock; curBlock++)
5085 {
5086 uint32 bufHash; /* hash value for tag */
5087 BufferTag bufTag; /* identity of requested block */
5088 LWLock *bufPartitionLock; /* buffer partition lock for it */
5089 int buf_id;
5091
5092 /* create a tag so we can lookup the buffer */
5093 InitBufferTag(&bufTag, &rlocator, forkNum, curBlock);
5094
5095 /* determine its hash code and partition lock ID */
5098
5099 /* Check that it is in the buffer pool. If not, do nothing. */
5101 buf_id = BufTableLookup(&bufTag, bufHash);
5103
5104 if (buf_id < 0)
5105 continue;
5106
5107 bufHdr = GetBufferDescriptor(buf_id);
5108
5109 /*
5110 * We need to lock the buffer header and recheck if the buffer is
5111 * still associated with the same block because the buffer could be
5112 * evicted by some other backend loading blocks for a different
5113 * relation after we release lock on the BufMapping table.
5114 */
5116
5117 if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rlocator) &&
5118 BufTagGetForkNum(&bufHdr->tag) == forkNum &&
5119 bufHdr->tag.blockNum >= firstDelBlock)
5120 InvalidateBuffer(bufHdr); /* releases spinlock */
5121 else
5123 }
5124}
5125
5126/* ---------------------------------------------------------------------
5127 * DropDatabaseBuffers
5128 *
5129 * This function removes all the buffers in the buffer cache for a
5130 * particular database. Dirty pages are simply dropped, without
5131 * bothering to write them out first. This is used when we destroy a
5132 * database, to avoid trying to flush data to disk when the directory
5133 * tree no longer exists. Implementation is pretty similar to
5134 * DropRelationBuffers() which is for destroying just one relation.
5135 * --------------------------------------------------------------------
5136 */
5137void
5139{
5140 int i;
5141
5142 /*
5143 * We needn't consider local buffers, since by assumption the target
5144 * database isn't our own.
5145 */
5146
5147 for (i = 0; i < NBuffers; i++)
5148 {
5150
5151 /*
5152 * As in DropRelationBuffers, an unlocked precheck should be safe and
5153 * saves some cycles.
5154 */
5155 if (bufHdr->tag.dbOid != dbid)
5156 continue;
5157
5159 if (bufHdr->tag.dbOid == dbid)
5160 InvalidateBuffer(bufHdr); /* releases spinlock */
5161 else
5163 }
5164}
5165
5166/* ---------------------------------------------------------------------
5167 * FlushRelationBuffers
5168 *
5169 * This function writes all dirty pages of a relation out to disk
5170 * (or more accurately, out to kernel disk buffers), ensuring that the
5171 * kernel has an up-to-date view of the relation.
5172 *
5173 * Generally, the caller should be holding AccessExclusiveLock on the
5174 * target relation to ensure that no other backend is busy dirtying
5175 * more blocks of the relation; the effects can't be expected to last
5176 * after the lock is released.
5177 *
5178 * XXX currently it sequentially searches the buffer pool, should be
5179 * changed to more clever ways of searching. This routine is not
5180 * used in any performance-critical code paths, so it's not worth
5181 * adding additional overhead to normal paths to make it go faster.
5182 * --------------------------------------------------------------------
5183 */
5184void
5186{
5187 int i;
5189 SMgrRelation srel = RelationGetSmgr(rel);
5190
5191 if (RelationUsesLocalBuffers(rel))
5192 {
5193 for (i = 0; i < NLocBuffer; i++)
5194 {
5196
5198 if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rel->rd_locator) &&
5199 ((buf_state = pg_atomic_read_u64(&bufHdr->state)) &
5200 (BM_VALID | BM_DIRTY)) == (BM_VALID | BM_DIRTY))
5201 {
5202 ErrorContextCallback errcallback;
5203
5204 /* Setup error traceback support for ereport() */
5206 errcallback.arg = bufHdr;
5207 errcallback.previous = error_context_stack;
5208 error_context_stack = &errcallback;
5209
5210 /* Make sure we can handle the pin */
5213
5214 /*
5215 * Pin/unpin mostly to make valgrind work, but it also seems
5216 * like the right thing to do.
5217 */
5218 PinLocalBuffer(bufHdr, false);
5219
5220
5221 FlushLocalBuffer(bufHdr, srel);
5222
5224
5225 /* Pop the error context stack */
5226 error_context_stack = errcallback.previous;
5227 }
5228 }
5229
5230 return;
5231 }
5232
5233 for (i = 0; i < NBuffers; i++)
5234 {
5236
5238
5239 /*
5240 * As in DropRelationBuffers, an unlocked precheck should be safe and
5241 * saves some cycles.
5242 */
5244 continue;
5245
5246 /* Make sure we can handle the pin */
5249
5251 if (BufTagMatchesRelFileLocator(&bufHdr->tag, &rel->rd_locator) &&
5253 {
5257 }
5258 else
5260 }
5261}
5262
5263/* ---------------------------------------------------------------------
5264 * FlushRelationsAllBuffers
5265 *
5266 * This function flushes out of the buffer pool all the pages of all
5267 * forks of the specified smgr relations. It's equivalent to calling
5268 * FlushRelationBuffers once per relation. The relations are assumed not
5269 * to use local buffers.
5270 * --------------------------------------------------------------------
5271 */
5272void
5274{
5275 int i;
5277 bool use_bsearch;
5278
5279 if (nrels == 0)
5280 return;
5281
5282 /* fill-in array for qsort */
5284
5285 for (i = 0; i < nrels; i++)
5286 {
5287 Assert(!RelFileLocatorBackendIsTemp(smgrs[i]->smgr_rlocator));
5288
5289 srels[i].rlocator = smgrs[i]->smgr_rlocator.locator;
5290 srels[i].srel = smgrs[i];
5291 }
5292
5293 /*
5294 * Save the bsearch overhead for low number of relations to sync. See
5295 * DropRelationsAllBuffers for details.
5296 */
5298
5299 /* sort the list of SMgrRelations if necessary */
5300 if (use_bsearch)
5301 qsort(srels, nrels, sizeof(SMgrSortArray), rlocator_comparator);
5302
5303 for (i = 0; i < NBuffers; i++)
5304 {
5308
5309 /*
5310 * As in DropRelationBuffers, an unlocked precheck should be safe and
5311 * saves some cycles.
5312 */
5313
5314 if (!use_bsearch)
5315 {
5316 int j;
5317
5318 for (j = 0; j < nrels; j++)
5319 {
5320 if (BufTagMatchesRelFileLocator(&bufHdr->tag, &srels[j].rlocator))
5321 {
5322 srelent = &srels[j];
5323 break;
5324 }
5325 }
5326 }
5327 else
5328 {
5329 RelFileLocator rlocator;
5330
5331 rlocator = BufTagGetRelFileLocator(&bufHdr->tag);
5332 srelent = bsearch(&rlocator,
5333 srels, nrels, sizeof(SMgrSortArray),
5335 }
5336
5337 /* buffer doesn't belong to any of the given relfilelocators; skip it */
5338 if (srelent == NULL)
5339 continue;
5340
5341 /* Make sure we can handle the pin */
5344
5346 if (BufTagMatchesRelFileLocator(&bufHdr->tag, &srelent->rlocator) &&
5348 {
5352 }
5353 else
5355 }
5356
5357 pfree(srels);
5358}
5359
5360/* ---------------------------------------------------------------------
5361 * RelationCopyStorageUsingBuffer
5362 *
5363 * Copy fork's data using bufmgr. Same as RelationCopyStorage but instead
5364 * of using smgrread and smgrextend this will copy using bufmgr APIs.
5365 *
5366 * Refer comments atop CreateAndCopyRelationData() for details about
5367 * 'permanent' parameter.
5368 * --------------------------------------------------------------------
5369 */
5370static void
5373 ForkNumber forkNum, bool permanent)
5374{
5375 Buffer srcBuf;
5376 Buffer dstBuf;
5377 Page srcPage;
5378 Page dstPage;
5379 bool use_wal;
5380 BlockNumber nblocks;
5381 BlockNumber blkno;
5388
5389 /*
5390 * In general, we want to write WAL whenever wal_level > 'minimal', but we
5391 * can skip it when copying any fork of an unlogged relation other than
5392 * the init fork.
5393 */
5394 use_wal = XLogIsNeeded() && (permanent || forkNum == INIT_FORKNUM);
5395
5396 /* Get number of blocks in the source relation. */
5398 forkNum);
5399
5400 /* Nothing to copy; just return. */
5401 if (nblocks == 0)
5402 return;
5403
5404 /*
5405 * Bulk extend the destination relation of the same size as the source
5406 * relation before starting to copy block by block.
5407 */
5408 memset(buf.data, 0, BLCKSZ);
5409 smgrextend(smgropen(dstlocator, INVALID_PROC_NUMBER), forkNum, nblocks - 1,
5410 buf.data, true);
5411
5412 /* This is a bulk operation, so use buffer access strategies. */
5415
5416 /* Initialize streaming read */
5417 p.current_blocknum = 0;
5418 p.last_exclusive = nblocks;
5420
5421 /*
5422 * It is safe to use batchmode as block_range_read_stream_cb takes no
5423 * locks.
5424 */
5428 src_smgr,
5430 forkNum,
5432 &p,
5433 0);
5434
5435 /* Iterate over each block of the source relation file. */
5436 for (blkno = 0; blkno < nblocks; blkno++)
5437 {
5439
5440 /* Read block from source relation. */
5444
5448 permanent);
5450
5452
5453 /* Copy page data from the source to the destination. */
5456
5457 /* WAL-log the copied page. */
5458 if (use_wal)
5460
5462
5465 }
5468
5471}
5472
5473/* ---------------------------------------------------------------------
5474 * CreateAndCopyRelationData
5475 *
5476 * Create destination relation storage and copy all forks from the
5477 * source relation to the destination.
5478 *
5479 * Pass permanent as true for permanent relations and false for
5480 * unlogged relations. Currently this API is not supported for
5481 * temporary relations.
5482 * --------------------------------------------------------------------
5483 */
5484void
5486 RelFileLocator dst_rlocator, bool permanent)
5487{
5488 char relpersistence;
5491
5492 /* Set the relpersistence. */
5493 relpersistence = permanent ?
5495
5498
5499 /*
5500 * Create and copy all forks of the relation. During create database we
5501 * have a separate cleanup mechanism which deletes complete database
5502 * directory. Therefore, each individual relation doesn't need to be
5503 * registered for cleanup.
5504 */
5505 RelationCreateStorage(dst_rlocator, relpersistence, false);
5506
5507 /* copy main fork. */
5509 permanent);
5510
5511 /* copy those extra forks that exist */
5512 for (ForkNumber forkNum = MAIN_FORKNUM + 1;
5513 forkNum <= MAX_FORKNUM; forkNum++)
5514 {
5515 if (smgrexists(src_rel, forkNum))
5516 {
5517 smgrcreate(dst_rel, forkNum, false);
5518
5519 /*
5520 * WAL log creation if the relation is persistent, or this is the
5521 * init fork of an unlogged relation.
5522 */
5523 if (permanent || forkNum == INIT_FORKNUM)
5524 log_smgrcreate(&dst_rlocator, forkNum);
5525
5526 /* Copy a fork's data, block by block. */
5528 permanent);
5529 }
5530 }
5531}
5532
5533/* ---------------------------------------------------------------------
5534 * FlushDatabaseBuffers
5535 *
5536 * This function writes all dirty pages of a database out to disk
5537 * (or more accurately, out to kernel disk buffers), ensuring that the
5538 * kernel has an up-to-date view of the database.
5539 *
5540 * Generally, the caller should be holding an appropriate lock to ensure
5541 * no other backend is active in the target database; otherwise more
5542 * pages could get dirtied.
5543 *
5544 * Note we don't worry about flushing any pages of temporary relations.
5545 * It's assumed these wouldn't be interesting.
5546 * --------------------------------------------------------------------
5547 */
5548void
5550{
5551 int i;
5553
5554 for (i = 0; i < NBuffers; i++)
5555 {
5557
5559
5560 /*
5561 * As in DropRelationBuffers, an unlocked precheck should be safe and
5562 * saves some cycles.
5563 */
5564 if (bufHdr->tag.dbOid != dbid)
5565 continue;
5566
5567 /* Make sure we can handle the pin */
5570
5572 if (bufHdr->tag.dbOid == dbid &&
5574 {
5578 }
5579 else
5581 }
5582}
5583
5584/*
5585 * Flush a previously, share-exclusively or exclusively, locked and pinned
5586 * buffer to the OS.
5587 */
5588void
5590{
5592
5593 /* currently not needed, but no fundamental reason not to support */
5595
5597
5599
5601
5603}
5604
5605/*
5606 * ReleaseBuffer -- release the pin on a buffer
5607 */
5608void
5610{
5611 if (!BufferIsValid(buffer))
5612 elog(ERROR, "bad buffer ID: %d", buffer);
5613
5614 if (BufferIsLocal(buffer))
5616 else
5618}
5619
5620/*
5621 * UnlockReleaseBuffer -- release the content lock and pin on a buffer
5622 *
5623 * This is just a, more efficient, shorthand for a common combination.
5624 */
5625void
5627{
5628 int mode;
5629 BufferDesc *buf;
5631 uint64 sub;
5633
5635
5636 if (BufferIsLocal(buffer))
5637 {
5639 return;
5640 }
5641
5643
5645
5647
5648 /* compute state modification for lock release */
5650
5651 /* compute state modification for pin release */
5653 Assert(ref != NULL);
5654 Assert(ref->data.refcount > 0);
5655 ref->data.refcount--;
5656
5657 /* no more backend local pins, reduce shared pin count */
5658 if (likely(ref->data.refcount == 0))
5659 {
5660 /* See comment in UnpinBufferNoOwner() */
5662
5663 sub |= BUF_REFCOUNT_ONE;
5665 }
5666
5667 /* perform the lock and pin release in one atomic op */
5668 lockstate = pg_atomic_sub_fetch_u64(&buf->state, sub);
5669
5670 /* wake up waiters for the lock */
5672
5673 /* wake up waiter for the pin release */
5676
5677 /*
5678 * Now okay to allow cancel/die interrupts again, which were held when the
5679 * lock was acquired.
5680 */
5682}
5683
5684/*
5685 * IncrBufferRefCount
5686 * Increment the pin count on a buffer that we have *already* pinned
5687 * at least once.
5688 *
5689 * This function cannot be used on a buffer we do not have pinned,
5690 * because it doesn't change the shared buffer state.
5691 */
5692void
5709
5710/*
5711 * Shared-buffer only helper for MarkBufferDirtyHint() and
5712 * BufferSetHintBits16().
5713 *
5714 * This is separated out because it turns out that the repeated checks for
5715 * local buffers, repeated GetBufferDescriptor() and repeated reading of the
5716 * buffer's state sufficiently hurts the performance of BufferSetHintBits16().
5717 */
5718static inline void
5720 bool buffer_std)
5721{
5722 Page page = BufferGetPage(buffer);
5723
5725
5726 /* here, either share-exclusive or exclusive lock is OK */
5729
5730 /*
5731 * This routine might get called many times on the same page, if we are
5732 * making the first scan after commit of an xact that added/deleted many
5733 * tuples. So, be as quick as we can if the buffer is already dirty.
5734 *
5735 * As we are holding (at least) a share-exclusive lock, nobody could have
5736 * cleaned or dirtied the page concurrently, so we can just rely on the
5737 * previously fetched value here without any danger of races.
5738 */
5739 if (unlikely(!(lockstate & BM_DIRTY)))
5740 {
5742 bool wal_log = false;
5744
5745 /*
5746 * If we need to protect hint bit updates from torn writes, WAL-log a
5747 * full page image of the page. This full page image is only necessary
5748 * if the hint bit update is the first change to the page since the
5749 * last checkpoint.
5750 *
5751 * We don't check full_page_writes here because that logic is included
5752 * when we call XLogInsert() since the value changes dynamically.
5753 */
5755 {
5756 /*
5757 * If we must not write WAL, due to a relfilelocator-specific
5758 * condition or being in recovery, don't dirty the page. We can
5759 * set the hint, just not dirty the page as a result so the hint
5760 * is lost when we evict the page or shutdown.
5761 *
5762 * See src/backend/storage/page/README for longer discussion.
5763 */
5764 if (RecoveryInProgress() ||
5766 return;
5767
5768 wal_log = true;
5769 }
5770
5771 /*
5772 * We must mark the page dirty before we emit the WAL record, as per
5773 * the usual rules, to ensure that BufferSync()/SyncOneBuffer() try to
5774 * flush the buffer, even if we haven't inserted the WAL record yet.
5775 * As we hold at least a share-exclusive lock, checkpoints will wait
5776 * for this backend to be done with the buffer before continuing. If
5777 * we did it the other way round, a checkpoint could start between
5778 * writing the WAL record and marking the buffer dirty.
5779 */
5781
5782 /*
5783 * It should not be possible for the buffer to already be dirty, see
5784 * comment above.
5785 */
5789 BM_DIRTY,
5790 0, 0);
5791
5792 /*
5793 * If the block is already dirty because we either made a change or
5794 * set a hint already, then we don't need to write a full page image.
5795 * Note that aggressive cleaning of blocks dirtied by hint bit setting
5796 * would increase the call rate. Bulk setting of hint bits would
5797 * reduce the call rate...
5798 */
5799 if (wal_log)
5801
5802 if (XLogRecPtrIsValid(lsn))
5803 {
5804 /*
5805 * Set the page LSN if we wrote a backup block. To allow backends
5806 * that only hold a share lock on the buffer to read the LSN in a
5807 * tear-free manner, we set the page LSN while holding the buffer
5808 * header lock. This allows any reader of an LSN who holds only a
5809 * share lock to also obtain a buffer header lock before using
5810 * PageGetLSN() to read the LSN in a tear free way. This is done
5811 * in BufferGetLSNAtomic().
5812 *
5813 * If checksums are enabled, you might think we should reset the
5814 * checksum here. That will happen when the page is written
5815 * sometime later in this checkpoint cycle.
5816 */
5818 PageSetLSN(page, lsn);
5820 }
5821
5823 if (VacuumCostActive)
5825 }
5826}
5827
5828/*
5829 * MarkBufferDirtyHint
5830 *
5831 * Mark a buffer dirty for non-critical changes.
5832 *
5833 * This is essentially the same as MarkBufferDirty, except:
5834 *
5835 * 1. The caller does not write WAL; so if checksums are enabled, we may need
5836 * to write an XLOG_FPI_FOR_HINT WAL record to protect against torn pages.
5837 * 2. The caller might have only a share-exclusive-lock instead of an
5838 * exclusive-lock on the buffer's content lock.
5839 * 3. This function does not guarantee that the buffer is always marked dirty
5840 * (it e.g. can't always on a hot standby), so it cannot be used for
5841 * important changes.
5842 */
5843inline void
5845{
5847
5848 if (!BufferIsValid(buffer))
5849 elog(ERROR, "bad buffer ID: %d", buffer);
5850
5851 if (BufferIsLocal(buffer))
5852 {
5854 return;
5855 }
5856
5858
5860 pg_atomic_read_u64(&bufHdr->state),
5861 buffer_std);
5862}
5863
5864/*
5865 * Release buffer content locks for shared buffers.
5866 *
5867 * Used to clean up after errors.
5868 *
5869 * Currently, we can expect that resource owner cleanup, via
5870 * ResOwnerReleaseBuffer(), took care of releasing buffer content locks per
5871 * se; the only thing we need to deal with here is clearing any PIN_COUNT
5872 * request that was in progress.
5873 */
5874void
5876{
5878
5879 if (buf)
5880 {
5882 uint64 unset_bits = 0;
5883
5885
5886 /*
5887 * Don't complain if flag bit not set; it could have been reset but we
5888 * got a cancel/die interrupt before getting the signal.
5889 */
5890 if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
5891 buf->wait_backend_pgprocno == MyProcNumber)
5893
5895 0, unset_bits,
5896 0);
5897
5899 }
5900}
5901
5902/*
5903 * Acquire the buffer content lock in the specified mode
5904 *
5905 * If the lock is not available, sleep until it is.
5906 *
5907 * Side effect: cancel/die interrupts are held off until lock release.
5908 *
5909 * This uses almost the same locking approach as lwlock.c's
5910 * LWLockAcquire(). See documentation at the top of lwlock.c for a more
5911 * detailed discussion.
5912 *
5913 * The reason that this, and most of the other BufferLock* functions, get both
5914 * the Buffer and BufferDesc* as parameters, is that looking up one from the
5915 * other repeatedly shows up noticeably in profiles.
5916 *
5917 * Callers should provide a constant for mode, for more efficient code
5918 * generation.
5919 */
5920static inline void
5922{
5923 PrivateRefCountEntry *entry;
5924 int extraWaits = 0;
5925
5926 /*
5927 * Get reference to the refcount entry before we hold the lock, it seems
5928 * better to do before holding the lock.
5929 */
5930 entry = GetPrivateRefCountEntry(buffer, true);
5931
5932 /*
5933 * We better not already hold a lock on the buffer.
5934 */
5936
5937 /*
5938 * Lock out cancel/die interrupts until we exit the code section protected
5939 * by the content lock. This ensures that interrupts will not interfere
5940 * with manipulations of data structures in shared memory.
5941 */
5943
5944 for (;;)
5945 {
5946 uint32 wait_event = 0; /* initialized to avoid compiler warning */
5947 bool mustwait;
5948
5949 /*
5950 * Try to grab the lock the first time, we're not in the waitqueue
5951 * yet/anymore.
5952 */
5954
5955 if (likely(!mustwait))
5956 {
5957 break;
5958 }
5959
5960 /*
5961 * Ok, at this point we couldn't grab the lock on the first try. We
5962 * cannot simply queue ourselves to the end of the list and wait to be
5963 * woken up because by now the lock could long have been released.
5964 * Instead add us to the queue and try to grab the lock again. If we
5965 * succeed we need to revert the queuing and be happy, otherwise we
5966 * recheck the lock. If we still couldn't grab it, we know that the
5967 * other locker will see our queue entries when releasing since they
5968 * existed before we checked for the lock.
5969 */
5970
5971 /* add to the queue */
5973
5974 /* we're now guaranteed to be woken up if necessary */
5976
5977 /* ok, grabbed the lock the second time round, need to undo queueing */
5978 if (!mustwait)
5979 {
5981 break;
5982 }
5983
5984 switch (mode)
5985 {
5988 break;
5991 break;
5992 case BUFFER_LOCK_SHARE:
5994 break;
5995 case BUFFER_LOCK_UNLOCK:
5997
5998 }
6000
6001 /*
6002 * Wait until awakened.
6003 *
6004 * It is possible that we get awakened for a reason other than being
6005 * signaled by BufferLockWakeup(). If so, loop back and wait again.
6006 * Once we've gotten the lock, re-increment the sema by the number of
6007 * additional signals received.
6008 */
6009 for (;;)
6010 {
6013 break;
6014 extraWaits++;
6015 }
6016
6018
6019 /* Retrying, allow BufferLockReleaseSub to release waiters again. */
6021 }
6022
6023 /* Remember that we now hold this lock */
6024 entry->data.lockmode = mode;
6025
6026 /*
6027 * Fix the process wait semaphore's count for any absorbed wakeups.
6028 */
6029 while (unlikely(extraWaits-- > 0))
6031}
6032
6033/*
6034 * Release a previously acquired buffer content lock.
6035 */
6036static void
6038{
6041 uint64 sub;
6042
6044
6045 /*
6046 * Release my hold on lock, after that it can immediately be acquired by
6047 * others, even if we still have to wakeup other waiters.
6048 */
6050
6052
6054
6055 /*
6056 * Now okay to allow cancel/die interrupts.
6057 */
6059}
6060
6061
6062/*
6063 * Acquire the content lock for the buffer, but only if we don't have to wait.
6064 *
6065 * It is allowed to try to conditionally acquire a lock on a buffer that this
6066 * backend has already locked, but the lock acquisition will always fail, even
6067 * if the new lock acquisition does not conflict with an already held lock
6068 * (e.g. two share locks). This is because we currently do not have space to
6069 * track multiple lock ownerships of the same buffer within one backend. That
6070 * is ok for the current uses of BufferLockConditional().
6071 */
6072static bool
6074{
6076 bool mustwait;
6077
6078 /*
6079 * As described above, if we're trying to lock a buffer this backend
6080 * already has locked, return false, independent of the existing and
6081 * desired lock level.
6082 */
6083 if (entry->data.lockmode != BUFFER_LOCK_UNLOCK)
6084 return false;
6085
6086 /*
6087 * Lock out cancel/die interrupts until we exit the code section protected
6088 * by the content lock. This ensures that interrupts will not interfere
6089 * with manipulations of data structures in shared memory.
6090 */
6092
6093 /* Check for the lock */
6095
6096 if (mustwait)
6097 {
6098 /* Failed to get lock, so release interrupt holdoff */
6100 }
6101 else
6102 {
6103 entry->data.lockmode = mode;
6104 }
6105
6106 return !mustwait;
6107}
6108
6109/*
6110 * Internal function that tries to atomically acquire the content lock in the
6111 * passed in mode.
6112 *
6113 * This function will not block waiting for a lock to become free - that's the
6114 * caller's job.
6115 *
6116 * Similar to LWLockAttemptLock().
6117 */
6118static inline bool
6120{
6122
6123 /*
6124 * Read once outside the loop, later iterations will get the newer value
6125 * via compare & exchange.
6126 */
6128
6129 /* loop until we've determined whether we could acquire the lock or not */
6130 while (true)
6131 {
6133 bool lock_free;
6134
6136
6138 {
6139 lock_free = (old_state & BM_LOCK_MASK) == 0;
6140 if (lock_free)
6142 }
6144 {
6146 if (lock_free)
6148 }
6149 else
6150 {
6152 if (lock_free)
6154 }
6155
6156 /*
6157 * Attempt to swap in the state we are expecting. If we didn't see
6158 * lock to be free, that's just the old value. If we saw it as free,
6159 * we'll attempt to mark it acquired. The reason that we always swap
6160 * in the value is that this doubles as a memory barrier. We could try
6161 * to be smarter and only swap in values if we saw the lock as free,
6162 * but benchmark haven't shown it as beneficial so far.
6163 *
6164 * Retry if the value changed since we last looked at it.
6165 */
6168 {
6169 if (lock_free)
6170 {
6171 /* Great! Got the lock. */
6172 return false;
6173 }
6174 else
6175 return true; /* somebody else has the lock */
6176 }
6177 }
6178
6180}
6181
6182/*
6183 * Add ourselves to the end of the content lock's wait queue.
6184 */
6185static void
6187{
6188 /*
6189 * If we don't have a PGPROC structure, there's no way to wait. This
6190 * should never occur, since MyProc should only be null during shared
6191 * memory initialization.
6192 */
6193 if (MyProc == NULL)
6194 elog(PANIC, "cannot wait without a PGPROC structure");
6195
6197 elog(PANIC, "queueing for lock while waiting on another one");
6198
6200
6201 /* setting the flag is protected by the spinlock */
6203
6204 /*
6205 * These are currently used both for lwlocks and buffer content locks,
6206 * which is acceptable, although not pretty, because a backend can't wait
6207 * for both types of locks at the same time.
6208 */
6211
6212 proclist_push_tail(&buf_hdr->lock_waiters, MyProcNumber, lwWaitLink);
6213
6214 /* Can release the mutex now */
6216}
6217
6218/*
6219 * Remove ourselves from the waitlist.
6220 *
6221 * This is used if we queued ourselves because we thought we needed to sleep
6222 * but, after further checking, we discovered that we don't actually need to
6223 * do so.
6224 */
6225static void
6227{
6228 bool on_waitlist;
6229
6231
6233 if (on_waitlist)
6234 proclist_delete(&buf_hdr->lock_waiters, MyProcNumber, lwWaitLink);
6235
6236 if (proclist_is_empty(&buf_hdr->lock_waiters) &&
6238 {
6240 }
6241
6242 /* XXX: combine with fetch_and above? */
6244
6245 /* clear waiting state again, nice for debugging */
6246 if (on_waitlist)
6248 else
6249 {
6250 int extraWaits = 0;
6251
6252
6253 /*
6254 * Somebody else dequeued us and has or will wake us up. Deal with the
6255 * superfluous absorption of a wakeup.
6256 */
6257
6258 /*
6259 * Clear BM_LOCK_WAKE_IN_PROGRESS if somebody woke us before we
6260 * removed ourselves - they'll have set it.
6261 */
6263
6264 /*
6265 * Now wait for the scheduled wakeup, otherwise our ->lwWaiting would
6266 * get reset at some inconvenient point later. Most of the time this
6267 * will immediately return.
6268 */
6269 for (;;)
6270 {
6273 break;
6274 extraWaits++;
6275 }
6276
6277 /*
6278 * Fix the process wait semaphore's count for any absorbed wakeups.
6279 */
6280 while (extraWaits-- > 0)
6282 }
6283}
6284
6285/*
6286 * Stop treating lock as held by current backend.
6287 *
6288 * After calling this function it's the callers responsibility to ensure that
6289 * the lock gets released, even in case of an error. This only is desirable if
6290 * the lock is going to be released in a different process than the process
6291 * that acquired it.
6292 */
6293static inline void
6299
6300/*
6301 * Stop treating lock as held by current backend.
6302 *
6303 * This is the code that can be shared between actually releasing a lock
6304 * (BufferLockUnlock()) and just not tracking ownership of the lock anymore
6305 * without releasing the lock (BufferLockDisown()).
6306 */
6307static inline int
6309{
6312
6314 if (ref == NULL)
6315 elog(ERROR, "lock %d is not held", buffer);
6316 mode = ref->data.lockmode;
6317 ref->data.lockmode = BUFFER_LOCK_UNLOCK;
6318
6319 return mode;
6320}
6321
6322/*
6323 * Wakeup all the lockers that currently have a chance to acquire the lock.
6324 *
6325 * wake_exclusive indicates whether exclusive lock waiters should be woken up.
6326 */
6327static void
6329{
6330 bool new_wake_in_progress = false;
6331 bool wake_share_exclusive = true;
6334
6336
6337 /* lock wait list while collecting backends to wake up */
6339
6340 proclist_foreach_modify(iter, &buf_hdr->lock_waiters, lwWaitLink)
6341 {
6342 PGPROC *waiter = GetPGProcByNumber(iter.cur);
6343
6344 /*
6345 * Already woke up a conflicting lock, so skip over this wait list
6346 * entry.
6347 */
6349 continue;
6351 continue;
6352
6353 proclist_delete(&buf_hdr->lock_waiters, iter.cur, lwWaitLink);
6354 proclist_push_tail(&wakeup, iter.cur, lwWaitLink);
6355
6356 /*
6357 * Prevent additional wakeups until retryer gets to run. Backends that
6358 * are just waiting for the lock to become free don't retry
6359 * automatically.
6360 */
6361 new_wake_in_progress = true;
6362
6363 /*
6364 * Signal that the process isn't on the wait list anymore. This allows
6365 * BufferLockDequeueSelf() to remove itself from the waitlist with a
6366 * proclist_delete(), rather than having to check if it has been
6367 * removed from the list.
6368 */
6369 Assert(waiter->lwWaiting == LW_WS_WAITING);
6371
6372 /*
6373 * Don't wakeup further waiters after waking a conflicting waiter.
6374 */
6375 if (waiter->lwWaitMode == BUFFER_LOCK_SHARE)
6376 {
6377 /*
6378 * Share locks conflict with exclusive locks.
6379 */
6380 wake_exclusive = false;
6381 }
6382 else if (waiter->lwWaitMode == BUFFER_LOCK_SHARE_EXCLUSIVE)
6383 {
6384 /*
6385 * Share-exclusive locks conflict with share-exclusive and
6386 * exclusive locks.
6387 */
6388 wake_exclusive = false;
6389 wake_share_exclusive = false;
6390 }
6391 else if (waiter->lwWaitMode == BUFFER_LOCK_EXCLUSIVE)
6392 {
6393 /*
6394 * Exclusive locks conflict with all other locks, there's no point
6395 * in waking up anybody else.
6396 */
6397 break;
6398 }
6399 }
6400
6402
6403 /* unset required flags, and release lock, in one fell swoop */
6404 {
6407
6409 while (true)
6410 {
6412
6413 /* compute desired flags */
6414
6417 else
6419
6420 if (proclist_is_empty(&buf_hdr->lock_waiters))
6422
6423 desired_state &= ~BM_LOCKED; /* release lock */
6424
6427 break;
6428 }
6429 }
6430
6431 /* Awaken any waiters I removed from the queue. */
6432 proclist_foreach_modify(iter, &wakeup, lwWaitLink)
6433 {
6434 PGPROC *waiter = GetPGProcByNumber(iter.cur);
6435
6436 proclist_delete(&wakeup, iter.cur, lwWaitLink);
6437
6438 /*
6439 * Guarantee that lwWaiting being unset only becomes visible once the
6440 * unlink from the link has completed. Otherwise the target backend
6441 * could be woken up for other reason and enqueue for a new lock - if
6442 * that happens before the list unlink happens, the list would end up
6443 * being corrupted.
6444 *
6445 * The barrier pairs with the LockBufHdr() when enqueuing for another
6446 * lock.
6447 */
6449 waiter->lwWaiting = LW_WS_NOT_WAITING;
6450 PGSemaphoreUnlock(waiter->sem);
6451 }
6452}
6453
6454/*
6455 * Compute subtraction from buffer state for a release of a held lock in
6456 * `mode`.
6457 *
6458 * This is separated from BufferLockUnlock() as we want to combine the lock
6459 * release with other atomic operations when possible, leading to the lock
6460 * release being done in multiple places, each needing to compute what to
6461 * subtract from the lock state.
6462 */
6463static inline uint64
6465{
6466 /*
6467 * Turns out that a switch() leads gcc to generate sufficiently worse code
6468 * for this to show up in profiles...
6469 */
6471 return BM_LOCK_VAL_EXCLUSIVE;
6474 else
6475 {
6477 return BM_LOCK_VAL_SHARED;
6478 }
6479
6480 return 0; /* keep compiler quiet */
6481}
6482
6483/*
6484 * Handle work that needs to be done after releasing a lock that was held in
6485 * `mode`, where `lockstate` is the result of the atomic operation modifying
6486 * the state variable.
6487 *
6488 * This is separated from BufferLockUnlock() as we want to combine the lock
6489 * release with other atomic operations when possible, leading to the lock
6490 * release being done in multiple places.
6491 */
6492static void
6494{
6495 bool check_waiters = false;
6496 bool wake_exclusive = false;
6497
6498 /* nobody else can have that kind of lock */
6500
6501 /*
6502 * If we're still waiting for backends to get scheduled, don't wake them
6503 * up again. Otherwise check if we need to look through the waitqueue to
6504 * wake other backends.
6505 */
6508 {
6509 if ((lockstate & BM_LOCK_MASK) == 0)
6510 {
6511 /*
6512 * We released a lock and the lock was, in that moment, free. We
6513 * therefore can wake waiters for any kind of lock.
6514 */
6515 check_waiters = true;
6516 wake_exclusive = true;
6517 }
6519 {
6520 /*
6521 * We released the lock, but another backend still holds a lock.
6522 * We can't have released an exclusive lock, as there couldn't
6523 * have been other lock holders. If we released a share lock, no
6524 * waiters need to be woken up, as there must be other share
6525 * lockers. However, if we held a share-exclusive lock, another
6526 * backend now could acquire a share-exclusive lock.
6527 */
6528 check_waiters = true;
6529 wake_exclusive = false;
6530 }
6531 }
6532
6533 /*
6534 * As waking up waiters requires the spinlock to be acquired, only do so
6535 * if necessary.
6536 */
6537 if (check_waiters)
6539}
6540
6541/*
6542 * BufferLockHeldByMeInMode - test whether my process holds the content lock
6543 * in the specified mode
6544 *
6545 * This is meant as debug support only.
6546 */
6547static bool
6549{
6550 PrivateRefCountEntry *entry =
6552
6553 if (!entry)
6554 return false;
6555 else
6556 return entry->data.lockmode == mode;
6557}
6558
6559/*
6560 * BufferLockHeldByMe - test whether my process holds the content lock in any
6561 * mode
6562 *
6563 * This is meant as debug support only.
6564 */
6565static bool
6567{
6568 PrivateRefCountEntry *entry =
6570
6571 if (!entry)
6572 return false;
6573 else
6574 return entry->data.lockmode != BUFFER_LOCK_UNLOCK;
6575}
6576
6577/*
6578 * Release the content lock for the buffer.
6579 */
6580void
6582{
6584
6586 if (BufferIsLocal(buffer))
6587 return; /* local buffers need no lock */
6588
6591}
6592
6593/*
6594 * Acquire the content_lock for the buffer.
6595 */
6596void
6598{
6600
6601 /*
6602 * We can't wait if we haven't got a PGPROC. This should only occur
6603 * during bootstrap or shared memory initialization. Put an Assert here
6604 * to catch unsafe coding practices.
6605 */
6607
6608 /* handled in LockBuffer() wrapper */
6610
6612 if (BufferIsLocal(buffer))
6613 return; /* local buffers need no lock */
6614
6616
6617 /*
6618 * Test the most frequent lock modes first. While a switch (mode) would be
6619 * nice, at least gcc generates considerably worse code for it.
6620 *
6621 * Call BufferLockAcquire() with a constant argument for mode, to generate
6622 * more efficient code for the different lock modes.
6623 */
6624 if (mode == BUFFER_LOCK_SHARE)
6626 else if (mode == BUFFER_LOCK_EXCLUSIVE)
6630 else
6631 elog(ERROR, "unrecognized buffer lock mode: %d", mode);
6632}
6633
6634/*
6635 * Acquire the content_lock for the buffer, but only if we don't have to wait.
6636 *
6637 * This assumes the caller wants BUFFER_LOCK_EXCLUSIVE mode.
6638 */
6639bool
6641{
6642 BufferDesc *buf;
6643
6645 if (BufferIsLocal(buffer))
6646 return true; /* act as though we got it */
6647
6649
6651}
6652
6653/*
6654 * Verify that this backend is pinning the buffer exactly once.
6655 *
6656 * NOTE: Like in BufferIsPinned(), what we check here is that *this* backend
6657 * holds a pin on the buffer. We do not care whether some other backend does.
6658 */
6659void
6661{
6662 if (BufferIsLocal(buffer))
6663 {
6664 if (LocalRefCount[-buffer - 1] != 1)
6665 elog(ERROR, "incorrect local pin count: %d",
6666 LocalRefCount[-buffer - 1]);
6667 }
6668 else
6669 {
6670 if (GetPrivateRefCount(buffer) != 1)
6671 elog(ERROR, "incorrect local pin count: %d",
6673 }
6674}
6675
6676/*
6677 * LockBufferForCleanup - lock a buffer in preparation for deleting items
6678 *
6679 * Items may be deleted from a disk page only when the caller (a) holds an
6680 * exclusive lock on the buffer and (b) has observed that no other backend
6681 * holds a pin on the buffer. If there is a pin, then the other backend
6682 * might have a pointer into the buffer (for example, a heapscan reference
6683 * to an item --- see README for more details). It's OK if a pin is added
6684 * after the cleanup starts, however; the newly-arrived backend will be
6685 * unable to look at the page until we release the exclusive lock.
6686 *
6687 * To implement this protocol, a would-be deleter must pin the buffer and
6688 * then call LockBufferForCleanup(). LockBufferForCleanup() is similar to
6689 * LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE), except that it loops until
6690 * it has successfully observed pin count = 1.
6691 */
6692void
6694{
6696 TimestampTz waitStart = 0;
6697 bool waiting = false;
6698 bool logged_recovery_conflict = false;
6699
6702
6704
6705 /*
6706 * We do not yet need to be worried about in-progress AIOs holding a pin,
6707 * as we, so far, only support doing reads via AIO and this function can
6708 * only be called once the buffer is valid (i.e. no read can be in
6709 * flight).
6710 */
6711
6712 /* Nobody else to wait for */
6713 if (BufferIsLocal(buffer))
6714 return;
6715
6717
6718 for (;;)
6719 {
6721 uint64 unset_bits = 0;
6722
6723 /* Try to acquire lock */
6726
6729 {
6730 /* Successfully acquired exclusive lock with pincount 1 */
6733 }
6734 /* Failed, so mark myself as waiting for pincount 1 */
6736 {
6739 elog(ERROR, "multiple backends attempting to wait for pincount 1");
6740 }
6741 bufHdr->wait_backend_pgprocno = MyProcNumber;
6743
6744 /*
6745 * Publish BM_PIN_COUNT_WAITER while retaining the buffer header lock.
6746 * The shared refcount can be decremented while BM_LOCKED is set, so
6747 * use an atomic operation that preserves concurrent refcount changes.
6748 */
6750
6751 /*
6752 * Recheck the refcount after publishing the waiter flag, while shared
6753 * refcount increments are still prevented by BM_LOCKED. If only our
6754 * pin remains, the cleanup-lock condition has already been satisfied,
6755 * so remove the waiter state and return without sleeping.
6756 */
6758
6760 {
6763 0);
6766 }
6767
6770
6771 /* Wait to be signaled by UnpinBuffer() */
6772 if (InHotStandby)
6773 {
6774 if (!waiting)
6775 {
6776 /* adjust the process title to indicate that it's waiting */
6777 set_ps_display_suffix("waiting");
6778 waiting = true;
6779 }
6780
6781 /*
6782 * Emit the log message if the startup process is waiting longer
6783 * than deadlock_timeout for recovery conflict on buffer pin.
6784 *
6785 * Skip this if first time through because the startup process has
6786 * not started waiting yet in this case. So, the wait start
6787 * timestamp is set after this logic.
6788 */
6789 if (waitStart != 0 && !logged_recovery_conflict)
6790 {
6792
6793 if (TimestampDifferenceExceeds(waitStart, now,
6795 {
6797 waitStart, now, NULL, true);
6799 }
6800 }
6801
6802 /*
6803 * Set the wait start timestamp if logging is enabled and first
6804 * time through.
6805 */
6806 if (log_recovery_conflict_waits && waitStart == 0)
6807 waitStart = GetCurrentTimestamp();
6808
6809 /* Publish the bufid that Startup process waits on */
6811 /* Set alarm and then wait to be signaled by UnpinBuffer() */
6813 /* Reset the published bufid */
6815 }
6816 else
6818
6819 /*
6820 * Remove flag marking us as waiter. Normally this will not be set
6821 * anymore, but ProcWaitForSignal() can return for other signals as
6822 * well. We take care to only reset the flag if we're the waiter, as
6823 * theoretically another backend could have started waiting. That's
6824 * impossible with the current usages due to table level locking, but
6825 * better be safe.
6826 */
6828 if ((buf_state & BM_PIN_COUNT_WAITER) != 0 &&
6829 bufHdr->wait_backend_pgprocno == MyProcNumber)
6831
6833 0, unset_bits,
6834 0);
6835
6837 /* Loop back and try again */
6838 }
6839
6841
6842 /*
6843 * Emit the log message if recovery conflict on buffer pin was resolved
6844 * but the startup process waited longer than deadlock_timeout for it.
6845 */
6848 waitStart, GetCurrentTimestamp(),
6849 NULL, false);
6850
6851 if (waiting)
6852 {
6853 /* reset ps display to remove the suffix if we added one */
6855 waiting = false;
6856 }
6857
6858 return;
6859}
6860
6861/*
6862 * Check called from ProcessRecoveryConflictInterrupts() when Startup process
6863 * requests cancellation of all pin holders that are blocking it.
6864 */
6865bool
6867{
6869
6870 /*
6871 * If we get woken slowly then it's possible that the Startup process was
6872 * already woken by other backends before we got here. Also possible that
6873 * we get here by multiple interrupts or interrupts at inappropriate
6874 * times, so make sure we do nothing if the bufid is not set.
6875 */
6876 if (bufid < 0)
6877 return false;
6878
6879 if (GetPrivateRefCount(bufid + 1) > 0)
6880 return true;
6881
6882 return false;
6883}
6884
6885/*
6886 * ConditionalLockBufferForCleanup - as above, but don't wait to get the lock
6887 *
6888 * We won't loop, but just check once to see if the pin count is OK. If
6889 * not, return false with no lock held.
6890 */
6891bool
6893{
6896 refcount;
6897
6899
6900 /* see AIO related comment in LockBufferForCleanup() */
6901
6902 if (BufferIsLocal(buffer))
6903 {
6904 refcount = LocalRefCount[-buffer - 1];
6905 /* There should be exactly one pin */
6906 Assert(refcount > 0);
6907 if (refcount != 1)
6908 return false;
6909 /* Nobody else to wait for */
6910 return true;
6911 }
6912
6913 /* There should be exactly one local pin */
6914 refcount = GetPrivateRefCount(buffer);
6915 Assert(refcount);
6916 if (refcount != 1)
6917 return false;
6918
6919 /* Try to acquire lock */
6921 return false;
6922
6926
6927 Assert(refcount > 0);
6928 if (refcount == 1)
6929 {
6930 /* Successfully acquired exclusive lock with pincount 1 */
6932 return true;
6933 }
6934
6935 /* Failed, so release the lock */
6938 return false;
6939}
6940
6941/*
6942 * IsBufferCleanupOK - as above, but we already have the lock
6943 *
6944 * Check whether it's OK to perform cleanup on a buffer we've already
6945 * locked. If we observe that the pin count is 1, our exclusive lock
6946 * happens to be a cleanup lock, and we can proceed with anything that
6947 * would have been allowable had we sought a cleanup lock originally.
6948 */
6949bool
6951{
6954
6956
6957 /* see AIO related comment in LockBufferForCleanup() */
6958
6959 if (BufferIsLocal(buffer))
6960 {
6961 /* There should be exactly one pin */
6962 if (LocalRefCount[-buffer - 1] != 1)
6963 return false;
6964 /* Nobody else to wait for */
6965 return true;
6966 }
6967
6968 /* There should be exactly one local pin */
6969 if (GetPrivateRefCount(buffer) != 1)
6970 return false;
6971
6973
6974 /* caller must hold exclusive lock on buffer */
6976
6978
6981 {
6982 /* pincount is OK. */
6984 return true;
6985 }
6986
6988 return false;
6989}
6990
6991/*
6992 * Helper for BufferBeginSetHintBits() and BufferSetHintBits16().
6993 *
6994 * This checks if the current lock mode already suffices to allow hint bits
6995 * being set and, if not, whether the current lock can be upgraded.
6996 *
6997 * Updates *lockstate when returning true.
6998 */
6999static inline bool
7001{
7005
7007
7008 if (ref == NULL)
7009 elog(ERROR, "buffer is not pinned");
7010
7011 mode = ref->data.lockmode;
7012 if (mode == BUFFER_LOCK_UNLOCK)
7013 elog(ERROR, "buffer is not locked");
7014
7015 /* we're done if we are already holding a sufficient lock level */
7017 {
7019 return true;
7020 }
7021
7022 /*
7023 * We are only holding a share lock right now, try to upgrade it to
7024 * SHARE_EXCLUSIVE.
7025 */
7027
7029 while (true)
7030 {
7032
7034
7035 /*
7036 * Can't upgrade if somebody else holds the lock in exclusive or
7037 * share-exclusive mode.
7038 */
7040 {
7041 return false;
7042 }
7043
7044 /* currently held lock state */
7046
7047 /* new lock level */
7049
7052 {
7053 ref->data.lockmode = BUFFER_LOCK_SHARE_EXCLUSIVE;
7055
7056 return true;
7057 }
7058 }
7059}
7060
7061/*
7062 * Try to acquire the right to set hint bits on the buffer.
7063 *
7064 * To be allowed to set hint bits, this backend needs to hold either a
7065 * share-exclusive or an exclusive lock. In case this backend only holds a
7066 * share lock, this function will try to upgrade the lock to
7067 * share-exclusive. The caller is only allowed to set hint bits if true is
7068 * returned.
7069 *
7070 * Once BufferBeginSetHintBits() has returned true, hint bits may be set
7071 * without further calls to BufferBeginSetHintBits(), until the buffer is
7072 * unlocked.
7073 *
7074 *
7075 * Requiring a share-exclusive lock to set hint bits prevents setting hint
7076 * bits on buffers that are currently being written out, which could corrupt
7077 * the checksum on the page. Flushing buffers also requires a share-exclusive
7078 * lock.
7079 *
7080 * Due to a lock >= share-exclusive being required to set hint bits, only one
7081 * backend can set hint bits at a time. Allowing multiple backends to set hint
7082 * bits would require more complicated locking: For setting hint bits we'd
7083 * need to store the count of backends currently setting hint bits, for I/O we
7084 * would need another lock-level conflicting with the hint-setting
7085 * lock-level. Given that the share-exclusive lock for setting hint bits is
7086 * only held for a short time, that backends often would just set the same
7087 * hint bits and that the cost of occasionally not setting hint bits in hotly
7088 * accessed pages is fairly low, this seems like an acceptable tradeoff.
7089 */
7090bool
7092{
7095
7096 if (BufferIsLocal(buffer))
7097 {
7098 /*
7099 * NB: Will need to check if there is a write in progress, once it is
7100 * possible for writes to be done asynchronously.
7101 */
7102 return true;
7103 }
7104
7106
7108}
7109
7110/*
7111 * End a phase of setting hint bits on this buffer, started with
7112 * BufferBeginSetHintBits().
7113 *
7114 * This would strictly speaking not be required (i.e. the caller could do
7115 * MarkBufferDirtyHint() if so desired), but allows us to perform some sanity
7116 * checks.
7117 */
7118void
7128
7129/*
7130 * Try to set hint bits on a single 16bit value in a buffer.
7131 *
7132 * If hint bits are allowed to be set, set *ptr = val, try to mark the buffer
7133 * dirty and return true. Otherwise false is returned.
7134 *
7135 * *ptr needs to be a pointer to memory within the buffer.
7136 *
7137 * This is a bit faster than BufferBeginSetHintBits() /
7138 * BufferFinishSetHintBits() when setting hints once in a buffer, but slower
7139 * than the former when setting hint bits multiple times in the same buffer.
7140 */
7141bool
7143{
7146#ifdef USE_ASSERT_CHECKING
7147 char *page;
7148
7149 /* verify that the address is on the page */
7150 page = BufferGetPage(buffer);
7151 Assert((char *) ptr >= page && (char *) ptr < (page + BLCKSZ));
7152#endif
7153
7154 if (BufferIsLocal(buffer))
7155 {
7156 *ptr = val;
7157
7159
7160 return true;
7161 }
7162
7164
7166 {
7167 *ptr = val;
7168
7170
7171 return true;
7172 }
7173
7174 return false;
7175}
7176
7177
7178/*
7179 * Functions for buffer I/O handling
7180 *
7181 * Also note that these are used only for shared buffers, not local ones.
7182 */
7183
7184/*
7185 * WaitIO -- Block until the IO_IN_PROGRESS flag on 'buf' is cleared.
7186 */
7187static void
7189{
7191
7192 /*
7193 * Should never end up here with unsubmitted IO, as no AIO unaware code
7194 * may be used while in batch mode and AIO aware code needs to have
7195 * submitted all staged IO to avoid deadlocks & slowness.
7196 */
7198
7200 for (;;)
7201 {
7204
7205 /*
7206 * It may not be necessary to acquire the spinlock to check the flag
7207 * here, but since this test is essential for correctness, we'd better
7208 * play it safe.
7209 */
7211
7212 /*
7213 * Copy the wait reference while holding the spinlock. This protects
7214 * against a concurrent TerminateBufferIO() in another backend from
7215 * clearing the wref while it's being read.
7216 */
7217 iow = buf->io_wref;
7219
7220 /* no IO in progress, we don't need to wait */
7222 break;
7223
7224 /*
7225 * The buffer has asynchronous IO in progress, wait for it to
7226 * complete.
7227 */
7228 if (pgaio_wref_valid(&iow))
7229 {
7231
7232 /*
7233 * The AIO subsystem internally uses condition variables and thus
7234 * might remove this backend from the BufferDesc's CV. While that
7235 * wouldn't cause a correctness issue (the first CV sleep just
7236 * immediately returns if not already registered), it seems worth
7237 * avoiding unnecessary loop iterations, given that we take care
7238 * to do so at the start of the function.
7239 */
7241 continue;
7242 }
7243
7244 /* wait on BufferDesc->cv, e.g. for concurrent synchronous IO */
7246 }
7248}
7249
7250/*
7251 * StartSharedBufferIO: begin I/O on this buffer
7252 * (Assumptions)
7253 * The buffer is Pinned
7254 *
7255 * In several scenarios the buffer may already be undergoing I/O in this or
7256 * another backend. How to best handle that depends on the caller's
7257 * situation. It might be appropriate to wait synchronously (e.g., because the
7258 * buffer is about to be invalidated); wait asynchronously, using the buffer's
7259 * IO wait reference (e.g., because the caller is doing readahead and doesn't
7260 * need the buffer to be ready immediately); or to not wait at all (e.g.,
7261 * because the caller is trying to combine IO for this buffer with another
7262 * buffer).
7263 *
7264 * How and whether to wait is controlled by the wait and io_wref
7265 * parameters. In detail:
7266 *
7267 * - If the caller passes a non-NULL io_wref and the buffer has an I/O wait
7268 * reference, the *io_wref is set to the buffer's io_wref and
7269 * BUFFER_IO_IN_PROGRESS is returned. This is done regardless of the wait
7270 * parameter.
7271 *
7272 * - If the caller passes a NULL io_wref (i.e. the caller does not want to
7273 * asynchronously wait for the completion of the IO), wait = false and the
7274 * buffer is undergoing IO, BUFFER_IO_IN_PROGRESS is returned.
7275 *
7276 * - If wait = true and either the buffer does not have a wait reference,
7277 * or the caller passes io_wref = NULL, WaitIO() is used to wait for the IO
7278 * to complete. To avoid the potential of deadlocks and unnecessary delays,
7279 * all staged I/O is submitted before waiting.
7280 *
7281 * Input operations are only attempted on buffers that are not BM_VALID, and
7282 * output operations only on buffers that are BM_VALID and BM_DIRTY, so we can
7283 * always tell if the work is already done. If no I/O is necessary,
7284 * BUFFER_IO_ALREADY_DONE is returned.
7285 *
7286 * If we successfully marked the buffer as BM_IO_IN_PROGRESS,
7287 * BUFFER_IO_READY_FOR_IO is returned.
7288 */
7291{
7293
7295
7296 for (;;)
7297 {
7299
7301 break;
7302
7303 /* Join the existing IO */
7304 if (io_wref != NULL && pgaio_wref_valid(&buf->io_wref))
7305 {
7306 *io_wref = buf->io_wref;
7308
7309 return BUFFER_IO_IN_PROGRESS;
7310 }
7311 else if (!wait)
7312 {
7314 return BUFFER_IO_IN_PROGRESS;
7315 }
7316 else
7317 {
7318 /*
7319 * With wait = true, we always have to wait if the caller has
7320 * passed io_wref = NULL.
7321 *
7322 * Even with io_wref != NULL, we have to wait if the buffer's wait
7323 * ref is not valid but the IO is in progress, someone else
7324 * started IO but hasn't set the wait ref yet. We have no choice
7325 * but to wait until the IO completes.
7326 */
7328
7329 /*
7330 * If this backend currently has staged IO, submit it before
7331 * waiting for in-progress IO, to avoid potential deadlocks and
7332 * unnecessary delays.
7333 */
7335
7336 WaitIO(buf);
7337 }
7338 }
7339
7340 /* Once we get here, there is definitely no I/O active on this buffer */
7341
7342 /* Check if someone else already did the I/O */
7343 if (forInput ? (buf_state & BM_VALID) : !(buf_state & BM_DIRTY))
7344 {
7347 }
7348
7349 /*
7350 * No IO in progress and not already done; we will start IO. It's possible
7351 * that the IO was in progress but we're not done, because the IO errored
7352 * out. We'll do the IO ourselves.
7353 */
7356 0);
7357
7360
7362}
7363
7364/*
7365 * Wrapper around StartSharedBufferIO / StartLocalBufferIO. Only to be used
7366 * when the caller doesn't otherwise need to care about local vs shared. See
7367 * StartSharedBufferIO() for details.
7368 */
7371{
7373
7374 if (BufferIsLocal(buffer))
7375 {
7377
7378 return StartLocalBufferIO(buf_hdr, forInput, wait, io_wref);
7379 }
7380 else
7381 {
7383
7384 return StartSharedBufferIO(buf_hdr, forInput, wait, io_wref);
7385 }
7386}
7387
7388/*
7389 * TerminateBufferIO: release a buffer we were doing I/O on
7390 * (Assumptions)
7391 * My process is executing IO for the buffer
7392 * BM_IO_IN_PROGRESS bit is set for the buffer
7393 * The buffer is Pinned
7394 *
7395 * If clear_dirty is true, we clear the buffer's BM_DIRTY flag. This is
7396 * appropriate when terminating a successful write.
7397 *
7398 * set_flag_bits gets ORed into the buffer's flags. It must include
7399 * BM_IO_ERROR in a failure case. For successful completion it could
7400 * be 0, or BM_VALID if we just finished reading in the page.
7401 *
7402 * If forget_owner is true, we release the buffer I/O from the current
7403 * resource owner. (forget_owner=false is used when the resource owner itself
7404 * is being released)
7405 */
7406void
7408 bool forget_owner, bool release_aio)
7409{
7412 int refcount_change = 0;
7413
7415
7418
7419 /* Clear earlier errors, if this IO failed, it'll be marked again */
7421
7422 if (clear_dirty)
7424
7425 if (release_aio)
7426 {
7427 /* release ownership by the AIO subsystem */
7429 refcount_change = -1;
7430 pgaio_wref_clear(&buf->io_wref);
7431 }
7432
7436
7437 if (forget_owner)
7440
7442
7443 /*
7444 * Support LockBufferForCleanup()
7445 *
7446 * We may have just released the last pin other than the waiter's. In most
7447 * cases, this backend holds another pin on the buffer. But, if, for
7448 * example, this backend is completing an IO issued by another backend, it
7449 * may be time to wake the waiter.
7450 */
7453}
7454
7455/*
7456 * AbortBufferIO: Clean up active buffer I/O after an error.
7457 *
7458 * All LWLocks & content locks we might have held have been released, but we
7459 * haven't yet released buffer pins, so the buffer is still pinned.
7460 *
7461 * If I/O was in progress, we always set BM_IO_ERROR, even though it's
7462 * possible the error condition wasn't related to the I/O.
7463 *
7464 * Note: this does not remove the buffer I/O from the resource owner.
7465 * That's correct when we're releasing the whole resource owner, but
7466 * beware if you use this in other contexts.
7467 */
7468static void
7470{
7473
7476
7477 if (!(buf_state & BM_VALID))
7478 {
7481 }
7482 else
7483 {
7486
7487 /* Issue notice if this is not the first failure... */
7488 if (buf_state & BM_IO_ERROR)
7489 {
7490 /* Buffer is pinned, so we can read tag without spinlock */
7493 errmsg("could not write block %u of %s",
7494 buf_hdr->tag.blockNum,
7496 BufTagGetForkNum(&buf_hdr->tag)).str),
7497 errdetail("Multiple failures --- write error might be permanent.")));
7498 }
7499 }
7500
7501 TerminateBufferIO(buf_hdr, false, BM_IO_ERROR, false, false);
7502}
7503
7504/*
7505 * Error context callback for errors occurring during shared buffer writes.
7506 */
7507static void
7509{
7511
7512 /* Buffer is pinned, so we can read the tag without locking the spinlock */
7513 if (bufHdr != NULL)
7514 errcontext("writing block %u of relation \"%s\"",
7515 bufHdr->tag.blockNum,
7517 BufTagGetForkNum(&bufHdr->tag)).str);
7518}
7519
7520/*
7521 * Error context callback for errors occurring during local buffer writes.
7522 */
7523static void
7525{
7527
7528 if (bufHdr != NULL)
7529 errcontext("writing block %u of relation \"%s\"",
7530 bufHdr->tag.blockNum,
7533 BufTagGetForkNum(&bufHdr->tag)).str);
7534}
7535
7536/*
7537 * RelFileLocator qsort/bsearch comparator; see RelFileLocatorEquals.
7538 */
7539static int
7540rlocator_comparator(const void *p1, const void *p2)
7541{
7542 RelFileLocator n1 = *(const RelFileLocator *) p1;
7543 RelFileLocator n2 = *(const RelFileLocator *) p2;
7544
7545 if (n1.relNumber < n2.relNumber)
7546 return -1;
7547 else if (n1.relNumber > n2.relNumber)
7548 return 1;
7549
7550 if (n1.dbOid < n2.dbOid)
7551 return -1;
7552 else if (n1.dbOid > n2.dbOid)
7553 return 1;
7554
7555 if (n1.spcOid < n2.spcOid)
7556 return -1;
7557 else if (n1.spcOid > n2.spcOid)
7558 return 1;
7559 else
7560 return 0;
7561}
7562
7563/*
7564 * Lock buffer header - set BM_LOCKED in buffer state.
7565 */
7566uint64
7568{
7570
7572
7573 while (true)
7574 {
7575 /*
7576 * Always try once to acquire the lock directly, without setting up
7577 * the spin-delay infrastructure. The work necessary for that shows up
7578 * in profiles and is rarely necessary.
7579 */
7581 if (likely(!(old_buf_state & BM_LOCKED)))
7582 break; /* got lock */
7583
7584 /* and then spin without atomic operations until lock is released */
7585 {
7587
7589
7590 while (old_buf_state & BM_LOCKED)
7591 {
7594 }
7596 }
7597
7598 /*
7599 * Retry. The lock might obviously already be re-acquired by the time
7600 * we're attempting to get it again.
7601 */
7602 }
7603
7604 return old_buf_state | BM_LOCKED;
7605}
7606
7607/*
7608 * Wait until the BM_LOCKED flag isn't set anymore and return the buffer's
7609 * state at that point.
7610 *
7611 * Obviously the buffer could be locked by the time the value is returned, so
7612 * this is primarily useful in CAS style loops.
7613 */
7616{
7619
7621
7622 buf_state = pg_atomic_read_u64(&buf->state);
7623
7624 while (buf_state & BM_LOCKED)
7625 {
7627 buf_state = pg_atomic_read_u64(&buf->state);
7628 }
7629
7631
7632 return buf_state;
7633}
7634
7635/*
7636 * BufferTag comparator.
7637 */
7638static inline int
7640{
7641 int ret;
7644
7647
7649
7650 if (ret != 0)
7651 return ret;
7652
7654 return -1;
7656 return 1;
7657
7658 if (ba->blockNum < bb->blockNum)
7659 return -1;
7660 if (ba->blockNum > bb->blockNum)
7661 return 1;
7662
7663 return 0;
7664}
7665
7666/*
7667 * Comparator determining the writeout order in a checkpoint.
7668 *
7669 * It is important that tablespaces are compared first, the logic balancing
7670 * writes between tablespaces relies on it.
7671 */
7672static inline int
7674{
7675 /* compare tablespace */
7676 if (a->tsId < b->tsId)
7677 return -1;
7678 else if (a->tsId > b->tsId)
7679 return 1;
7680 /* compare relation */
7681 if (a->relNumber < b->relNumber)
7682 return -1;
7683 else if (a->relNumber > b->relNumber)
7684 return 1;
7685 /* compare fork */
7686 else if (a->forkNum < b->forkNum)
7687 return -1;
7688 else if (a->forkNum > b->forkNum)
7689 return 1;
7690 /* compare block number */
7691 else if (a->blockNum < b->blockNum)
7692 return -1;
7693 else if (a->blockNum > b->blockNum)
7694 return 1;
7695 /* equal page IDs are unlikely, but not impossible */
7696 return 0;
7697}
7698
7699/*
7700 * Comparator for a Min-Heap over the per-tablespace checkpoint completion
7701 * progress.
7702 */
7703static int
7705{
7708
7709 /* we want a min-heap, so return 1 for the a < b */
7710 if (sa->progress < sb->progress)
7711 return 1;
7712 else if (sa->progress == sb->progress)
7713 return 0;
7714 else
7715 return -1;
7716}
7717
7718/*
7719 * Initialize a writeback context, discarding potential previous state.
7720 *
7721 * *max_pending is a pointer instead of an immediate value, so the coalesce
7722 * limits can easily changed by the GUC mechanism, and so calling code does
7723 * not have to check the current configuration. A value of 0 means that no
7724 * writeback control will be performed.
7725 */
7726void
7727WritebackContextInit(WritebackContext *context, int *max_pending)
7728{
7729 Assert(*max_pending <= WRITEBACK_MAX_PENDING_FLUSHES);
7730
7731 context->max_pending = max_pending;
7732 context->nr_pending = 0;
7733}
7734
7735/*
7736 * Add buffer to list of pending writeback requests.
7737 */
7738void
7740 BufferTag *tag)
7741{
7742 PendingWriteback *pending;
7743
7744 /*
7745 * As pg_flush_data() doesn't do anything with fsync disabled, there's no
7746 * point in tracking in that case.
7747 */
7749 !enableFsync)
7750 return;
7751
7752 /*
7753 * Add buffer to the pending writeback array, unless writeback control is
7754 * disabled.
7755 */
7756 if (*wb_context->max_pending > 0)
7757 {
7759
7760 pending = &wb_context->pending_writebacks[wb_context->nr_pending++];
7761
7762 pending->tag = *tag;
7763 }
7764
7765 /*
7766 * Perform pending flushes if the writeback limit is exceeded. This
7767 * includes the case where previously an item has been added, but control
7768 * is now disabled.
7769 */
7770 if (wb_context->nr_pending >= *wb_context->max_pending)
7772}
7773
7774#define ST_SORT sort_pending_writebacks
7775#define ST_ELEMENT_TYPE PendingWriteback
7776#define ST_COMPARE(a, b) buffertag_comparator(&a->tag, &b->tag)
7777#define ST_SCOPE static
7778#define ST_DEFINE
7779#include "lib/sort_template.h"
7780
7781/*
7782 * Issue all pending writeback requests, previously scheduled with
7783 * ScheduleBufferTagForWriteback, to the OS.
7784 *
7785 * Because this is only used to improve the OSs IO scheduling we try to never
7786 * error out - it's just a hint.
7787 */
7788void
7790{
7792 int i;
7793
7794 if (wb_context->nr_pending == 0)
7795 return;
7796
7797 /*
7798 * Executing the writes in-order can make them a lot faster, and allows to
7799 * merge writeback requests to consecutive blocks into larger writebacks.
7800 */
7801 sort_pending_writebacks(wb_context->pending_writebacks,
7802 wb_context->nr_pending);
7803
7805
7806 /*
7807 * Coalesce neighbouring writes, but nothing else. For that we iterate
7808 * through the, now sorted, array of pending flushes, and look forward to
7809 * find all neighbouring (or identical) writes.
7810 */
7811 for (i = 0; i < wb_context->nr_pending; i++)
7812 {
7816 int ahead;
7817 BufferTag tag;
7819 Size nblocks = 1;
7820
7821 cur = &wb_context->pending_writebacks[i];
7822 tag = cur->tag;
7824
7825 /*
7826 * Peek ahead, into following writeback requests, to see if they can
7827 * be combined with the current one.
7828 */
7829 for (ahead = 0; i + ahead + 1 < wb_context->nr_pending; ahead++)
7830 {
7831
7832 next = &wb_context->pending_writebacks[i + ahead + 1];
7833
7834 /* different file, stop */
7836 BufTagGetRelFileLocator(&next->tag)) ||
7837 BufTagGetForkNum(&cur->tag) != BufTagGetForkNum(&next->tag))
7838 break;
7839
7840 /* ok, block queued twice, skip */
7841 if (cur->tag.blockNum == next->tag.blockNum)
7842 continue;
7843
7844 /* only merge consecutive writes */
7845 if (cur->tag.blockNum + 1 != next->tag.blockNum)
7846 break;
7847
7848 nblocks++;
7849 cur = next;
7850 }
7851
7852 i += ahead;
7853
7854 /* and finally tell the kernel to write the data to storage */
7856 smgrwriteback(reln, BufTagGetForkNum(&tag), tag.blockNum, nblocks);
7857 }
7858
7859 /*
7860 * Assume that writeback requests are only issued for buffers containing
7861 * blocks of permanent relations.
7862 */
7864 IOOP_WRITEBACK, io_start, wb_context->nr_pending, 0);
7865
7866 wb_context->nr_pending = 0;
7867}
7868
7869/* ResourceOwner callbacks */
7870
7871static void
7878
7879static char *
7881{
7883
7884 return psprintf("lost track of buffer IO on buffer %d", buffer);
7885}
7886
7887/*
7888 * Release buffer as part of resource owner cleanup. This will only be called
7889 * if the buffer is pinned. If this backend held the content lock at the time
7890 * of the error we also need to release that (note that it is not possible to
7891 * hold a content lock without a pin).
7892 */
7893static void
7895{
7897
7898 /* Like ReleaseBuffer, but don't call ResourceOwnerForgetBuffer */
7899 if (!BufferIsValid(buffer))
7900 elog(ERROR, "bad buffer ID: %d", buffer);
7901
7902 if (BufferIsLocal(buffer))
7904 else
7905 {
7907
7909
7910 /* not having a private refcount would imply resowner corruption */
7911 Assert(ref != NULL);
7912
7913 /*
7914 * If the buffer was locked at the time of the resowner release,
7915 * release the lock now. This should only happen after errors.
7916 */
7917 if (ref->data.lockmode != BUFFER_LOCK_UNLOCK)
7918 {
7920
7921 HOLD_INTERRUPTS(); /* match the upcoming RESUME_INTERRUPTS */
7923 }
7924
7926 }
7927}
7928
7929static char *
7934
7935/*
7936 * Helper function to evict unpinned buffer whose buffer header lock is
7937 * already acquired.
7938 */
7939static bool
7941{
7943 bool result;
7944
7945 *buffer_flushed = false;
7946
7949
7950 if ((buf_state & BM_VALID) == 0)
7951 {
7952 UnlockBufHdr(desc);
7953 return false;
7954 }
7955
7956 /* Check that it's not pinned already. */
7958 {
7959 UnlockBufHdr(desc);
7960 return false;
7961 }
7962
7963 PinBuffer_Locked(desc); /* releases spinlock */
7964
7965 /* If it was dirty, try to clean it once. */
7966 if (buf_state & BM_DIRTY)
7967 {
7969 *buffer_flushed = true;
7970 }
7971
7972 /* This will return false if it becomes dirty or someone else pins it. */
7974
7975 UnpinBuffer(desc);
7976
7977 return result;
7978}
7979
7980/*
7981 * Try to evict the current block in a shared buffer.
7982 *
7983 * This function is intended for testing/development use only!
7984 *
7985 * To succeed, the buffer must not be pinned on entry, so if the caller had a
7986 * particular block in mind, it might already have been replaced by some other
7987 * block by the time this function runs. It's also unpinned on return, so the
7988 * buffer might be occupied again by the time control is returned, potentially
7989 * even by the same block. This inherent raciness without other interlocking
7990 * makes the function unsuitable for non-testing usage.
7991 *
7992 * *buffer_flushed is set to true if the buffer was dirty and has been
7993 * flushed, false otherwise. However, *buffer_flushed=true does not
7994 * necessarily mean that we flushed the buffer, it could have been flushed by
7995 * someone else.
7996 *
7997 * Returns true if the buffer was valid and it has now been made invalid.
7998 * Returns false if it wasn't valid, if it couldn't be evicted due to a pin,
7999 * or if the buffer becomes dirty again while we're trying to write it out.
8000 */
8001bool
8003{
8004 BufferDesc *desc;
8005
8007
8008 /* Make sure we can pin the buffer. */
8011
8012 desc = GetBufferDescriptor(buf - 1);
8013 LockBufHdr(desc);
8014
8016}
8017
8018/*
8019 * Try to evict all the shared buffers.
8020 *
8021 * This function is intended for testing/development use only! See
8022 * EvictUnpinnedBuffer().
8023 *
8024 * The buffers_* parameters are mandatory and indicate the total count of
8025 * buffers that:
8026 * - buffers_evicted - were evicted
8027 * - buffers_flushed - were flushed
8028 * - buffers_skipped - could not be evicted
8029 */
8030void
8033{
8034 *buffers_evicted = 0;
8035 *buffers_skipped = 0;
8036 *buffers_flushed = 0;
8037
8038 for (int buf = 1; buf <= NBuffers; buf++)
8039 {
8040 BufferDesc *desc = GetBufferDescriptor(buf - 1);
8042 bool buffer_flushed;
8043
8045
8047 if (!(buf_state & BM_VALID))
8048 continue;
8049
8052
8053 LockBufHdr(desc);
8054
8056 (*buffers_evicted)++;
8057 else
8058 (*buffers_skipped)++;
8059
8060 if (buffer_flushed)
8061 (*buffers_flushed)++;
8062 }
8063}
8064
8065/*
8066 * Try to evict all the shared buffers containing provided relation's pages.
8067 *
8068 * This function is intended for testing/development use only! See
8069 * EvictUnpinnedBuffer().
8070 *
8071 * The caller must hold at least AccessShareLock on the relation to prevent
8072 * the relation from being dropped.
8073 *
8074 * The buffers_* parameters are mandatory and indicate the total count of
8075 * buffers that:
8076 * - buffers_evicted - were evicted
8077 * - buffers_flushed - were flushed
8078 * - buffers_skipped - could not be evicted
8079 */
8080void
8083{
8085
8086 *buffers_skipped = 0;
8087 *buffers_evicted = 0;
8088 *buffers_flushed = 0;
8089
8090 for (int buf = 1; buf <= NBuffers; buf++)
8091 {
8092 BufferDesc *desc = GetBufferDescriptor(buf - 1);
8094 bool buffer_flushed;
8095
8097
8098 /* An unlocked precheck should be safe and saves some cycles. */
8099 if ((buf_state & BM_VALID) == 0 ||
8101 continue;
8102
8103 /* Make sure we can pin the buffer. */
8106
8107 buf_state = LockBufHdr(desc);
8108
8109 /* recheck, could have changed without the lock */
8110 if ((buf_state & BM_VALID) == 0 ||
8112 {
8113 UnlockBufHdr(desc);
8114 continue;
8115 }
8116
8118 (*buffers_evicted)++;
8119 else
8120 (*buffers_skipped)++;
8121
8122 if (buffer_flushed)
8123 (*buffers_flushed)++;
8124 }
8125}
8126
8127/*
8128 * Helper function to mark unpinned buffer dirty whose buffer header lock is
8129 * already acquired.
8130 */
8131static bool
8134{
8136 bool result = false;
8137
8138 *buffer_already_dirty = false;
8139
8142
8143 if ((buf_state & BM_VALID) == 0)
8144 {
8145 UnlockBufHdr(desc);
8146 return false;
8147 }
8148
8149 /* Check that it's not pinned already. */
8151 {
8152 UnlockBufHdr(desc);
8153 return false;
8154 }
8155
8156 /* Pin the buffer and then release the buffer spinlock */
8157 PinBuffer_Locked(desc);
8158
8159 /* If it was not already dirty, mark it as dirty. */
8160 if (!(buf_state & BM_DIRTY))
8161 {
8164 result = true;
8165 BufferLockUnlock(buf, desc);
8166 }
8167 else
8168 *buffer_already_dirty = true;
8169
8170 UnpinBuffer(desc);
8171
8172 return result;
8173}
8174
8175/*
8176 * Try to mark the provided shared buffer as dirty.
8177 *
8178 * This function is intended for testing/development use only!
8179 *
8180 * Same as EvictUnpinnedBuffer() but with MarkBufferDirty() call inside.
8181 *
8182 * The buffer_already_dirty parameter is mandatory and indicate if the buffer
8183 * could not be dirtied because it is already dirty.
8184 *
8185 * Returns true if the buffer has successfully been marked as dirty.
8186 */
8187bool
8189{
8190 BufferDesc *desc;
8191 bool buffer_dirtied = false;
8192
8194
8195 /* Make sure we can pin the buffer. */
8198
8199 desc = GetBufferDescriptor(buf - 1);
8200 LockBufHdr(desc);
8201
8203 /* Both can not be true at the same time */
8205
8206 return buffer_dirtied;
8207}
8208
8209/*
8210 * Try to mark all the shared buffers containing provided relation's pages as
8211 * dirty.
8212 *
8213 * This function is intended for testing/development use only! See
8214 * MarkDirtyUnpinnedBuffer().
8215 *
8216 * The buffers_* parameters are mandatory and indicate the total count of
8217 * buffers that:
8218 * - buffers_dirtied - were dirtied
8219 * - buffers_already_dirty - were already dirty
8220 * - buffers_skipped - could not be dirtied because of a reason different
8221 * than a buffer being already dirty.
8222 */
8223void
8228{
8230
8231 *buffers_dirtied = 0;
8233 *buffers_skipped = 0;
8234
8235 for (int buf = 1; buf <= NBuffers; buf++)
8236 {
8237 BufferDesc *desc = GetBufferDescriptor(buf - 1);
8240
8242
8243 /* An unlocked precheck should be safe and saves some cycles. */
8244 if ((buf_state & BM_VALID) == 0 ||
8246 continue;
8247
8248 /* Make sure we can pin the buffer. */
8251
8252 buf_state = LockBufHdr(desc);
8253
8254 /* recheck, could have changed without the lock */
8255 if ((buf_state & BM_VALID) == 0 ||
8257 {
8258 UnlockBufHdr(desc);
8259 continue;
8260 }
8261
8263 (*buffers_dirtied)++;
8264 else if (buffer_already_dirty)
8265 (*buffers_already_dirty)++;
8266 else
8267 (*buffers_skipped)++;
8268 }
8269}
8270
8271/*
8272 * Try to mark all the shared buffers as dirty.
8273 *
8274 * This function is intended for testing/development use only! See
8275 * MarkDirtyUnpinnedBuffer().
8276 *
8277 * See MarkDirtyRelUnpinnedBuffers() above for details about the buffers_*
8278 * parameters.
8279 */
8280void
8284{
8285 *buffers_dirtied = 0;
8287 *buffers_skipped = 0;
8288
8289 for (int buf = 1; buf <= NBuffers; buf++)
8290 {
8291 BufferDesc *desc = GetBufferDescriptor(buf - 1);
8294
8296
8298 if (!(buf_state & BM_VALID))
8299 continue;
8300
8303
8304 LockBufHdr(desc);
8305
8307 (*buffers_dirtied)++;
8308 else if (buffer_already_dirty)
8309 (*buffers_already_dirty)++;
8310 else
8311 (*buffers_skipped)++;
8312 }
8313}
8314
8315/*
8316 * Generic implementation of the AIO handle staging callback for readv/writev
8317 * on local/shared buffers.
8318 *
8319 * Each readv/writev can target multiple buffers. The buffers have already
8320 * been registered with the IO handle.
8321 *
8322 * To make the IO ready for execution ("staging"), we need to ensure that the
8323 * targeted buffers are in an appropriate state while the IO is ongoing. For
8324 * that the AIO subsystem needs to have its own buffer pin, otherwise an error
8325 * in this backend could lead to this backend's buffer pin being released as
8326 * part of error handling, which in turn could lead to the buffer being
8327 * replaced while IO is ongoing.
8328 */
8329static pg_always_inline void
8331{
8332 uint64 *io_data;
8333 uint8 handle_data_len;
8336
8337 io_data = pgaio_io_get_handle_data(ioh, &handle_data_len);
8338
8340
8341 /* iterate over all buffers affected by the vectored readv/writev */
8342 for (int i = 0; i < handle_data_len; i++)
8343 {
8345 BufferDesc *buf_hdr = is_temp ?
8349
8350 /*
8351 * Check that all the buffers are actually ones that could conceivably
8352 * be done in one IO, i.e. are sequential. This is the last
8353 * buffer-aware code before IO is actually executed and confusion
8354 * about which buffers are targeted by IO can be hard to debug, making
8355 * it worth doing extra-paranoid checks.
8356 */
8357 if (i == 0)
8358 first = buf_hdr->tag;
8359 else
8360 {
8361 Assert(buf_hdr->tag.relNumber == first.relNumber);
8362 Assert(buf_hdr->tag.blockNum == first.blockNum + i);
8363 }
8364
8365 if (is_temp)
8367 else
8369
8370 /* verify the buffer is in the expected state */
8372 if (is_write)
8373 {
8376 }
8377 else
8378 {
8381 }
8382
8383 /* temp buffers don't use BM_IO_IN_PROGRESS */
8384 if (!is_temp)
8386
8388
8389 /*
8390 * Reflect that the buffer is now owned by the AIO subsystem.
8391 *
8392 * For local buffers: This can't be done just via LocalRefCount, as
8393 * one might initially think, as this backend could error out while
8394 * AIO is still in progress, releasing all the pins by the backend
8395 * itself.
8396 *
8397 * This pin is released again in TerminateBufferIO().
8398 */
8399 buf_hdr->io_wref = io_ref;
8400
8401 if (is_temp)
8402 {
8405 }
8406 else
8408
8409 /*
8410 * Ensure the content lock that prevents buffer modifications while
8411 * the buffer is being written out is not released early due to an
8412 * error.
8413 */
8414 if (is_write && !is_temp)
8415 {
8417
8418 /*
8419 * Lock is now owned by AIO subsystem.
8420 */
8422 }
8423
8424 /*
8425 * Stop tracking this buffer via the resowner - the AIO system now
8426 * keeps track.
8427 */
8428 if (!is_temp)
8430 }
8431}
8432
8433/*
8434 * Decode readv errors as encoded by buffer_readv_encode_error().
8435 */
8436static inline void
8438 bool *zeroed_any,
8439 bool *ignored_any,
8443{
8444 uint32 rem_error = result.error_data;
8445
8446 /* see static asserts in buffer_readv_encode_error */
8447#define READV_COUNT_BITS 7
8448#define READV_COUNT_MASK ((1 << READV_COUNT_BITS) - 1)
8449
8450 *zeroed_any = rem_error & 1;
8451 rem_error >>= 1;
8452
8453 *ignored_any = rem_error & 1;
8454 rem_error >>= 1;
8455
8458
8461
8464}
8465
8466/*
8467 * Helper to encode errors for buffer_readv_complete()
8468 *
8469 * Errors are encoded as follows:
8470 * - bit 0 indicates whether any page was zeroed (1) or not (0)
8471 * - bit 1 indicates whether any checksum failure was ignored (1) or not (0)
8472 * - next READV_COUNT_BITS bits indicate the number of errored or zeroed pages
8473 * - next READV_COUNT_BITS bits indicate the number of checksum failures
8474 * - next READV_COUNT_BITS bits indicate the first offset of the first page
8475 * that was errored or zeroed or, if no errors/zeroes, the first ignored
8476 * checksum
8477 */
8478static inline void
8480 bool is_temp,
8481 bool zeroed_any,
8482 bool ignored_any,
8489{
8490
8491 uint8 shift = 0;
8495
8497 "PG_IOV_MAX is bigger than reserved space for error data");
8499 "PGAIO_RESULT_ERROR_BITS is insufficient for buffer_readv");
8500
8501 /*
8502 * We only have space to encode one offset - but luckily that's good
8503 * enough. If there is an error, the error is the interesting offset, same
8504 * with a zeroed buffer vs an ignored buffer.
8505 */
8506 if (error_count > 0)
8508 else if (zeroed_count > 0)
8510 else
8512
8513 Assert(!zeroed_any || error_count == 0);
8514
8515 result->error_data = 0;
8516
8517 result->error_data |= zeroed_any << shift;
8518 shift += 1;
8519
8520 result->error_data |= ignored_any << shift;
8521 shift += 1;
8522
8523 result->error_data |= ((uint32) zeroed_or_error_count) << shift;
8524 shift += READV_COUNT_BITS;
8525
8526 result->error_data |= ((uint32) checkfail_count) << shift;
8527 shift += READV_COUNT_BITS;
8528
8529 result->error_data |= ((uint32) first_off) << shift;
8530 shift += READV_COUNT_BITS;
8531
8532 result->id = is_temp ? PGAIO_HCB_LOCAL_BUFFER_READV :
8534
8535 if (error_count > 0)
8536 result->status = PGAIO_RS_ERROR;
8537 else
8538 result->status = PGAIO_RS_WARNING;
8539
8540 /*
8541 * The encoding is complicated enough to warrant cross-checking it against
8542 * the decode function.
8543 */
8544#ifdef USE_ASSERT_CHECKING
8545 {
8546 bool zeroed_any_2,
8551
8556 &first_off_2);
8562 }
8563#endif
8564
8565#undef READV_COUNT_BITS
8566#undef READV_COUNT_MASK
8567}
8568
8569/*
8570 * Helper for AIO readv completion callbacks, supporting both shared and temp
8571 * buffers. Gets called once for each buffer in a multi-page read.
8572 */
8573static pg_always_inline void
8575 uint8 flags, bool failed, bool is_temp,
8576 bool *buffer_invalid,
8577 bool *failed_checksum,
8578 bool *ignored_checksum,
8579 bool *zeroed_buffer)
8580{
8581 BufferDesc *buf_hdr = is_temp ?
8584 BufferTag tag = buf_hdr->tag;
8585 char *bufdata = BufferGetBlock(buffer);
8587 int piv_flags;
8588
8589 /* check that the buffer is in the expected state for a read */
8590#ifdef USE_ASSERT_CHECKING
8591 {
8593
8596 /* temp buffers don't use BM_IO_IN_PROGRESS */
8597 if (!is_temp)
8600 }
8601#endif
8602
8603 *buffer_invalid = false;
8604 *failed_checksum = false;
8605 *ignored_checksum = false;
8606 *zeroed_buffer = false;
8607
8608 /*
8609 * We ask PageIsVerified() to only log the message about checksum errors,
8610 * as the completion might be run in any backend (or IO workers). We will
8611 * report checksum errors in buffer_readv_report().
8612 */
8614
8615 /* the local zero_damaged_pages may differ from the definer's */
8618
8619 /*
8620 * If the buffers are marked for zero on error, we want to log that in
8621 * case of a checksum failure.
8622 */
8623 if (flags & READ_BUFFERS_ZERO_ON_ERROR)
8625
8626 /* Check for garbage data. */
8627 if (!failed)
8628 {
8629 /*
8630 * If the buffer is not currently pinned by this backend, e.g. because
8631 * we're completing this IO after an error, the buffer data will have
8632 * been marked as inaccessible when the buffer was unpinned. The AIO
8633 * subsystem holds a pin, but that doesn't prevent the buffer from
8634 * having been marked as inaccessible. The completion might also be
8635 * executed in a different process.
8636 */
8637#ifdef USE_VALGRIND
8638 if (!BufferIsPinned(buffer))
8640#endif
8641
8642 if (!PageIsVerified((Page) bufdata, tag.blockNum, piv_flags,
8644 {
8645 if (flags & READ_BUFFERS_ZERO_ON_ERROR)
8646 {
8647 memset(bufdata, 0, BLCKSZ);
8648 *zeroed_buffer = true;
8649 }
8650 else
8651 {
8652 *buffer_invalid = true;
8653 /* mark buffer as having failed */
8654 failed = true;
8655 }
8656 }
8657 else if (*failed_checksum)
8658 *ignored_checksum = true;
8659
8660 /* undo what we did above */
8661#ifdef USE_VALGRIND
8662 if (!BufferIsPinned(buffer))
8664#endif
8665
8666 /*
8667 * Immediately log a message about the invalid page, but only to the
8668 * server log. The reason to do so immediately is that this may be
8669 * executed in a different backend than the one that originated the
8670 * request. The reason to do so immediately is that the originator
8671 * might not process the query result immediately (because it is busy
8672 * doing another part of query processing) or at all (e.g. if it was
8673 * cancelled or errored out due to another IO also failing). The
8674 * definer of the IO will emit an ERROR or WARNING when processing the
8675 * IO's results
8676 *
8677 * To avoid duplicating the code to emit these log messages, we reuse
8678 * buffer_readv_report().
8679 */
8681 {
8682 PgAioResult result_one = {0};
8683
8688 *zeroed_buffer ? 1 : 0,
8689 *failed_checksum ? 1 : 0,
8692 }
8693 }
8694
8695 /* Terminate I/O and set BM_VALID. */
8696 set_flag_bits = failed ? BM_IO_ERROR : BM_VALID;
8697 if (is_temp)
8699 else
8700 TerminateBufferIO(buf_hdr, false, set_flag_bits, false, true);
8701
8702 /*
8703 * Call the BUFFER_READ_DONE tracepoint in the callback, even though the
8704 * callback may not be executed in the same backend that called
8705 * BUFFER_READ_START. The alternative would be to defer calling the
8706 * tracepoint to a later point (e.g. the local completion callback for
8707 * shared buffer reads), which seems even less helpful.
8708 */
8710 tag.blockNum,
8711 tag.spcOid,
8712 tag.dbOid,
8713 tag.relNumber,
8715 false);
8716}
8717
8718/*
8719 * Perform completion handling of a single AIO read. This read may cover
8720 * multiple blocks / buffers.
8721 *
8722 * Shared between shared and local buffers, to reduce code duplication.
8723 */
8726 uint8 cb_data, bool is_temp)
8727{
8733 uint8 error_count = 0;
8734 uint8 zeroed_count = 0;
8735 uint8 ignored_count = 0;
8737 uint64 *io_data;
8738 uint8 handle_data_len;
8739
8740 if (is_temp)
8741 {
8742 Assert(td->smgr.is_temp);
8744 }
8745 else
8746 Assert(!td->smgr.is_temp);
8747
8748 /*
8749 * Iterate over all the buffers affected by this IO and call the
8750 * per-buffer completion function for each buffer.
8751 */
8752 io_data = pgaio_io_get_handle_data(ioh, &handle_data_len);
8753 for (uint8 buf_off = 0; buf_off < handle_data_len; buf_off++)
8754 {
8756 bool failed;
8757 bool failed_verification = false;
8758 bool failed_checksum = false;
8759 bool zeroed_buffer = false;
8760 bool ignored_checksum = false;
8761
8763
8764 /*
8765 * If the entire I/O failed on a lower-level, each buffer needs to be
8766 * marked as failed. In case of a partial read, the first few buffers
8767 * may be ok.
8768 */
8769 failed =
8771 || prior_result.result <= buf_off;
8772
8773 buffer_readv_complete_one(td, buf_off, buf, cb_data, failed, is_temp,
8777 &zeroed_buffer);
8778
8779 /*
8780 * Track information about the number of different kinds of error
8781 * conditions across all pages, as there can be multiple pages failing
8782 * verification as part of one IO.
8783 */
8786 if (zeroed_buffer && zeroed_count++ == 0)
8788 if (ignored_checksum && ignored_count++ == 0)
8790 if (failed_checksum)
8792 }
8793
8794 /*
8795 * If the smgr read succeeded [partially] and page verification failed for
8796 * some of the pages, adjust the IO's result state appropriately.
8797 */
8798 if (prior_result.status != PGAIO_RS_ERROR &&
8799 (error_count > 0 || ignored_count > 0 || zeroed_count > 0))
8800 {
8802 zeroed_count > 0, ignored_count > 0,
8807 }
8808
8809 /*
8810 * For shared relations this reporting is done in
8811 * shared_buffer_readv_complete_local().
8812 */
8813 if (is_temp && checkfail_count > 0)
8816
8817 return result;
8818}
8819
8820/*
8821 * AIO error reporting callback for aio_shared_buffer_readv_cb and
8822 * aio_local_buffer_readv_cb.
8823 *
8824 * The error is encoded / decoded in buffer_readv_encode_error() /
8825 * buffer_readv_decode_error().
8826 */
8827static void
8829 int elevel)
8830{
8831 int nblocks = td->smgr.nblocks;
8832 BlockNumber first = td->smgr.blockNum;
8833 BlockNumber last = first + nblocks - 1;
8836 RelPathStr rpath =
8838 bool zeroed_any,
8842 first_off;
8844 const char *msg_one,
8845 *msg_mult,
8846 *det_mult,
8847 *hint_mult;
8848
8852 &first_off);
8853
8854 /*
8855 * Treat a read that had both zeroed buffers *and* ignored checksums as a
8856 * special case, it's too irregular to be emitted the same way as the
8857 * other cases.
8858 */
8859 if (zeroed_any && ignored_any)
8860 {
8862 Assert(nblocks > 1); /* same block can't be both zeroed and ignored */
8863 Assert(result.status != PGAIO_RS_ERROR);
8865
8866 ereport(elevel,
8868 errmsg("zeroing %u page(s) and ignoring %u checksum failure(s) among blocks %u..%u of relation \"%s\"",
8869 affected_count, checkfail_count, first, last, rpath.str),
8870 affected_count > 1 ?
8871 errdetail("Block %u held the first zeroed page.",
8872 first + first_off) : 0,
8873 errhint_plural("See server log for details about the other %d invalid block.",
8874 "See server log for details about the other %d invalid blocks.",
8877 return;
8878 }
8879
8880 /*
8881 * The other messages are highly repetitive. To avoid duplicating a long
8882 * and complicated ereport(), gather the translated format strings
8883 * separately and then do one common ereport.
8884 */
8885 if (result.status == PGAIO_RS_ERROR)
8886 {
8887 Assert(!zeroed_any); /* can't have invalid pages when zeroing them */
8889 msg_one = _("invalid page in block %u of relation \"%s\"");
8890 msg_mult = _("%u invalid pages among blocks %u..%u of relation \"%s\"");
8891 det_mult = _("Block %u held the first invalid page.");
8892 hint_mult = _("See server log for the other %u invalid block(s).");
8893 }
8894 else if (zeroed_any && !ignored_any)
8895 {
8897 msg_one = _("invalid page in block %u of relation \"%s\"; zeroing out page");
8898 msg_mult = _("zeroing out %u invalid pages among blocks %u..%u of relation \"%s\"");
8899 det_mult = _("Block %u held the first zeroed page.");
8900 hint_mult = _("See server log for the other %u zeroed block(s).");
8901 }
8902 else if (!zeroed_any && ignored_any)
8903 {
8905 msg_one = _("ignoring checksum failure in block %u of relation \"%s\"");
8906 msg_mult = _("ignoring %u checksum failures among blocks %u..%u of relation \"%s\"");
8907 det_mult = _("Block %u held the first ignored page.");
8908 hint_mult = _("See server log for the other %u ignored block(s).");
8909 }
8910 else
8912
8913 ereport(elevel,
8915 affected_count == 1 ?
8916 errmsg_internal(msg_one, first + first_off, rpath.str) :
8917 errmsg_internal(msg_mult, affected_count, first, last, rpath.str),
8920}
8921
8922static void
8927
8928static PgAioResult
8934
8935/*
8936 * We need a backend-local completion callback for shared buffers, to be able
8937 * to report checksum errors correctly. Unfortunately that can only safely
8938 * happen if the reporting backend has previously called
8939 * pgstat_prepare_report_checksum_failure(), which we can only guarantee in
8940 * the backend that started the IO. Hence this callback.
8941 */
8942static PgAioResult
8972
8973static void
8978
8979static PgAioResult
8985
8986/* readv callback is passed READ_BUFFERS_* flags as callback data */
8989 .complete_shared = shared_buffer_readv_complete,
8990 /* need a local callback to report checksum failures */
8991 .complete_local = shared_buffer_readv_complete_local,
8992 .report = buffer_readv_report,
8993};
8994
8995/* readv callback is passed READ_BUFFERS_* flags as callback data */
8998
8999 /*
9000 * Note that this, in contrast to the shared_buffers case, uses
9001 * complete_local, as only the issuing backend has access to the required
9002 * datastructures. This is important in case the IO completion may be
9003 * consumed incidentally by another backend.
9004 */
9005 .complete_local = local_buffer_readv_complete,
9006 .report = buffer_readv_report,
9007};
int io_method
Definition aio.c:74
bool pgaio_wref_valid(PgAioWaitRef *iow)
Definition aio.c:971
PgAioHandle * pgaio_io_acquire(struct ResourceOwnerData *resowner, PgAioReturn *ret)
Definition aio.c:162
void pgaio_wref_clear(PgAioWaitRef *iow)
Definition aio.c:964
void pgaio_io_get_wref(PgAioHandle *ioh, PgAioWaitRef *iow)
Definition aio.c:366
void pgaio_io_set_flag(PgAioHandle *ioh, PgAioHandleFlags flag)
Definition aio.c:330
bool pgaio_have_staged(void)
Definition aio.c:1117
bool pgaio_wref_check_done(PgAioWaitRef *iow)
Definition aio.c:1005
ProcNumber pgaio_io_get_owner(PgAioHandle *ioh)
Definition aio.c:355
void pgaio_submit_staged(void)
Definition aio.c:1133
void pgaio_wref_wait(PgAioWaitRef *iow)
Definition aio.c:991
void pgaio_io_release(PgAioHandle *ioh)
Definition aio.c:240
PgAioHandle * pgaio_io_acquire_nb(struct ResourceOwnerData *resowner, PgAioReturn *ret)
Definition aio.c:188
@ PGAIO_HCB_LOCAL_BUFFER_READV
Definition aio.h:200
@ PGAIO_HCB_SHARED_BUFFER_READV
Definition aio.h:198
@ IOMETHOD_SYNC
Definition aio.h:34
@ PGAIO_HF_SYNCHRONOUS
Definition aio.h:70
@ PGAIO_HF_REFERENCES_LOCAL
Definition aio.h:60
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)
Definition aio_target.c:73
#define PGAIO_RESULT_ERROR_BITS
Definition aio_types.h:98
PgAioResultStatus
Definition aio_types.h:79
@ PGAIO_RS_OK
Definition aio_types.h:81
@ PGAIO_RS_UNKNOWN
Definition aio_types.h:80
@ PGAIO_RS_PARTIAL
Definition aio_types.h:82
@ PGAIO_RS_ERROR
Definition aio_types.h:84
@ PGAIO_RS_WARNING
Definition aio_types.h:83
static bool pg_atomic_compare_exchange_u64(volatile pg_atomic_uint64 *ptr, uint64 *expected, uint64 newval)
Definition atomics.h:517
#define pg_write_barrier()
Definition atomics.h:155
static void pg_atomic_unlocked_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition atomics.h:489
static uint64 pg_atomic_sub_fetch_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
Definition atomics.h:573
static uint64 pg_atomic_fetch_and_u64(volatile pg_atomic_uint64 *ptr, uint64 and_)
Definition atomics.h:546
static uint64 pg_atomic_fetch_or_u64(volatile pg_atomic_uint64 *ptr, uint64 or_)
Definition atomics.h:555
static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)
Definition atomics.h:462
static uint64 pg_atomic_fetch_sub_u64(volatile pg_atomic_uint64 *ptr, int64 sub_)
Definition atomics.h:536
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition timestamp.c:1789
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1649
Datum now(PG_FUNCTION_ARGS)
Definition timestamp.c:1613
int BgWriterDelay
Definition bgwriter.c:59
void binaryheap_build(binaryheap *heap)
Definition binaryheap.c:136
void binaryheap_replace_first(binaryheap *heap, bh_node_type d)
Definition binaryheap.c:253
bh_node_type binaryheap_first(binaryheap *heap)
Definition binaryheap.c:175
bh_node_type binaryheap_remove_first(binaryheap *heap)
Definition binaryheap.c:190
void binaryheap_free(binaryheap *heap)
Definition binaryheap.c:73
void binaryheap_add_unordered(binaryheap *heap, bh_node_type d)
Definition binaryheap.c:114
binaryheap * binaryheap_allocate(int capacity, binaryheap_comparator compare, void *arg)
Definition binaryheap.c:37
#define binaryheap_empty(h)
Definition binaryheap.h:65
uint32 BlockNumber
Definition block.h:31
#define InvalidBlockNumber
Definition block.h:33
static bool BlockNumberIsValid(BlockNumber blockNumber)
Definition block.h:71
#define MaxBlockNumber
Definition block.h:35
static int32 next
Definition blutils.c:225
int Buffer
Definition buf.h:23
#define InvalidBuffer
Definition buf.h:25
#define BufferIsLocal(buffer)
Definition buf.h:37
CkptSortItem * CkptBufferIds
Definition buf_init.c:28
WritebackContext BackendWritebackContext
Definition buf_init.c:27
#define BM_MAX_USAGE_COUNT
static void InitBufferTag(BufferTag *tag, const RelFileLocator *rlocator, ForkNumber forkNum, BlockNumber blockNum)
#define BM_TAG_VALID
#define BM_PERMANENT
#define BUF_USAGECOUNT_MASK
static ForkNumber BufTagGetForkNum(const BufferTag *tag)
#define BM_LOCK_VAL_SHARED
#define BUF_REFCOUNT_ONE
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)
static BufferDesc * GetLocalBufferDescriptor(int id)
#define BUF_FLAG_MASK
#define BM_PIN_COUNT_WAITER
#define BM_DIRTY
#define BM_LOCK_WAKE_IN_PROGRESS
static void ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer)
#define BM_LOCKED
#define BUF_STATE_GET_USAGECOUNT(state)
#define BM_LOCK_MASK
StartBufferIOResult
@ BUFFER_IO_IN_PROGRESS
@ BUFFER_IO_ALREADY_DONE
@ BUFFER_IO_READY_FOR_IO
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_VALID
#define BM_LOCK_HAS_WAITERS
#define BM_IO_ERROR
#define BM_LOCK_VAL_SHARE_EXCLUSIVE
static Buffer BufferDescriptorGetBuffer(const BufferDesc *bdesc)
static BufferDesc * GetBufferDescriptor(int id)
#define BM_CHECKPOINT_NEEDED
void BufTableDelete(BufferTag *tagPtr, uint32 hashcode)
Definition buf_table.c:154
int BufTableLookup(BufferTag *tagPtr, uint32 hashcode)
Definition buf_table.c:96
uint32 BufTableHashCode(BufferTag *tagPtr)
Definition buf_table.c:84
int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id)
Definition buf_table.c:124
bool track_io_timing
Definition bufmgr.c:192
static void ResOwnerReleaseBuffer(Datum res)
Definition bufmgr.c:7894
void CheckBufferIsPinnedOnce(Buffer buffer)
Definition bufmgr.c:6660
void FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels)
Definition bufmgr.c:5273
void IncrBufferRefCount(Buffer buffer)
Definition bufmgr.c:5693
static void MarkSharedBufferDirtyHint(Buffer buffer, BufferDesc *bufHdr, uint64 lockstate, bool buffer_std)
Definition bufmgr.c:5719
void DropDatabaseBuffers(Oid dbid)
Definition bufmgr.c:5138
bool BufferSetHintBits16(uint16 *ptr, uint16 val, Buffer buffer)
Definition bufmgr.c:7142
static int ckpt_buforder_comparator(const CkptSortItem *a, const CkptSortItem *b)
Definition bufmgr.c:7673
BlockNumber BufferGetBlockNumber(Buffer buffer)
Definition bufmgr.c:4469
static PrivateRefCountEntry * NewPrivateRefCountEntry(Buffer buffer)
Definition bufmgr.c:388
static Buffer PrivateRefCountArrayKeys[REFCOUNT_ARRAY_ENTRIES]
Definition bufmgr.c:263
void BufferFinishSetHintBits(Buffer buffer, bool mark_dirty, bool buffer_std)
Definition bufmgr.c:7119
void DropRelationBuffers(SMgrRelation smgr_reln, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock)
Definition bufmgr.c:4788
Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, BlockNumber blockNum)
Definition bufmgr.c:3235
static int ReservedRefCountSlot
Definition bufmgr.c:268
static PgAioResult shared_buffer_readv_complete_local(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data)
Definition bufmgr.c:8943
static void CheckReadBuffersOperation(ReadBuffersOperation *operation, bool is_complete)
Definition bufmgr.c:1656
PrefetchBufferResult PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
Definition bufmgr.c:787
static uint32 PrivateRefCountClock
Definition bufmgr.c:267
static void FlushBuffer(BufferDesc *buf, SMgrRelation reln, IOObject io_object, IOContext io_context)
Definition bufmgr.c:4526
static void ResOwnerReleaseBufferIO(Datum res)
Definition bufmgr.c:7872
static PgAioResult local_buffer_readv_complete(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data)
Definition bufmgr.c:8980
bool StartReadBuffers(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, int *nblocks, int flags)
Definition bufmgr.c:1618
void EvictAllUnpinnedBuffers(int32 *buffers_evicted, int32 *buffers_flushed, int32 *buffers_skipped)
Definition bufmgr.c:8031
int io_max_combine_limit
Definition bufmgr.c:217
static void FlushUnlockedBuffer(BufferDesc *buf, SMgrRelation reln, IOObject io_object, IOContext io_context)
Definition bufmgr.c:4649
const ResourceOwnerDesc buffer_io_resowner_desc
Definition bufmgr.c:285
bool zero_damaged_pages
Definition bufmgr.c:189
#define BUF_DROP_FULL_SCAN_THRESHOLD
Definition bufmgr.c:95
static void PinBuffer_Locked(BufferDesc *buf)
Definition bufmgr.c:3411
void EvictRelUnpinnedBuffers(Relation rel, int32 *buffers_evicted, int32 *buffers_flushed, int32 *buffers_skipped)
Definition bufmgr.c:8081
static char * ResOwnerPrintBuffer(Datum res)
Definition bufmgr.c:7930
static void BufferLockAcquire(Buffer buffer, BufferDesc *buf_hdr, BufferLockMode mode)
Definition bufmgr.c:5921
static bool BufferLockAttempt(BufferDesc *buf_hdr, BufferLockMode mode)
Definition bufmgr.c:6119
static int buffertag_comparator(const BufferTag *ba, const BufferTag *bb)
Definition bufmgr.c:7639
bool IsBufferCleanupOK(Buffer buffer)
Definition bufmgr.c:6950
#define BufferGetLSN(bufHdr)
Definition bufmgr.c:77
static char * ResOwnerPrintBufferIO(Datum res)
Definition bufmgr.c:7880
bool BufferIsLockedByMeInMode(Buffer buffer, BufferLockMode mode)
Definition bufmgr.c:3110
static void BufferLockDisown(Buffer buffer, BufferDesc *buf_hdr)
Definition bufmgr.c:6294
Buffer ExtendBufferedRel(BufferManagerRelation bmr, ForkNumber forkNum, BufferAccessStrategy strategy, uint32 flags)
Definition bufmgr.c:970
void AtEOXact_Buffers(bool isCommit)
Definition bufmgr.c:4222
static void AbortBufferIO(Buffer buffer)
Definition bufmgr.c:7469
const PgAioHandleCallbacks aio_shared_buffer_readv_cb
Definition bufmgr.c:8987
static void BufferLockUnlock(Buffer buffer, BufferDesc *buf_hdr)
Definition bufmgr.c:6037
BlockNumber ExtendBufferedRelBy(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, Buffer *buffers, uint32 *extended_by)
Definition bufmgr.c:1002
static void ProcessReadBuffersResult(ReadBuffersOperation *operation)
Definition bufmgr.c:1714
pg_noinline uint64 WaitBufHdrUnlocked(BufferDesc *buf)
Definition bufmgr.c:7615
static void ZeroAndLockBuffer(Buffer buffer, ReadBufferMode mode, bool already_valid)
Definition bufmgr.c:1137
static void CheckForBufferLeaks(void)
Definition bufmgr.c:4286
void CreateAndCopyRelationData(RelFileLocator src_rlocator, RelFileLocator dst_rlocator, bool permanent)
Definition bufmgr.c:5485
void DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators)
Definition bufmgr.c:4908
static void BufferLockDequeueSelf(BufferDesc *buf_hdr)
Definition bufmgr.c:6226
static int rlocator_comparator(const void *p1, const void *p2)
Definition bufmgr.c:7540
static bool BufferLockHeldByMeInMode(BufferDesc *buf_hdr, BufferLockMode mode)
Definition bufmgr.c:6548
Buffer ExtendBufferedRelTo(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, BlockNumber extend_to, ReadBufferMode mode)
Definition bufmgr.c:1031
static pg_always_inline Buffer PinBufferForBlock(Relation rel, SMgrRelation smgr, char persistence, ForkNumber forkNum, BlockNumber blockNum, BufferAccessStrategy strategy, IOObject io_object, IOContext io_context, bool *foundPtr)
Definition bufmgr.c:1223
const PgAioHandleCallbacks aio_local_buffer_readv_cb
Definition bufmgr.c:8996
static bool InvalidateVictimBuffer(BufferDesc *buf_hdr)
Definition bufmgr.c:2471
static void AtProcExit_Buffers(int code, Datum arg)
Definition bufmgr.c:4268
int io_combine_limit_guc
Definition bufmgr.c:216
static int ts_ckpt_progress_comparator(Datum a, Datum b, void *arg)
Definition bufmgr.c:7704
void BufferGetTag(Buffer buffer, RelFileLocator *rlocator, ForkNumber *forknum, BlockNumber *blknum)
Definition bufmgr.c:4490
#define BufHdrGetBlock(bufHdr)
Definition bufmgr.c:76
static bool BufferLockConditional(Buffer buffer, BufferDesc *buf_hdr, BufferLockMode mode)
Definition bufmgr.c:6073
const ResourceOwnerDesc buffer_resowner_desc
Definition bufmgr.c:294
static refcount_hash * PrivateRefCountHash
Definition bufmgr.c:265
void UnlockBuffer(Buffer buffer)
Definition bufmgr.c:6581
#define BUF_REUSABLE
Definition bufmgr.c:85
static pg_always_inline PgAioResult buffer_readv_complete(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data, bool is_temp)
Definition bufmgr.c:8725
static void local_buffer_write_error_callback(void *arg)
Definition bufmgr.c:7524
static void BufferSync(int flags)
Definition bufmgr.c:3575
static bool AsyncReadBuffers(ReadBuffersOperation *operation, int *nblocks_progress)
Definition bufmgr.c:1938
static void local_buffer_readv_stage(PgAioHandle *ioh, uint8 cb_data)
Definition bufmgr.c:8974
char * DebugPrintBufferRefcount(Buffer buffer)
Definition bufmgr.c:4412
void CheckPointBuffers(int flags)
Definition bufmgr.c:4455
bool BufferIsDirty(Buffer buffer)
Definition bufmgr.c:3137
static uint32 MaxProportionalPins
Definition bufmgr.c:271
static void BufferLockQueueSelf(BufferDesc *buf_hdr, BufferLockMode mode)
Definition bufmgr.c:6186
static BlockNumber ExtendBufferedRelShared(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
Definition bufmgr.c:2809
static int BufferLockDisownInternal(Buffer buffer, BufferDesc *buf_hdr)
Definition bufmgr.c:6308
bool BgBufferSync(WritebackContext *wb_context)
Definition bufmgr.c:3854
uint64 LockBufHdr(BufferDesc *desc)
Definition bufmgr.c:7567
static void WakePinCountWaiter(BufferDesc *buf)
Definition bufmgr.c:3443
bool BufferIsPermanent(Buffer buffer)
Definition bufmgr.c:4700
void MarkDirtyAllUnpinnedBuffers(int32 *buffers_dirtied, int32 *buffers_already_dirty, int32 *buffers_skipped)
Definition bufmgr.c:8281
#define REFCOUNT_ARRAY_ENTRIES
Definition bufmgr.c:145
static pg_always_inline void TrackBufferHit(IOObject io_object, IOContext io_context, Relation rel, char persistence, SMgrRelation smgr, ForkNumber forknum, BlockNumber blocknum)
Definition bufmgr.c:1683
static void shared_buffer_readv_stage(PgAioHandle *ioh, uint8 cb_data)
Definition bufmgr.c:8923
static void BufferLockProcessRelease(BufferDesc *buf_hdr, BufferLockMode mode, uint64 lockstate)
Definition bufmgr.c:6493
void UnlockBuffers(void)
Definition bufmgr.c:5875
PrefetchBufferResult PrefetchSharedBuffer(SMgrRelation smgr_reln, ForkNumber forkNum, BlockNumber blockNum)
Definition bufmgr.c:697
static PgAioResult shared_buffer_readv_complete(PgAioHandle *ioh, PgAioResult prior_result, uint8 cb_data)
Definition bufmgr.c:8929
static Buffer GetVictimBuffer(BufferAccessStrategy strategy, IOContext io_context)
Definition bufmgr.c:2548
bool ConditionalLockBuffer(Buffer buffer)
Definition bufmgr.c:6640
static BufferDesc * BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, BlockNumber blockNum, BufferAccessStrategy strategy, bool *foundPtr, IOContext io_context)
Definition bufmgr.c:2197
BlockNumber RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
Definition bufmgr.c:4668
StartBufferIOResult StartSharedBufferIO(BufferDesc *buf, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition bufmgr.c:7290
int bgwriter_flush_after
Definition bufmgr.c:224
void ReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5609
static pg_always_inline void buffer_stage_common(PgAioHandle *ioh, bool is_write, bool is_temp)
Definition bufmgr.c:8330
bool BufferIsLockedByMe(Buffer buffer)
Definition bufmgr.c:3084
static bool PinBuffer(BufferDesc *buf, BufferAccessStrategy strategy, bool skip_if_not_valid)
Definition bufmgr.c:3295
static void FindAndDropRelationBuffers(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber nForkBlock, BlockNumber firstDelBlock)
Definition bufmgr.c:5078
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
Definition bufmgr.c:4736
void LockBufferInternal(Buffer buffer, BufferLockMode mode)
Definition bufmgr.c:6597
bool HoldingBufferPinThatDelaysRecovery(void)
Definition bufmgr.c:6866
bool MarkDirtyUnpinnedBuffer(Buffer buf, bool *buffer_already_dirty)
Definition bufmgr.c:8188
int checkpoint_flush_after
Definition bufmgr.c:223
void UnlockReleaseBuffer(Buffer buffer)
Definition bufmgr.c:5626
static void UnpinBufferNoOwner(BufferDesc *buf)
Definition bufmgr.c:3488
static void shared_buffer_write_error_callback(void *arg)
Definition bufmgr.c:7508
void ScheduleBufferTagForWriteback(WritebackContext *wb_context, IOContext io_context, BufferTag *tag)
Definition bufmgr.c:7739
void WritebackContextInit(WritebackContext *context, int *max_pending)
Definition bufmgr.c:7727
StartBufferIOResult StartBufferIO(Buffer buffer, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition bufmgr.c:7370
void MarkBufferDirty(Buffer buffer)
Definition bufmgr.c:3170
#define BufferIsPinned(bufnum)
Definition bufmgr.c:599
double bgwriter_lru_multiplier
Definition bufmgr.c:191
static bool EvictUnpinnedBufferInternal(BufferDesc *desc, bool *buffer_flushed)
Definition bufmgr.c:7940
bool BufferBeginSetHintBits(Buffer buffer)
Definition bufmgr.c:7091
int backend_flush_after
Definition bufmgr.c:225
void LimitAdditionalPins(uint32 *additional_pins)
Definition bufmgr.c:2733
static void buffer_readv_report(PgAioResult result, const PgAioTargetData *td, int elevel)
Definition bufmgr.c:8828
static void ReservePrivateRefCountEntry(void)
Definition bufmgr.c:309
static BufferDesc * PinCountWaitBuf
Definition bufmgr.c:228
static void BufferLockWakeup(BufferDesc *buf_hdr, bool wake_exclusive)
Definition bufmgr.c:6328
static pg_noinline PrivateRefCountEntry * GetPrivateRefCountEntrySlow(Buffer buffer, bool do_move)
Definition bufmgr.c:419
static int32 GetPrivateRefCount(Buffer buffer)
Definition bufmgr.c:542
bool WaitReadBuffers(ReadBuffersOperation *operation)
Definition bufmgr.c:1759
static BlockNumber ExtendBufferedRelCommon(BufferManagerRelation bmr, ForkNumber fork, BufferAccessStrategy strategy, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
Definition bufmgr.c:2751
void LockBufferForCleanup(Buffer buffer)
Definition bufmgr.c:6693
static bool SharedBufferBeginSetHintBits(Buffer buffer, BufferDesc *buf_hdr, uint64 *lockstate)
Definition bufmgr.c:7000
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
Definition bufmgr.c:5844
void FlushRelationBuffers(Relation rel)
Definition bufmgr.c:5185
#define READV_COUNT_BITS
static uint64 BufferLockReleaseSub(BufferLockMode mode)
Definition bufmgr.c:6464
void IssuePendingWritebacks(WritebackContext *wb_context, IOContext io_context)
Definition bufmgr.c:7789
static void ForgetPrivateRefCountEntry(PrivateRefCountEntry *ref)
Definition bufmgr.c:565
bool EvictUnpinnedBuffer(Buffer buf, bool *buffer_flushed)
Definition bufmgr.c:8002
Buffer ReadBufferWithoutRelcache(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy, bool permanent)
Definition bufmgr.c:954
bool ReadRecentBuffer(RelFileLocator rlocator, ForkNumber forkNum, BlockNumber blockNum, Buffer recent_buffer)
Definition bufmgr.c:818
#define RELS_BSEARCH_THRESHOLD
Definition bufmgr.c:87
int maintenance_io_concurrency
Definition bufmgr.c:207
static void UnpinBuffer(BufferDesc *buf)
Definition bufmgr.c:3479
void FlushDatabaseBuffers(Oid dbid)
Definition bufmgr.c:5549
static void InvalidateBuffer(BufferDesc *buf)
Definition bufmgr.c:2370
static void RelationCopyStorageUsingBuffer(RelFileLocator srclocator, RelFileLocator dstlocator, ForkNumber forkNum, bool permanent)
Definition bufmgr.c:5371
int effective_io_concurrency
Definition bufmgr.c:200
static PrivateRefCountEntry * GetPrivateRefCountEntry(Buffer buffer, bool do_move)
Definition bufmgr.c:507
static bool BufferLockHeldByMe(BufferDesc *buf_hdr)
Definition bufmgr.c:6566
void TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint64 set_flag_bits, bool forget_owner, bool release_aio)
Definition bufmgr.c:7407
void MarkDirtyRelUnpinnedBuffers(Relation rel, int32 *buffers_dirtied, int32 *buffers_already_dirty, int32 *buffers_skipped)
Definition bufmgr.c:8224
bool StartReadBuffer(ReadBuffersOperation *operation, Buffer *buffer, BlockNumber blocknum, int flags)
Definition bufmgr.c:1637
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition bufmgr.c:926
static bool MarkDirtyUnpinnedBufferInternal(Buffer buf, BufferDesc *desc, bool *buffer_already_dirty)
Definition bufmgr.c:8132
static struct PrivateRefCountEntry PrivateRefCountArray[REFCOUNT_ARRAY_ENTRIES]
Definition bufmgr.c:264
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)
Definition bufmgr.c:8437
#define READV_COUNT_MASK
static int PrivateRefCountEntryLast
Definition bufmgr.c:269
int io_combine_limit
Definition bufmgr.c:215
void InitBufferManagerAccess(void)
Definition bufmgr.c:4239
static Buffer ReadBuffer_common(Relation rel, SMgrRelation smgr, char smgr_persistence, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition bufmgr.c:1276
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)
Definition bufmgr.c:8479
static int SyncOneBuffer(int buf_id, bool skip_recently_used, WritebackContext *wb_context)
Definition bufmgr.c:4152
uint32 GetAdditionalPinLimit(void)
Definition bufmgr.c:2707
static pg_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)
Definition bufmgr.c:8574
Buffer ReadBuffer(Relation reln, BlockNumber blockNum)
Definition bufmgr.c:879
void TrackNewBufferPin(Buffer buf)
Definition bufmgr.c:3535
static pg_always_inline bool StartReadBuffersImpl(ReadBuffersOperation *operation, Buffer *buffers, BlockNumber blockNum, int *nblocks, int flags, bool allow_forwarding)
Definition bufmgr.c:1371
static int32 PrivateRefCountOverflowed
Definition bufmgr.c:266
bool ConditionalLockBufferForCleanup(Buffer buffer)
Definition bufmgr.c:6892
int bgwriter_lru_maxpages
Definition bufmgr.c:190
uint32 GetPinLimit(void)
Definition bufmgr.c:2695
static void WaitIO(BufferDesc *buf)
Definition bufmgr.c:7188
#define BUF_WRITTEN
Definition bufmgr.c:84
void FlushOneBuffer(Buffer buffer)
Definition bufmgr.c:5589
@ BAS_BULKREAD
Definition bufmgr.h:37
@ BAS_BULKWRITE
Definition bufmgr.h:39
#define P_NEW
Definition bufmgr.h:200
#define READ_BUFFERS_ZERO_ON_ERROR
Definition bufmgr.h:122
static Page BufferGetPage(Buffer buffer)
Definition bufmgr.h:468
#define DEFAULT_IO_COMBINE_LIMIT
Definition bufmgr.h:176
static Block BufferGetBlock(Buffer buffer)
Definition bufmgr.h:435
#define READ_BUFFERS_ISSUE_ADVICE
Definition bufmgr.h:124
BufferLockMode
Definition bufmgr.h:206
@ BUFFER_LOCK_SHARE_EXCLUSIVE
Definition bufmgr.h:217
@ BUFFER_LOCK_SHARE
Definition bufmgr.h:212
@ BUFFER_LOCK_EXCLUSIVE
Definition bufmgr.h:222
@ BUFFER_LOCK_UNLOCK
Definition bufmgr.h:207
#define MAX_IO_COMBINE_LIMIT
Definition bufmgr.h:175
#define DEFAULT_EFFECTIVE_IO_CONCURRENCY
Definition bufmgr.h:170
#define READ_BUFFERS_IGNORE_CHECKSUM_FAILURES
Definition bufmgr.h:126
#define DEFAULT_MAINTENANCE_IO_CONCURRENCY
Definition bufmgr.h:171
void * Block
Definition bufmgr.h:26
static void LockBuffer(Buffer buffer, BufferLockMode mode)
Definition bufmgr.h:334
#define BMR_GET_SMGR(bmr)
Definition bufmgr.h:118
@ EB_LOCK_TARGET
Definition bufmgr.h:93
@ EB_CLEAR_SIZE_CACHE
Definition bufmgr.h:90
@ EB_PERFORMING_RECOVERY
Definition bufmgr.h:78
@ EB_CREATE_FORK_IF_NEEDED
Definition bufmgr.h:84
@ EB_SKIP_EXTENSION_LOCK
Definition bufmgr.h:75
@ EB_LOCK_FIRST
Definition bufmgr.h:87
#define READ_BUFFERS_SYNCHRONOUSLY
Definition bufmgr.h:128
ReadBufferMode
Definition bufmgr.h:45
@ RBM_ZERO_ON_ERROR
Definition bufmgr.h:51
@ RBM_ZERO_AND_CLEANUP_LOCK
Definition bufmgr.h:49
@ RBM_ZERO_AND_LOCK
Definition bufmgr.h:47
@ RBM_NORMAL
Definition bufmgr.h:46
#define BMR_REL(p_rel)
Definition bufmgr.h:114
static bool BufferIsValid(Buffer bufnum)
Definition bufmgr.h:419
bool ignore_checksum_failure
Definition bufpage.c:27
void PageSetChecksum(Page page, BlockNumber blkno)
Definition bufpage.c:1518
bool PageIsVerified(PageData *page, BlockNumber blkno, int flags, bool *checksum_failure_p)
Definition bufpage.c:94
#define PIV_LOG_LOG
Definition bufpage.h:500
#define PIV_ZERO_BUFFERS_ON_ERROR
Definition bufpage.h:502
static bool PageIsNew(const PageData *page)
Definition bufpage.h:258
static void PageSetLSN(Page page, XLogRecPtr lsn)
Definition bufpage.h:416
PageData * Page
Definition bufpage.h:81
static XLogRecPtr PageGetLSN(const PageData *page)
Definition bufpage.h:410
#define PIV_IGNORE_CHECKSUM_FAILURE
Definition bufpage.h:501
#define pg_always_inline
Definition c.h:364
#define pg_noinline
Definition c.h:380
#define likely(x)
Definition c.h:496
uint8_t uint8
Definition c.h:681
#define PG_USED_FOR_ASSERTS_ONLY
Definition c.h:308
#define Max(x, y)
Definition c.h:1125
#define Assert(condition)
Definition c.h:1002
double float8
Definition c.h:773
int16_t int16
Definition c.h:678
int32_t int32
Definition c.h:679
uint64_t uint64
Definition c.h:684
uint16_t uint16
Definition c.h:682
#define pg_unreachable()
Definition c.h:426
#define unlikely(x)
Definition c.h:497
uint32_t uint32
Definition c.h:683
#define lengthof(array)
Definition c.h:932
#define MemSet(start, val, len)
Definition c.h:1147
#define StaticAssertDecl(condition, errmessage)
Definition c.h:1067
size_t Size
Definition c.h:748
bool IsCatalogRelationOid(Oid relid)
Definition catalog.c:123
bool IsCatalogTextUniqueIndexOid(Oid relid)
Definition catalog.c:158
void CheckpointWriteDelay(int flags, double progress)
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
bool ConditionVariableCancelSleep(void)
void ConditionVariableBroadcast(ConditionVariable *cv)
void ConditionVariablePrepareToSleep(ConditionVariable *cv)
void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
static DataChecksumsWorkerOperation operation
int64 TimestampTz
Definition timestamp.h:39
struct cursor * cur
Definition ecpg.c:29
Datum arg
Definition elog.c:1323
ErrorContextCallback * error_context_stack
Definition elog.c:100
int errcode(int sqlerrcode)
Definition elog.c:875
#define _(x)
Definition elog.c:96
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
#define errcontext
Definition elog.h:200
int int int errhint_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...) pg_attribute_printf(1
#define DEBUG3
Definition elog.h:29
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define LOG_SERVER_ONLY
Definition elog.h:33
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define WARNING
Definition elog.h:37
#define DEBUG2
Definition elog.h:30
#define PANIC
Definition elog.h:44
#define DEBUG1
Definition elog.h:31
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
int int errhint_internal(const char *fmt,...) pg_attribute_printf(1
int io_direct_flags
Definition fd.c:172
#define IO_DIRECT_DATA
Definition fd.h:54
#define palloc_array(type, count)
Definition fe_memutils.h:91
int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc)
Definition freelist.c:331
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
Definition freelist.c:426
BufferDesc * StrategyGetBuffer(BufferAccessStrategy strategy, uint64 *buf_state, bool *from_ring)
Definition freelist.c:184
void FreeAccessStrategy(BufferAccessStrategy strategy)
Definition freelist.c:608
IOContext IOContextForStrategy(BufferAccessStrategy strategy)
Definition freelist.c:712
bool StrategyRejectBuffer(BufferAccessStrategy strategy, BufferDesc *buf, bool from_ring)
Definition freelist.c:752
volatile sig_atomic_t ProcSignalBarrierPending
Definition globals.c:40
int NBuffers
Definition globals.c:144
bool enableFsync
Definition globals.c:131
ProcNumber MyProcNumber
Definition globals.c:92
int VacuumCostPageMiss
Definition globals.c:155
bool VacuumCostActive
Definition globals.c:161
bool IsUnderPostmaster
Definition globals.c:122
int VacuumCostBalance
Definition globals.c:160
int MaxBackends
Definition globals.c:149
int VacuumCostPageDirty
Definition globals.c:156
int VacuumCostPageHit
Definition globals.c:154
const char * str
long val
Definition informix.c:689
BufferUsage pgBufferUsage
Definition instrument.c:25
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:372
int b
Definition isn.c:74
int a
Definition isn.c:73
int j
Definition isn.c:78
int i
Definition isn.c:77
void LockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition lmgr.c:424
void UnlockRelationForExtension(Relation relation, LOCKMODE lockmode)
Definition lmgr.c:474
int32 * LocalRefCount
Definition localbuf.c:49
void FlushLocalBuffer(BufferDesc *bufHdr, SMgrRelation reln)
Definition localbuf.c:183
void UnpinLocalBuffer(Buffer buffer)
Definition localbuf.c:865
void AtEOXact_LocalBuffers(bool isCommit)
Definition localbuf.c:1027
StartBufferIOResult StartLocalBufferIO(BufferDesc *bufHdr, bool forInput, bool wait, PgAioWaitRef *io_wref)
Definition localbuf.c:532
void AtProcExit_LocalBuffers(void)
Definition localbuf.c:1038
bool PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)
Definition localbuf.c:829
void MarkLocalBufferDirty(Buffer buffer)
Definition localbuf.c:500
void DropRelationAllLocalBuffers(RelFileLocator rlocator)
Definition localbuf.c:726
void TerminateLocalBufferIO(BufferDesc *bufHdr, bool clear_dirty, uint64 set_flag_bits, bool release_aio)
Definition localbuf.c:586
int NLocBuffer
Definition localbuf.c:45
PrefetchBufferResult PrefetchLocalBuffer(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum)
Definition localbuf.c:72
BlockNumber ExtendBufferedRelLocal(BufferManagerRelation bmr, ForkNumber fork, uint32 flags, uint32 extend_by, BlockNumber extend_upto, Buffer *buffers, uint32 *extended_by)
Definition localbuf.c:355
void UnpinLocalBufferNoOwner(Buffer buffer)
Definition localbuf.c:872
void DropRelationLocalBuffers(RelFileLocator rlocator, ForkNumber *forkNum, int nforks, BlockNumber *firstDelBlock)
Definition localbuf.c:689
BufferDesc * LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum, BlockNumber blockNum, bool *foundPtr)
Definition localbuf.c:119
#define ExclusiveLock
Definition lockdefs.h:42
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
@ LW_WS_NOT_WAITING
Definition lwlock.h:30
@ LW_WS_WAITING
Definition lwlock.h:31
@ LW_WS_PENDING_WAKEUP
Definition lwlock.h:32
@ LW_SHARED
Definition lwlock.h:105
@ LW_EXCLUSIVE
Definition lwlock.h:104
void * repalloc(void *pointer, Size size)
Definition mcxt.c:1635
void pfree(void *pointer)
Definition mcxt.c:1619
void * palloc(Size size)
Definition mcxt.c:1390
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
#define VALGRIND_MAKE_MEM_DEFINED(addr, size)
Definition memdebug.h:26
#define VALGRIND_MAKE_MEM_NOACCESS(addr, size)
Definition memdebug.h:27
#define RESUME_INTERRUPTS()
Definition miscadmin.h:138
#define START_CRIT_SECTION()
Definition miscadmin.h:152
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:125
#define HOLD_INTERRUPTS()
Definition miscadmin.h:136
#define END_CRIT_SECTION()
Definition miscadmin.h:154
static char * errmsg
#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
const void * data
#define PG_IOV_MAX
Definition pg_iovec.h:47
static char buf[DEFAULT_XLOG_SEG_SIZE]
IOObject
Definition pgstat.h:280
@ IOOBJECT_RELATION
Definition pgstat.h:281
@ IOOBJECT_TEMP_RELATION
Definition pgstat.h:282
#define pgstat_count_buffer_read(rel)
Definition pgstat.h:755
IOContext
Definition pgstat.h:289
@ IOCONTEXT_NORMAL
Definition pgstat.h:293
@ IOOP_EXTEND
Definition pgstat.h:318
@ IOOP_READ
Definition pgstat.h:319
@ IOOP_WRITEBACK
Definition pgstat.h:315
@ IOOP_HIT
Definition pgstat.h:313
@ IOOP_EVICT
Definition pgstat.h:311
@ IOOP_REUSE
Definition pgstat.h:314
@ IOOP_WRITE
Definition pgstat.h:320
#define pgstat_count_buffer_hit(rel)
Definition pgstat.h:760
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)
Definition pgstat_io.c:91
void pgstat_count_io_op(IOObject io_object, IOContext io_context, IOOp io_op, uint32 cnt, uint64 bytes)
Definition pgstat_io.c:68
void pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op, instr_time start_time, uint32 cnt, uint64 bytes)
Definition pgstat_io.c:122
#define qsort(a, b, c, d)
Definition port.h:496
void PGSemaphoreUnlock(PGSemaphore sema)
Definition posix_sema.c:333
void PGSemaphoreLock(PGSemaphore sema)
Definition posix_sema.c:313
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
static int32 DatumGetInt32(Datum X)
Definition postgres.h:202
#define PointerGetDatum(X)
Definition postgres.h:354
#define InvalidOid
unsigned int Oid
static int fb(int x)
#define NUM_AUXILIARY_PROCS
Definition proc.h:529
#define GetPGProcByNumber(n)
Definition proc.h:506
#define proclist_delete(list, procno, link_member)
Definition proclist.h:187
static void proclist_init(proclist_head *list)
Definition proclist.h:29
#define proclist_push_tail(list, procno, link_member)
Definition proclist.h:191
#define proclist_foreach_modify(iter, lhead, link_member)
Definition proclist.h:206
static bool proclist_is_empty(const proclist_head *list)
Definition proclist.h:38
#define INVALID_PROC_NUMBER
Definition procnumber.h:26
int ProcNumber
Definition procnumber.h:24
void ProcessProcSignalBarrier(void)
Definition procsignal.c:511
void set_ps_display_remove_suffix(void)
Definition ps_status.c:440
void set_ps_display_suffix(const char *suffix)
Definition ps_status.c:388
char * psprintf(const char *fmt,...)
Definition psprintf.c:43
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
Definition read_stream.h:64
#define READ_STREAM_FULL
Definition read_stream.h:43
static unsigned hash(unsigned *uv, int n)
Definition rege_dfa.c:724
static SMgrRelation RelationGetSmgr(Relation rel)
Definition rel.h:578
#define RelationUsesLocalBuffers(relation)
Definition rel.h:648
#define RELATION_IS_OTHER_TEMP(relation)
Definition rel.h:678
#define RelationIsValid(relation)
Definition rel.h:491
#define RelFileLocatorBackendIsTemp(rlocator)
#define RelFileLocatorEquals(locator1, locator2)
ForkNumber
Definition relpath.h:56
@ MAIN_FORKNUM
Definition relpath.h:58
@ INIT_FORKNUM
Definition relpath.h:61
#define MAX_FORKNUM
Definition relpath.h:70
#define relpath(rlocator, forknum)
Definition relpath.h:150
#define relpathbackend(rlocator, backend, forknum)
Definition relpath.h:141
#define relpathperm(rlocator, forknum)
Definition relpath.h:146
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition resowner.c:459
#define RELEASE_PRIO_BUFFER_IOS
Definition resowner.h:62
@ RESOURCE_RELEASE_BEFORE_LOCKS
Definition resowner.h:54
#define RELEASE_PRIO_BUFFER_PINS
Definition resowner.h:63
void perform_spin_delay(SpinDelayStatus *status)
Definition s_lock.c:126
void finish_spin_delay(SpinDelayStatus *status)
Definition s_lock.c:186
#define init_local_spin_delay(status)
Definition s_lock.h:749
BlockNumber smgrnblocks(SMgrRelation reln, ForkNumber forknum)
Definition smgr.c:819
void smgrstartreadv(PgAioHandle *ioh, SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, void **buffers, BlockNumber nblocks)
Definition smgr.c:753
void smgrwriteback(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, BlockNumber nblocks)
Definition smgr.c:805
SMgrRelation smgropen(RelFileLocator rlocator, ProcNumber backend)
Definition smgr.c:240
void smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo)
Definition smgr.c:481
BlockNumber smgrnblocks_cached(SMgrRelation reln, ForkNumber forknum)
Definition smgr.c:847
uint32 smgrmaxcombine(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum)
Definition smgr.c:697
void smgrzeroextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks, bool skipFsync)
Definition smgr.c:649
void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
Definition smgr.c:620
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Definition smgr.c:462
bool smgrprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, int nblocks)
Definition smgr.c:678
static void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, const void *buffer, bool skipFsync)
Definition smgr.h:131
#define free(a)
void ProcSendSignal(ProcNumber procNumber)
Definition proc.c:2091
PGPROC * MyProc
Definition proc.c:71
int GetStartupBufferPinWaitBufId(void)
Definition proc.c:781
int DeadlockTimeout
Definition proc.c:62
void SetStartupBufferPinWaitBufId(int bufid)
Definition proc.c:769
void ProcWaitForSignal(uint32 wait_event_info)
Definition proc.c:2079
void ResolveRecoveryConflictWithBufferPin(void)
Definition standby.c:795
bool log_recovery_conflict_waits
Definition standby.c:43
void LogRecoveryConflict(RecoveryConflictReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
Definition standby.c:275
@ RECOVERY_CONFLICT_BUFFERPIN
Definition standby.h:49
bool RelFileLocatorSkippingWAL(RelFileLocator rlocator)
Definition storage.c:573
SMgrRelation RelationCreateStorage(RelFileLocator rlocator, char relpersistence, bool register_delete)
Definition storage.c:122
void log_smgrcreate(const RelFileLocator *rlocator, ForkNumber forkNum)
Definition storage.c:187
BufferTag tag
pg_atomic_uint64 state
int64 shared_blks_dirtied
Definition instrument.h:28
int64 local_blks_hit
Definition instrument.h:30
int64 shared_blks_read
Definition instrument.h:27
int64 shared_blks_written
Definition instrument.h:29
int64 local_blks_read
Definition instrument.h:31
int64 shared_blks_hit
Definition instrument.h:26
int ckpt_bufs_written
Definition xlog.h:179
ForkNumber forkNum
RelFileNumber relNumber
BlockNumber blockNum
float8 progress_slice
Definition bufmgr.c:164
int num_scanned
Definition bufmgr.c:169
float8 progress
Definition bufmgr.c:163
int num_to_scan
Definition bufmgr.c:167
struct ErrorContextCallback * previous
Definition elog.h:299
void(* callback)(void *arg)
Definition elog.h:300
Definition proc.h:179
uint8 lwWaitMode
Definition proc.h:284
PGSemaphore sem
Definition proc.h:258
uint8 lwWaiting
Definition proc.h:283
PgAioHandleCallbackStage stage
Definition aio.h:219
uint32 status
Definition aio_types.h:108
PgAioResult result
Definition aio_types.h:132
PgStat_Counter buf_written_clean
Definition pgstat.h:246
PgStat_Counter maxwritten_clean
Definition pgstat.h:247
PgStat_Counter buf_alloc
Definition pgstat.h:248
PgStat_Counter buffers_written
Definition pgstat.h:270
BufferLockMode lockmode
Definition bufmgr.c:112
PrivateRefCountData data
Definition bufmgr.c:130
RelFileLocator locator
RelFileNumber relNumber
char str[REL_PATH_STR_MAXLEN+1]
Definition relpath.h:123
RelFileLocator rd_locator
Definition rel.h:57
Form_pg_class rd_rel
Definition rel.h:111
const char * name
Definition resowner.h:93
RelFileLocatorBackend smgr_rlocator
Definition smgr.h:38
SMgrRelation srel
Definition bufmgr.c:185
RelFileLocator rlocator
Definition bufmgr.c:184
BlockNumber blockNum
RelFileNumber relNumber
ForkNumber forkNum
static uint64 table_relation_size(Relation rel, ForkNumber forkNumber)
Definition tableam.h:1938
struct PgAioTargetData::@129 smgr
BlockNumber blockNum
Definition aio_types.h:66
RelFileLocator rlocator
Definition aio_types.h:65
BlockNumber nblocks
Definition aio_types.h:67
ForkNumber forkNum
Definition aio_types.h:68
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition wait_event.h:67
static void pgstat_report_wait_end(void)
Definition wait_event.h:83
static volatile sig_atomic_t waiting
static TimestampTz wakeup[NUM_WALRCV_WAKEUPS]
bool RecoveryInProgress(void)
Definition xlog.c:6835
bool XLogNeedsFlush(XLogRecPtr record)
Definition xlog.c:3158
CheckpointStatsData CheckpointStats
Definition xlog.c:216
void XLogFlush(XLogRecPtr record)
Definition xlog.c:2800
#define CHECKPOINT_FLUSH_UNLOGGED
Definition xlog.h:155
#define CHECKPOINT_END_OF_RECOVERY
Definition xlog.h:152
#define CHECKPOINT_IS_SHUTDOWN
Definition xlog.h:151
#define XLogIsNeeded()
Definition xlog.h:112
#define XLogHintBitIsNeeded()
Definition xlog.h:123
#define XLogRecPtrIsValid(r)
Definition xlogdefs.h:29
uint64 XLogRecPtr
Definition xlogdefs.h:21
#define InvalidXLogRecPtr
Definition xlogdefs.h:28
XLogRecPtr XLogSaveBufferForHint(Buffer buffer, bool buffer_std)
XLogRecPtr log_newpage_buffer(Buffer buffer, bool page_std)
#define InHotStandby
Definition xlogutils.h:60