@@ -123,7 +123,7 @@ static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode,
123
123
bool add_okay );
124
124
static void merge_map_updates (RelMapFile * map ,const RelMapFile * updates ,
125
125
bool add_okay );
126
- static void load_relmap_file (bool shared );
126
+ static void load_relmap_file (bool shared , bool lock_held );
127
127
static void write_relmap_file (bool shared ,RelMapFile * newmap ,
128
128
bool write_wal ,bool send_sinval ,bool preserve_files ,
129
129
Oid dbid ,Oid tsid ,const char * dbpath );
@@ -393,12 +393,12 @@ RelationMapInvalidate(bool shared)
393
393
if (shared )
394
394
{
395
395
if (shared_map .magic == RELMAPPER_FILEMAGIC )
396
- load_relmap_file (true);
396
+ load_relmap_file (true, false );
397
397
}
398
398
else
399
399
{
400
400
if (local_map .magic == RELMAPPER_FILEMAGIC )
401
- load_relmap_file (false);
401
+ load_relmap_file (false, false );
402
402
}
403
403
}
404
404
413
413
RelationMapInvalidateAll (void )
414
414
{
415
415
if (shared_map .magic == RELMAPPER_FILEMAGIC )
416
- load_relmap_file (true);
416
+ load_relmap_file (true, false );
417
417
if (local_map .magic == RELMAPPER_FILEMAGIC )
418
- load_relmap_file (false);
418
+ load_relmap_file (false, false );
419
419
}
420
420
421
421
/*
@@ -594,7 +594,7 @@ RelationMapInitializePhase2(void)
594
594
/*
595
595
* Load the shared map file, die on error.
596
596
*/
597
- load_relmap_file (true);
597
+ load_relmap_file (true, false );
598
598
}
599
599
600
600
/*
@@ -615,7 +615,7 @@ RelationMapInitializePhase3(void)
615
615
/*
616
616
* Load the local map file, die on error.
617
617
*/
618
- load_relmap_file (false);
618
+ load_relmap_file (false, false );
619
619
}
620
620
621
621
/*
@@ -627,7 +627,7 @@ RelationMapInitializePhase3(void)
627
627
* Note that the local case requires DatabasePath to be set up.
628
628
*/
629
629
static void
630
- load_relmap_file (bool shared )
630
+ load_relmap_file (bool shared , bool lock_held )
631
631
{
632
632
RelMapFile * map ;
633
633
char mapfilename [MAXPGPATH ];
@@ -656,12 +656,15 @@ load_relmap_file(bool shared)
656
656
mapfilename )));
657
657
658
658
/*
659
- *Note: we could take RelationMappingLock in shared mode here, but it
660
- *seems unnecessary since our read() should be atomic against any
661
- *concurrent updater's write(). If thefile is updated shortly after we
662
- *look, the sinval signaling mechanism will make us re-read it before we
663
- *are able to access any relation that's affected by the change.
659
+ *Grab the lock to prevent the file from being updated while we read it,
660
+ *unless the caller is already holding the lock. If the file is updated
661
+ *shortly after we look, thesinval signaling mechanism will make us
662
+ *re-read it before we are able to access any relation that's affected by
663
+ * the change.
664
664
*/
665
+ if (!lock_held )
666
+ LWLockAcquire (RelationMappingLock ,LW_SHARED );
667
+
665
668
pgstat_report_wait_start (WAIT_EVENT_RELATION_MAP_READ );
666
669
if (read (fd ,map ,sizeof (RelMapFile ))!= sizeof (RelMapFile ))
667
670
ereport (FATAL ,
@@ -670,6 +673,9 @@ load_relmap_file(bool shared)
670
673
mapfilename )));
671
674
pgstat_report_wait_end ();
672
675
676
+ if (!lock_held )
677
+ LWLockRelease (RelationMappingLock );
678
+
673
679
CloseTransientFile (fd );
674
680
675
681
/* check for correct magic number, etc */
@@ -888,7 +894,7 @@ perform_relmap_update(bool shared, const RelMapFile *updates)
888
894
LWLockAcquire (RelationMappingLock ,LW_EXCLUSIVE );
889
895
890
896
/* Be certain we see any other updates just made */
891
- load_relmap_file (shared );
897
+ load_relmap_file (shared , true );
892
898
893
899
/* Prepare updated data in a local variable */
894
900
if (shared )