@@ -136,7 +136,7 @@ static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode,
136
136
bool add_okay );
137
137
static void merge_map_updates (RelMapFile * map , const RelMapFile * updates ,
138
138
bool add_okay );
139
- static void load_relmap_file (bool shared );
139
+ static void load_relmap_file (bool shared , bool lock_held );
140
140
static void write_relmap_file (bool shared , RelMapFile * newmap ,
141
141
bool write_wal , bool send_sinval , bool preserve_files ,
142
142
Oid dbid , Oid tsid , const char * dbpath );
@@ -405,12 +405,12 @@ RelationMapInvalidate(bool shared)
405
405
if (shared )
406
406
{
407
407
if (shared_map .magic == RELMAPPER_FILEMAGIC )
408
- load_relmap_file (true);
408
+ load_relmap_file (true, false );
409
409
}
410
410
else
411
411
{
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
425
425
RelationMapInvalidateAll (void )
426
426
{
427
427
if (shared_map .magic == RELMAPPER_FILEMAGIC )
428
- load_relmap_file (true);
428
+ load_relmap_file (true, false );
429
429
if (local_map .magic == RELMAPPER_FILEMAGIC )
430
- load_relmap_file (false);
430
+ load_relmap_file (false, false );
431
431
}
432
432
433
433
/*
@@ -612,7 +612,7 @@ RelationMapInitializePhase2(void)
612
612
/*
613
613
* Load the shared map file, die on error.
614
614
*/
615
- load_relmap_file (true);
615
+ load_relmap_file (true, false );
616
616
}
617
617
618
618
/*
@@ -633,7 +633,7 @@ RelationMapInitializePhase3(void)
633
633
/*
634
634
* Load the local map file, die on error.
635
635
*/
636
- load_relmap_file (false);
636
+ load_relmap_file (false, false );
637
637
}
638
638
639
639
/*
@@ -695,7 +695,7 @@ RestoreRelationMap(char *startAddress)
695
695
* Note that the local case requires DatabasePath to be set up.
696
696
*/
697
697
static void
698
- load_relmap_file (bool shared )
698
+ load_relmap_file (bool shared , bool lock_held )
699
699
{
700
700
RelMapFile * map ;
701
701
char mapfilename [MAXPGPATH ];
@@ -725,12 +725,15 @@ load_relmap_file(bool shared)
725
725
mapfilename )));
726
726
727
727
/*
728
- * Note: we could take RelationMappingLock in shared mode here, but it
729
- * seems unnecessary since our read() should be atomic against any
730
- * concurrent updater's write(). If the file is updated shortly after we
731
- * look, the sinval signaling mechanism will make us re-read it before we
732
- * are able to access any relation that's affected by the change.
728
+ * Grab the lock to prevent the file from being updated while we read it,
729
+ * unless the caller is already holding the lock. If the file is updated
730
+ * shortly after we look, the sinval signaling mechanism will make us
731
+ * re-read it before we are able to access any relation that's affected by
732
+ * the change.
733
733
*/
734
+ if (!lock_held )
735
+ LWLockAcquire (RelationMappingLock , LW_SHARED );
736
+
734
737
pgstat_report_wait_start (WAIT_EVENT_RELATION_MAP_READ );
735
738
r = read (fd , map , sizeof (RelMapFile ));
736
739
if (r != sizeof (RelMapFile ))
@@ -747,6 +750,9 @@ load_relmap_file(bool shared)
747
750
}
748
751
pgstat_report_wait_end ();
749
752
753
+ if (!lock_held )
754
+ LWLockRelease (RelationMappingLock );
755
+
750
756
if (CloseTransientFile (fd ) != 0 )
751
757
ereport (FATAL ,
752
758
(errcode_for_file_access (),
@@ -969,7 +975,7 @@ perform_relmap_update(bool shared, const RelMapFile *updates)
969
975
LWLockAcquire (RelationMappingLock , LW_EXCLUSIVE );
970
976
971
977
/* Be certain we see any other updates just made */
972
- load_relmap_file (shared );
978
+ load_relmap_file (shared , true );
973
979
974
980
/* Prepare updated data in a local variable */
975
981
if (shared )
0 commit comments