MCPcopy Create free account
hub / github.com/apache/cloudberry / DropRelFileNodeBuffers

Function DropRelFileNodeBuffers

src/backend/storage/buffer/bufmgr.c:3251–3367  ·  view source on GitHub ↗

--------------------------------------------------------------------- * DropRelFileNodeBuffers * * This function removes from the buffer pool all the pages of the * specified relation forks that have block numbers >= firstDelBlock. * (In particular, with firstDelBlock = 0, all pages are removed.) * Dirty pages are simply dropped, without bothering to write them * out first. Therefore

Source from the content-addressed store, hash-verified

3249 * --------------------------------------------------------------------
3250 */
3251void
3252DropRelFileNodeBuffers(SMgrRelation smgr_reln, ForkNumber *forkNum,
3253 int nforks, BlockNumber *firstDelBlock)
3254{
3255 int i;
3256 int j;
3257 RelFileNodeBackend rnode;
3258 BlockNumber nForkBlock[MAX_FORKNUM];
3259 uint64 nBlocksToInvalidate = 0;
3260
3261 rnode = smgr_reln->smgr_rnode;
3262
3263 /* Temp tables use shared buffers in Cloudberry */
3264 /* If it's a local relation, it's localbuf.c's problem. */
3265#if 0
3266 if (RelFileNodeBackendIsTemp(rnode))
3267 {
3268 if (rnode.backend == MyBackendId)
3269 {
3270 for (j = 0; j < nforks; j++)
3271 DropRelFileNodeLocalBuffers(rnode.node, forkNum[j],
3272 firstDelBlock[j]);
3273 }
3274 return;
3275 }
3276#endif
3277
3278 /*
3279 * To remove all the pages of the specified relation forks from the buffer
3280 * pool, we need to scan the entire buffer pool but we can optimize it by
3281 * finding the buffers from BufMapping table provided we know the exact
3282 * size of each fork of the relation. The exact size is required to ensure
3283 * that we don't leave any buffer for the relation being dropped as
3284 * otherwise the background writer or checkpointer can lead to a PANIC
3285 * error while flushing buffers corresponding to files that don't exist.
3286 *
3287 * To know the exact size, we rely on the size cached for each fork by us
3288 * during recovery which limits the optimization to recovery and on
3289 * standbys but we can easily extend it once we have shared cache for
3290 * relation size.
3291 *
3292 * In recovery, we cache the value returned by the first lseek(SEEK_END)
3293 * and the future writes keeps the cached value up-to-date. See
3294 * smgrextend. It is possible that the value of the first lseek is smaller
3295 * than the actual number of existing blocks in the file due to buggy
3296 * Linux kernels that might not have accounted for the recent write. But
3297 * that should be fine because there must not be any buffers after that
3298 * file size.
3299 */
3300 for (i = 0; i < nforks; i++)
3301 {
3302 /* Get the number of blocks for a relation's fork */
3303 nForkBlock[i] = smgrnblocks_cached(smgr_reln, forkNum[i]);
3304
3305 if (nForkBlock[i] == InvalidBlockNumber)
3306 {
3307 nBlocksToInvalidate = InvalidBlockNumber;
3308 break;

Callers 2

smgrtruncateFunction · 0.85
invalidate_buffersFunction · 0.85

Calls 5

smgrnblocks_cachedFunction · 0.85
LockBufHdrFunction · 0.85
InvalidateBufferFunction · 0.85

Tested by 1

invalidate_buffersFunction · 0.68