|
88 | 88 | #include "storage/bufmgr.h" |
89 | 89 | #include "storage/lmgr.h" |
90 | 90 | #include "storage/smgr.h" |
| 91 | +#include "utils/inval.h" |
91 | 92 |
|
92 | 93 |
|
93 | 94 | /*#define TRACE_VISIBILITYMAP */ |
@@ -482,16 +483,20 @@ vm_readbuf(Relation rel, BlockNumber blkno, bool extend) |
482 | 483 | { |
483 | 484 | Buffer buf; |
484 | 485 |
|
| 486 | + /* |
| 487 | + * We might not have opened the relation at the smgr level yet, or we might |
| 488 | + * have been forced to close it by a sinval message. The code below won't |
| 489 | + * necessarily notice relation extension immediately when extend = false, |
| 490 | + * so we rely on sinval messages to ensure that our ideas about the size of |
| 491 | + * the map aren't too far out of date. |
| 492 | + */ |
485 | 493 | RelationOpenSmgr(rel); |
486 | 494 |
|
487 | 495 | /* |
488 | 496 | * If we haven't cached the size of the visibility map fork yet, check it |
489 | | - * first. Also recheck if the requested block seems to be past end, since |
490 | | - * our cached value might be stale. (We send smgr inval messages on |
491 | | - * truncation, but not on extension.) |
| 497 | + * first. |
492 | 498 | */ |
493 | | - if (rel->rd_smgr->smgr_vm_nblocks == InvalidBlockNumber || |
494 | | - blkno >= rel->rd_smgr->smgr_vm_nblocks) |
| 499 | + if (rel->rd_smgr->smgr_vm_nblocks == InvalidBlockNumber) |
495 | 500 | { |
496 | 501 | if (smgrexists(rel->rd_smgr, VISIBILITYMAP_FORKNUM)) |
497 | 502 | rel->rd_smgr->smgr_vm_nblocks = smgrnblocks(rel->rd_smgr, |
@@ -560,13 +565,23 @@ vm_extend(Relation rel, BlockNumber vm_nblocks) |
560 | 565 |
|
561 | 566 | vm_nblocks_now = smgrnblocks(rel->rd_smgr, VISIBILITYMAP_FORKNUM); |
562 | 567 |
|
| 568 | + /* Now extend the file */ |
563 | 569 | while (vm_nblocks_now < vm_nblocks) |
564 | 570 | { |
565 | 571 | smgrextend(rel->rd_smgr, VISIBILITYMAP_FORKNUM, vm_nblocks_now, |
566 | 572 | (char *) pg, false); |
567 | 573 | vm_nblocks_now++; |
568 | 574 | } |
569 | 575 |
|
| 576 | + /* |
| 577 | + * Send a shared-inval message to force other backends to close any smgr |
| 578 | + * references they may have for this rel, which we are about to change. |
| 579 | + * This is a useful optimization because it means that backends don't have |
| 580 | + * to keep checking for creation or extension of the file, which happens |
| 581 | + * infrequently. |
| 582 | + */ |
| 583 | + CacheInvalidateSmgr(rel->rd_smgr->smgr_rnode); |
| 584 | + |
570 | 585 | /* Update local cache with the up-to-date size */ |
571 | 586 | rel->rd_smgr->smgr_vm_nblocks = vm_nblocks_now; |
572 | 587 |
|
|
0 commit comments