@@ -122,7 +122,7 @@ static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode,
122
122
bool add_okay );
123
123
static void merge_map_updates (RelMapFile * map , const RelMapFile * updates ,
124
124
bool add_okay );
125
- static void load_relmap_file (bool shared );
125
+ static void load_relmap_file (bool shared , bool lock_held );
126
126
static void write_relmap_file (bool shared , RelMapFile * newmap ,
127
127
bool write_wal , bool send_sinval , bool preserve_files ,
128
128
Oid dbid , Oid tsid , const char * dbpath );
@@ -388,12 +388,12 @@ RelationMapInvalidate(bool shared)
388
388
if (shared )
389
389
{
390
390
if (shared_map .magic == RELMAPPER_FILEMAGIC )
391
- load_relmap_file (true);
391
+ load_relmap_file (true, false );
392
392
}
393
393
else
394
394
{
395
395
if (local_map .magic == RELMAPPER_FILEMAGIC )
396
- load_relmap_file (false);
396
+ load_relmap_file (false, false );
397
397
}
398
398
}
399
399
408
408
RelationMapInvalidateAll (void )
409
409
{
410
410
if (shared_map .magic == RELMAPPER_FILEMAGIC )
411
- load_relmap_file (true);
411
+ load_relmap_file (true, false );
412
412
if (local_map .magic == RELMAPPER_FILEMAGIC )
413
- load_relmap_file (false);
413
+ load_relmap_file (false, false );
414
414
}
415
415
416
416
/*
@@ -589,7 +589,7 @@ RelationMapInitializePhase2(void)
589
589
/*
590
590
* Load the shared map file, die on error.
591
591
*/
592
- load_relmap_file (true);
592
+ load_relmap_file (true, false );
593
593
}
594
594
595
595
/*
@@ -610,7 +610,7 @@ RelationMapInitializePhase3(void)
610
610
/*
611
611
* Load the local map file, die on error.
612
612
*/
613
- load_relmap_file (false);
613
+ load_relmap_file (false, false );
614
614
}
615
615
616
616
/*
@@ -622,7 +622,7 @@ RelationMapInitializePhase3(void)
622
622
* Note that the local case requires DatabasePath to be set up.
623
623
*/
624
624
static void
625
- load_relmap_file (bool shared )
625
+ load_relmap_file (bool shared , bool lock_held )
626
626
{
627
627
RelMapFile * map ;
628
628
char mapfilename [MAXPGPATH ];
@@ -652,18 +652,24 @@ load_relmap_file(bool shared)
652
652
mapfilename )));
653
653
654
654
/*
655
- * Note: we could take RelationMappingLock in shared mode here, but it
656
- * seems unnecessary since our read() should be atomic against any
657
- * concurrent updater's write(). If the file is updated shortly after we
658
- * look, the sinval signaling mechanism will make us re-read it before we
659
- * are able to access any relation that's affected by the change.
655
+ * Grab the lock to prevent the file from being updated while we read it,
656
+ * unless the caller is already holding the lock. If the file is updated
657
+ * shortly after we look, the sinval signaling mechanism will make us
658
+ * re-read it before we are able to access any relation that's affected by
659
+ * the change.
660
660
*/
661
+ if (!lock_held )
662
+ LWLockAcquire (RelationMappingLock , LW_SHARED );
663
+
661
664
if (read (fd , map , sizeof (RelMapFile )) != sizeof (RelMapFile ))
662
665
ereport (FATAL ,
663
666
(errcode_for_file_access (),
664
667
errmsg ("could not read relation mapping file \"%s\": %m" ,
665
668
mapfilename )));
666
669
670
+ if (!lock_held )
671
+ LWLockRelease (RelationMappingLock );
672
+
667
673
CloseTransientFile (fd );
668
674
669
675
/* check for correct magic number, etc */
@@ -880,7 +886,7 @@ perform_relmap_update(bool shared, const RelMapFile *updates)
880
886
LWLockAcquire (RelationMappingLock , LW_EXCLUSIVE );
881
887
882
888
/* Be certain we see any other updates just made */
883
- load_relmap_file (shared );
889
+ load_relmap_file (shared , true );
884
890
885
891
/* Prepare updated data in a local variable */
886
892
if (shared )
0 commit comments