--------------------------------------------------------------------- * 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
| 3249 | * -------------------------------------------------------------------- |
| 3250 | */ |
| 3251 | void |
| 3252 | DropRelFileNodeBuffers(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; |