Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb6d8d20

Browse files
committed
Prevent race condition while reading relmapper file.
Contrary to the comment here, POSIX does not guarantee atomicity of aread(), if another process calls write() concurrently. Or at least Linuxdoes not. Add locking to load_relmap_file() to avoid the race condition.Fixes bug #17064. Thanks to Alexander Lakhin for the report and test case.Backpatch-through: 9.6, all supported versions.Discussion:https://www.postgresql.org/message-id/17064-bb0d7904ef72add3@postgresql.org
1 parentf08722c commitb6d8d20

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

‎src/backend/utils/cache/relmapper.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode,
136136
booladd_okay);
137137
staticvoidmerge_map_updates(RelMapFile*map,constRelMapFile*updates,
138138
booladd_okay);
139-
staticvoidload_relmap_file(boolshared);
139+
staticvoidload_relmap_file(boolshared,boollock_held);
140140
staticvoidwrite_relmap_file(boolshared,RelMapFile*newmap,
141141
boolwrite_wal,boolsend_sinval,boolpreserve_files,
142142
Oiddbid,Oidtsid,constchar*dbpath);
@@ -405,12 +405,12 @@ RelationMapInvalidate(bool shared)
405405
if (shared)
406406
{
407407
if (shared_map.magic==RELMAPPER_FILEMAGIC)
408-
load_relmap_file(true);
408+
load_relmap_file(true, false);
409409
}
410410
else
411411
{
412412
if (local_map.magic==RELMAPPER_FILEMAGIC)
413-
load_relmap_file(false);
413+
load_relmap_file(false, false);
414414
}
415415
}
416416

@@ -425,9 +425,9 @@ void
425425
RelationMapInvalidateAll(void)
426426
{
427427
if (shared_map.magic==RELMAPPER_FILEMAGIC)
428-
load_relmap_file(true);
428+
load_relmap_file(true, false);
429429
if (local_map.magic==RELMAPPER_FILEMAGIC)
430-
load_relmap_file(false);
430+
load_relmap_file(false, false);
431431
}
432432

433433
/*
@@ -612,7 +612,7 @@ RelationMapInitializePhase2(void)
612612
/*
613613
* Load the shared map file, die on error.
614614
*/
615-
load_relmap_file(true);
615+
load_relmap_file(true, false);
616616
}
617617

618618
/*
@@ -633,7 +633,7 @@ RelationMapInitializePhase3(void)
633633
/*
634634
* Load the local map file, die on error.
635635
*/
636-
load_relmap_file(false);
636+
load_relmap_file(false, false);
637637
}
638638

639639
/*
@@ -695,7 +695,7 @@ RestoreRelationMap(char *startAddress)
695695
* Note that the local case requires DatabasePath to be set up.
696696
*/
697697
staticvoid
698-
load_relmap_file(boolshared)
698+
load_relmap_file(boolshared,boollock_held)
699699
{
700700
RelMapFile*map;
701701
charmapfilename[MAXPGPATH];
@@ -725,12 +725,15 @@ load_relmap_file(bool shared)
725725
mapfilename)));
726726

727727
/*
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(). Ifthefile 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 bythe 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,thesinval signaling mechanism will make us
731+
*re-read it before we are able to access any relation that's affected by
732+
* the change.
733733
*/
734+
if (!lock_held)
735+
LWLockAcquire(RelationMappingLock,LW_SHARED);
736+
734737
pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_READ);
735738
r=read(fd,map,sizeof(RelMapFile));
736739
if (r!=sizeof(RelMapFile))
@@ -747,6 +750,9 @@ load_relmap_file(bool shared)
747750
}
748751
pgstat_report_wait_end();
749752

753+
if (!lock_held)
754+
LWLockRelease(RelationMappingLock);
755+
750756
if (CloseTransientFile(fd)!=0)
751757
ereport(FATAL,
752758
(errcode_for_file_access(),
@@ -969,7 +975,7 @@ perform_relmap_update(bool shared, const RelMapFile *updates)
969975
LWLockAcquire(RelationMappingLock,LW_EXCLUSIVE);
970976

971977
/* Be certain we see any other updates just made */
972-
load_relmap_file(shared);
978+
load_relmap_file(shared, true);
973979

974980
/* Prepare updated data in a local variable */
975981
if (shared)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp