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

Commitc78bb32

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 parente00e5db commitc78bb32

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
@@ -123,7 +123,7 @@ static void apply_map_update(RelMapFile *map, Oid relationId, Oid fileNode,
123123
booladd_okay);
124124
staticvoidmerge_map_updates(RelMapFile*map,constRelMapFile*updates,
125125
booladd_okay);
126-
staticvoidload_relmap_file(boolshared);
126+
staticvoidload_relmap_file(boolshared,boollock_held);
127127
staticvoidwrite_relmap_file(boolshared,RelMapFile*newmap,
128128
boolwrite_wal,boolsend_sinval,boolpreserve_files,
129129
Oiddbid,Oidtsid,constchar*dbpath);
@@ -393,12 +393,12 @@ RelationMapInvalidate(bool shared)
393393
if (shared)
394394
{
395395
if (shared_map.magic==RELMAPPER_FILEMAGIC)
396-
load_relmap_file(true);
396+
load_relmap_file(true, false);
397397
}
398398
else
399399
{
400400
if (local_map.magic==RELMAPPER_FILEMAGIC)
401-
load_relmap_file(false);
401+
load_relmap_file(false, false);
402402
}
403403
}
404404

@@ -413,9 +413,9 @@ void
413413
RelationMapInvalidateAll(void)
414414
{
415415
if (shared_map.magic==RELMAPPER_FILEMAGIC)
416-
load_relmap_file(true);
416+
load_relmap_file(true, false);
417417
if (local_map.magic==RELMAPPER_FILEMAGIC)
418-
load_relmap_file(false);
418+
load_relmap_file(false, false);
419419
}
420420

421421
/*
@@ -594,7 +594,7 @@ RelationMapInitializePhase2(void)
594594
/*
595595
* Load the shared map file, die on error.
596596
*/
597-
load_relmap_file(true);
597+
load_relmap_file(true, false);
598598
}
599599

600600
/*
@@ -615,7 +615,7 @@ RelationMapInitializePhase3(void)
615615
/*
616616
* Load the local map file, die on error.
617617
*/
618-
load_relmap_file(false);
618+
load_relmap_file(false, false);
619619
}
620620

621621
/*
@@ -627,7 +627,7 @@ RelationMapInitializePhase3(void)
627627
* Note that the local case requires DatabasePath to be set up.
628628
*/
629629
staticvoid
630-
load_relmap_file(boolshared)
630+
load_relmap_file(boolshared,boollock_held)
631631
{
632632
RelMapFile*map;
633633
charmapfilename[MAXPGPATH];
@@ -656,12 +656,15 @@ load_relmap_file(bool shared)
656656
mapfilename)));
657657

658658
/*
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(). Ifthefile 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 bythe 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.
664664
*/
665+
if (!lock_held)
666+
LWLockAcquire(RelationMappingLock,LW_SHARED);
667+
665668
pgstat_report_wait_start(WAIT_EVENT_RELATION_MAP_READ);
666669
if (read(fd,map,sizeof(RelMapFile))!=sizeof(RelMapFile))
667670
ereport(FATAL,
@@ -670,6 +673,9 @@ load_relmap_file(bool shared)
670673
mapfilename)));
671674
pgstat_report_wait_end();
672675

676+
if (!lock_held)
677+
LWLockRelease(RelationMappingLock);
678+
673679
CloseTransientFile(fd);
674680

675681
/* check for correct magic number, etc */
@@ -888,7 +894,7 @@ perform_relmap_update(bool shared, const RelMapFile *updates)
888894
LWLockAcquire(RelationMappingLock,LW_EXCLUSIVE);
889895

890896
/* Be certain we see any other updates just made */
891-
load_relmap_file(shared);
897+
load_relmap_file(shared, true);
892898

893899
/* Prepare updated data in a local variable */
894900
if (shared)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp