buf_internals.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. /*-------------------------------------------------------------------------
  2. *
  3. * buf_internals.h
  4. * Internal definitions for buffer manager and the buffer replacement
  5. * strategy.
  6. *
  7. *
  8. * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
  9. * Portions Copyright (c) 1994, Regents of the University of California
  10. *
  11. * src/include/storage/buf_internals.h
  12. *
  13. *-------------------------------------------------------------------------
  14. */
  15. #ifndef BUFMGR_INTERNALS_H
  16. #define BUFMGR_INTERNALS_H
  17. #include "storage/buf.h"
  18. #include "storage/bufmgr.h"
  19. #include "storage/latch.h"
  20. #include "storage/lwlock.h"
  21. #include "storage/shmem.h"
  22. #include "storage/smgr.h"
  23. #include "port/atomics.h"
  24. #include "storage/spin.h"
  25. #include "utils/relcache.h"
  26. /*
  27. * Buffer state is a single 32-bit variable where following data is combined.
  28. *
  29. * - 18 bits refcount
  30. * - 4 bits usage count
  31. * - 10 bits of flags
  32. *
  33. * Combining these values allows to perform some operations without locking
  34. * the buffer header, by modifying them together with a CAS loop.
  35. *
  36. * The definition of buffer state components is below.
  37. */
  38. #define BUF_REFCOUNT_ONE 1
  39. #define BUF_REFCOUNT_MASK ((1U << 18) - 1)
  40. #define BUF_USAGECOUNT_MASK 0x003C0000U
  41. #define BUF_USAGECOUNT_ONE (1U << 18)
  42. #define BUF_USAGECOUNT_SHIFT 18
  43. #define BUF_FLAG_MASK 0xFFC00000U
  44. /* Get refcount and usagecount from buffer state */
  45. #define BUF_STATE_GET_REFCOUNT(state) ((state) & BUF_REFCOUNT_MASK)
  46. #define BUF_STATE_GET_USAGECOUNT(state) (((state) & BUF_USAGECOUNT_MASK) >> BUF_USAGECOUNT_SHIFT)
  47. /*
  48. * Flags for buffer descriptors
  49. *
  50. * Note: TAG_VALID essentially means that there is a buffer hashtable
  51. * entry associated with the buffer's tag.
  52. */
  53. #define BM_LOCKED (1U << 22) /* buffer header is locked */
  54. #define BM_DIRTY (1U << 23) /* data needs writing */
  55. #define BM_VALID (1U << 24) /* data is valid */
  56. #define BM_TAG_VALID (1U << 25) /* tag is assigned */
  57. #define BM_IO_IN_PROGRESS (1U << 26) /* read or write in progress */
  58. #define BM_IO_ERROR (1U << 27) /* previous I/O failed */
  59. #define BM_JUST_DIRTIED (1U << 28) /* dirtied since write started */
  60. #define BM_PIN_COUNT_WAITER (1U << 29) /* have waiter for sole pin */
  61. #define BM_CHECKPOINT_NEEDED (1U << 30) /* must write for checkpoint */
  62. #define BM_PERMANENT (1U << 31) /* permanent buffer (not
  63. * unlogged, or init fork) */
  64. /*
  65. * The maximum allowed value of usage_count represents a tradeoff between
  66. * accuracy and speed of the clock-sweep buffer management algorithm. A
  67. * large value (comparable to NBuffers) would approximate LRU semantics.
  68. * But it can take as many as BM_MAX_USAGE_COUNT+1 complete cycles of
  69. * clock sweeps to find a free buffer, so in practice we don't want the
  70. * value to be very large.
  71. */
  72. #define BM_MAX_USAGE_COUNT 5
  73. /*
  74. * Buffer tag identifies which disk block the buffer contains.
  75. *
  76. * Note: the BufferTag data must be sufficient to determine where to write the
  77. * block, without reference to pg_class or pg_tablespace entries. It's
  78. * possible that the backend flushing the buffer doesn't even believe the
  79. * relation is visible yet (its xact may have started before the xact that
  80. * created the rel). The storage manager must be able to cope anyway.
  81. *
  82. * Note: if there's any pad bytes in the struct, INIT_BUFFERTAG will have
  83. * to be fixed to zero them, since this struct is used as a hash key.
  84. */
  85. typedef struct buftag
  86. {
  87. RelFileNode rnode; /* physical relation identifier */
  88. ForkNumber forkNum;
  89. BlockNumber blockNum; /* blknum relative to begin of reln */
  90. } BufferTag;
  91. #define CLEAR_BUFFERTAG(a) \
  92. ( \
  93. (a).rnode.spcNode = InvalidOid, \
  94. (a).rnode.dbNode = InvalidOid, \
  95. (a).rnode.relNode = InvalidOid, \
  96. (a).forkNum = InvalidForkNumber, \
  97. (a).blockNum = InvalidBlockNumber \
  98. )
  99. #define INIT_BUFFERTAG(a,xx_rnode,xx_forkNum,xx_blockNum) \
  100. ( \
  101. (a).rnode = (xx_rnode), \
  102. (a).forkNum = (xx_forkNum), \
  103. (a).blockNum = (xx_blockNum) \
  104. )
  105. #define BUFFERTAGS_EQUAL(a,b) \
  106. ( \
  107. RelFileNodeEquals((a).rnode, (b).rnode) && \
  108. (a).blockNum == (b).blockNum && \
  109. (a).forkNum == (b).forkNum \
  110. )
  111. /*
  112. * The shared buffer mapping table is partitioned to reduce contention.
  113. * To determine which partition lock a given tag requires, compute the tag's
  114. * hash code with BufTableHashCode(), then apply BufMappingPartitionLock().
  115. * NB: NUM_BUFFER_PARTITIONS must be a power of 2!
  116. */
  117. #define BufTableHashPartition(hashcode) \
  118. ((hashcode) % NUM_BUFFER_PARTITIONS)
  119. #define BufMappingPartitionLock(hashcode) \
  120. (&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + \
  121. BufTableHashPartition(hashcode)].lock)
  122. #define BufMappingPartitionLockByIndex(i) \
  123. (&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + (i)].lock)
  124. /*
  125. * BufferDesc -- shared descriptor/state data for a single shared buffer.
  126. *
  127. * Note: Buffer header lock (BM_LOCKED flag) must be held to examine or change
  128. * the tag, state or wait_backend_pid fields. In general, buffer header lock
  129. * is a spinlock which is combined with flags, refcount and usagecount into
  130. * single atomic variable. This layout allow us to do some operations in a
  131. * single atomic operation, without actually acquiring and releasing spinlock;
  132. * for instance, increase or decrease refcount. buf_id field never changes
  133. * after initialization, so does not need locking. freeNext is protected by
  134. * the buffer_strategy_lock not buffer header lock. The LWLock can take care
  135. * of itself. The buffer header lock is *not* used to control access to the
  136. * data in the buffer!
  137. *
  138. * It's assumed that nobody changes the state field while buffer header lock
  139. * is held. Thus buffer header lock holder can do complex updates of the
  140. * state variable in single write, simultaneously with lock release (cleaning
  141. * BM_LOCKED flag). On the other hand, updating of state without holding
  142. * buffer header lock is restricted to CAS, which insure that BM_LOCKED flag
  143. * is not set. Atomic increment/decrement, OR/AND etc. are not allowed.
  144. *
  145. * An exception is that if we have the buffer pinned, its tag can't change
  146. * underneath us, so we can examine the tag without locking the buffer header.
  147. * Also, in places we do one-time reads of the flags without bothering to
  148. * lock the buffer header; this is generally for situations where we don't
  149. * expect the flag bit being tested to be changing.
  150. *
  151. * We can't physically remove items from a disk page if another backend has
  152. * the buffer pinned. Hence, a backend may need to wait for all other pins
  153. * to go away. This is signaled by storing its own PID into
  154. * wait_backend_pid and setting flag bit BM_PIN_COUNT_WAITER. At present,
  155. * there can be only one such waiter per buffer.
  156. *
  157. * We use this same struct for local buffer headers, but the locks are not
  158. * used and not all of the flag bits are useful either. To avoid unnecessary
  159. * overhead, manipulations of the state field should be done without actual
  160. * atomic operations (i.e. only pg_atomic_read_u32() and
  161. * pg_atomic_unlocked_write_u32()).
  162. *
  163. * Be careful to avoid increasing the size of the struct when adding or
  164. * reordering members. Keeping it below 64 bytes (the most common CPU
  165. * cache line size) is fairly important for performance.
  166. */
  167. typedef struct BufferDesc
  168. {
  169. BufferTag tag; /* ID of page contained in buffer */
  170. int buf_id; /* buffer's index number (from 0) */
  171. /* state of the tag, containing flags, refcount and usagecount */
  172. pg_atomic_uint32 state;
  173. int wait_backend_pid; /* backend PID of pin-count waiter */
  174. int freeNext; /* link in freelist chain */
  175. LWLock content_lock; /* to lock access to buffer contents */
  176. } BufferDesc;
  177. /*
  178. * Concurrent access to buffer headers has proven to be more efficient if
  179. * they're cache line aligned. So we force the start of the BufferDescriptors
  180. * array to be on a cache line boundary and force the elements to be cache
  181. * line sized.
  182. *
  183. * XXX: As this is primarily matters in highly concurrent workloads which
  184. * probably all are 64bit these days, and the space wastage would be a bit
  185. * more noticeable on 32bit systems, we don't force the stride to be cache
  186. * line sized on those. If somebody does actual performance testing, we can
  187. * reevaluate.
  188. *
  189. * Note that local buffer descriptors aren't forced to be aligned - as there's
  190. * no concurrent access to those it's unlikely to be beneficial.
  191. *
  192. * We use 64bit as the cache line size here, because that's the most common
  193. * size. Making it bigger would be a waste of memory. Even if running on a
  194. * platform with either 32 or 128 byte line sizes, it's good to align to
  195. * boundaries and avoid false sharing.
  196. */
  197. #define BUFFERDESC_PAD_TO_SIZE (SIZEOF_VOID_P == 8 ? 64 : 1)
  198. typedef union BufferDescPadded
  199. {
  200. BufferDesc bufferdesc;
  201. char pad[BUFFERDESC_PAD_TO_SIZE];
  202. } BufferDescPadded;
  203. #define GetBufferDescriptor(id) (&BufferDescriptors[(id)].bufferdesc)
  204. #define GetLocalBufferDescriptor(id) (&LocalBufferDescriptors[(id)])
  205. #define BufferDescriptorGetBuffer(bdesc) ((bdesc)->buf_id + 1)
  206. #define BufferDescriptorGetIOLock(bdesc) \
  207. (&(BufferIOLWLockArray[(bdesc)->buf_id]).lock)
  208. #define BufferDescriptorGetContentLock(bdesc) \
  209. ((LWLock*) (&(bdesc)->content_lock))
  210. extern PGDLLIMPORT LWLockMinimallyPadded *BufferIOLWLockArray;
  211. /*
  212. * The freeNext field is either the index of the next freelist entry,
  213. * or one of these special values:
  214. */
  215. #define FREENEXT_END_OF_LIST (-1)
  216. #define FREENEXT_NOT_IN_LIST (-2)
  217. /*
  218. * Functions for acquiring/releasing a shared buffer header's spinlock. Do
  219. * not apply these to local buffers!
  220. */
  221. extern uint32 LockBufHdr(BufferDesc *desc);
  222. #define UnlockBufHdr(desc, s) \
  223. do { \
  224. pg_write_barrier(); \
  225. pg_atomic_write_u32(&(desc)->state, (s) & (~BM_LOCKED)); \
  226. } while (0)
  227. /*
  228. * The PendingWriteback & WritebackContext structure are used to keep
  229. * information about pending flush requests to be issued to the OS.
  230. */
  231. typedef struct PendingWriteback
  232. {
  233. /* could store different types of pending flushes here */
  234. BufferTag tag;
  235. } PendingWriteback;
  236. /* struct forward declared in bufmgr.h */
  237. typedef struct WritebackContext
  238. {
  239. /* pointer to the max number of writeback requests to coalesce */
  240. int *max_pending;
  241. /* current number of pending writeback requests */
  242. int nr_pending;
  243. /* pending requests */
  244. PendingWriteback pending_writebacks[WRITEBACK_MAX_PENDING_FLUSHES];
  245. } WritebackContext;
  246. /* in buf_init.c */
  247. extern PGDLLIMPORT BufferDescPadded *BufferDescriptors;
  248. extern PGDLLIMPORT WritebackContext BackendWritebackContext;
  249. /* in localbuf.c */
  250. extern BufferDesc *LocalBufferDescriptors;
  251. /* in bufmgr.c */
  252. /*
  253. * Structure to sort buffers per file on checkpoints.
  254. *
  255. * This structure is allocated per buffer in shared memory, so it should be
  256. * kept as small as possible.
  257. */
  258. typedef struct CkptSortItem
  259. {
  260. Oid tsId;
  261. Oid relNode;
  262. ForkNumber forkNum;
  263. BlockNumber blockNum;
  264. int buf_id;
  265. } CkptSortItem;
  266. extern CkptSortItem *CkptBufferIds;
  267. /*
  268. * Internal buffer management routines
  269. */
  270. /* bufmgr.c */
  271. extern void WritebackContextInit(WritebackContext *context, int *max_pending);
  272. extern void IssuePendingWritebacks(WritebackContext *context);
  273. extern void ScheduleBufferTagForWriteback(WritebackContext *context, BufferTag *tag);
  274. /* freelist.c */
  275. extern BufferDesc *StrategyGetBuffer(BufferAccessStrategy strategy,
  276. uint32 *buf_state);
  277. extern void StrategyFreeBuffer(BufferDesc *buf);
  278. extern bool StrategyRejectBuffer(BufferAccessStrategy strategy,
  279. BufferDesc *buf);
  280. extern int StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc);
  281. extern void StrategyNotifyBgWriter(int bgwprocno);
  282. extern Size StrategyShmemSize(void);
  283. extern void StrategyInitialize(bool init);
  284. /* buf_table.c */
  285. extern Size BufTableShmemSize(int size);
  286. extern void InitBufTable(int size);
  287. extern uint32 BufTableHashCode(BufferTag *tagPtr);
  288. extern int BufTableLookup(BufferTag *tagPtr, uint32 hashcode);
  289. extern int BufTableInsert(BufferTag *tagPtr, uint32 hashcode, int buf_id);
  290. extern void BufTableDelete(BufferTag *tagPtr, uint32 hashcode);
  291. /* localbuf.c */
  292. extern void LocalPrefetchBuffer(SMgrRelation smgr, ForkNumber forkNum,
  293. BlockNumber blockNum);
  294. extern BufferDesc *LocalBufferAlloc(SMgrRelation smgr, ForkNumber forkNum,
  295. BlockNumber blockNum, bool *foundPtr);
  296. extern void MarkLocalBufferDirty(Buffer buffer);
  297. extern void DropRelFileNodeLocalBuffers(RelFileNode rnode, ForkNumber forkNum,
  298. BlockNumber firstDelBlock);
  299. extern void DropRelFileNodeAllLocalBuffers(RelFileNode rnode);
  300. extern void AtEOXact_LocalBuffers(bool isCommit);
  301. #endif /* BUFMGR_INTERNALS_H */