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

Commit76733b3

Browse files
committed
Avoid using a fake relcache entry to own an SmgrRelation.
If an error occurs before we close the fake relcache entry, the thefake relcache entry will be destroyed by the SmgrRelation willsurvive until end of transaction. Its smgr_owner pointer ends uppointing to already-freed memory.The original reason for using a fake relcache entry here was to tryto avoid reusing an SMgrRelation across a relevant invalidation. Toavoid that problem, just call smgropen() again each time we need areference to it. Hopefully someday we will come up with a moreelegant approach, but accessing uninitialized memory is bad so let'sdo this for now.Dilip Kumar, reviewed by Andres Freund and Tom Lane. Report byJustin Pryzby.Discussion:http://postgr.es/m/20220802175043.GA13682@telsasoft.comDiscussion:http://postgr.es/m/CAFiTN-vSFeE6_W9z698XNtFROOA_nSqUXWqLcG0emob_kJ+dEQ@mail.gmail.com
1 parent3d895bc commit76733b3

File tree

2 files changed

+28
-38
lines changed

2 files changed

+28
-38
lines changed

‎src/backend/commands/dbcommands.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,8 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
258258
Pagepage;
259259
List*rlocatorlist=NIL;
260260
LockRelIdrelid;
261-
Relationrel;
262261
Snapshotsnapshot;
262+
SMgrRelationsmgr;
263263
BufferAccessStrategybstrategy;
264264

265265
/* Get pg_class relfilenumber. */
@@ -276,16 +276,9 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
276276
rlocator.dbOid=dbid;
277277
rlocator.relNumber=relfilenumber;
278278

279-
/*
280-
* We can't use a real relcache entry for a relation in some other
281-
* database, but since we're only going to access the fields related to
282-
* physical storage, a fake one is good enough. If we didn't do this and
283-
* used the smgr layer directly, we would have to worry about
284-
* invalidations.
285-
*/
286-
rel=CreateFakeRelcacheEntry(rlocator);
287-
nblocks=smgrnblocks(RelationGetSmgr(rel),MAIN_FORKNUM);
288-
FreeFakeRelcacheEntry(rel);
279+
smgr=smgropen(rlocator,InvalidBackendId);
280+
nblocks=smgrnblocks(smgr,MAIN_FORKNUM);
281+
smgrclose(smgr);
289282

290283
/* Use a buffer access strategy since this is a bulk read operation. */
291284
bstrategy=GetAccessStrategy(BAS_BULKREAD);

‎src/backend/storage/buffer/bufmgr.c

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -487,9 +487,9 @@ static void FindAndDropRelationBuffers(RelFileLocator rlocator,
487487
ForkNumberforkNum,
488488
BlockNumbernForkBlock,
489489
BlockNumberfirstDelBlock);
490-
staticvoidRelationCopyStorageUsingBuffer(Relationsrc,Relationdst,
491-
ForkNumberforkNum,
492-
boolisunlogged);
490+
staticvoidRelationCopyStorageUsingBuffer(RelFileLocatorsrclocator,
491+
RelFileLocatordstlocator,
492+
ForkNumberforkNum,boolpermanent);
493493
staticvoidAtProcExit_Buffers(intcode,Datumarg);
494494
staticvoidCheckForBufferLeaks(void);
495495
staticintrlocator_comparator(constvoid*p1,constvoid*p2);
@@ -3701,8 +3701,9 @@ FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels)
37013701
* --------------------------------------------------------------------
37023702
*/
37033703
staticvoid
3704-
RelationCopyStorageUsingBuffer(Relationsrc,Relationdst,ForkNumberforkNum,
3705-
boolpermanent)
3704+
RelationCopyStorageUsingBuffer(RelFileLocatorsrclocator,
3705+
RelFileLocatordstlocator,
3706+
ForkNumberforkNum,boolpermanent)
37063707
{
37073708
BuffersrcBuf;
37083709
BufferdstBuf;
@@ -3722,7 +3723,8 @@ RelationCopyStorageUsingBuffer(Relation src, Relation dst, ForkNumber forkNum,
37223723
use_wal=XLogIsNeeded()&& (permanent||forkNum==INIT_FORKNUM);
37233724

37243725
/* Get number of blocks in the source relation. */
3725-
nblocks=smgrnblocks(RelationGetSmgr(src),forkNum);
3726+
nblocks=smgrnblocks(smgropen(srclocator,InvalidBackendId),
3727+
forkNum);
37263728

37273729
/* Nothing to copy; just return. */
37283730
if (nblocks==0)
@@ -3738,14 +3740,14 @@ RelationCopyStorageUsingBuffer(Relation src, Relation dst, ForkNumber forkNum,
37383740
CHECK_FOR_INTERRUPTS();
37393741

37403742
/* Read block from source relation. */
3741-
srcBuf=ReadBufferWithoutRelcache(src->rd_locator,forkNum,blkno,
3743+
srcBuf=ReadBufferWithoutRelcache(srclocator,forkNum,blkno,
37423744
RBM_NORMAL,bstrategy_src,
37433745
permanent);
37443746
LockBuffer(srcBuf,BUFFER_LOCK_SHARE);
37453747
srcPage=BufferGetPage(srcBuf);
37463748

37473749
/* Use P_NEW to extend the destination relation. */
3748-
dstBuf=ReadBufferWithoutRelcache(dst->rd_locator,forkNum,P_NEW,
3750+
dstBuf=ReadBufferWithoutRelcache(dstlocator,forkNum,P_NEW,
37493751
RBM_NORMAL,bstrategy_dst,
37503752
permanent);
37513753
LockBuffer(dstBuf,BUFFER_LOCK_EXCLUSIVE);
@@ -3783,24 +3785,13 @@ void
37833785
CreateAndCopyRelationData(RelFileLocatorsrc_rlocator,
37843786
RelFileLocatordst_rlocator,boolpermanent)
37853787
{
3786-
Relationsrc_rel;
3787-
Relationdst_rel;
3788+
RelFileLocatorBackendrlocator;
37883789
charrelpersistence;
37893790

37903791
/* Set the relpersistence. */
37913792
relpersistence=permanent ?
37923793
RELPERSISTENCE_PERMANENT :RELPERSISTENCE_UNLOGGED;
37933794

3794-
/*
3795-
* We can't use a real relcache entry for a relation in some other
3796-
* database, but since we're only going to access the fields related to
3797-
* physical storage, a fake one is good enough. If we didn't do this and
3798-
* used the smgr layer directly, we would have to worry about
3799-
* invalidations.
3800-
*/
3801-
src_rel=CreateFakeRelcacheEntry(src_rlocator);
3802-
dst_rel=CreateFakeRelcacheEntry(dst_rlocator);
3803-
38043795
/*
38053796
* Create and copy all forks of the relation. During create database we
38063797
* have a separate cleanup mechanism which deletes complete database
@@ -3810,15 +3801,16 @@ CreateAndCopyRelationData(RelFileLocator src_rlocator,
38103801
RelationCreateStorage(dst_rlocator,relpersistence, false);
38113802

38123803
/* copy main fork. */
3813-
RelationCopyStorageUsingBuffer(src_rel,dst_rel,MAIN_FORKNUM,permanent);
3804+
RelationCopyStorageUsingBuffer(src_rlocator,dst_rlocator,MAIN_FORKNUM,
3805+
permanent);
38143806

38153807
/* copy those extra forks that exist */
38163808
for (ForkNumberforkNum=MAIN_FORKNUM+1;
38173809
forkNum <=MAX_FORKNUM;forkNum++)
38183810
{
3819-
if (smgrexists(RelationGetSmgr(src_rel),forkNum))
3811+
if (smgrexists(smgropen(src_rlocator,InvalidBackendId),forkNum))
38203812
{
3821-
smgrcreate(RelationGetSmgr(dst_rel),forkNum, false);
3813+
smgrcreate(smgropen(dst_rlocator,InvalidBackendId),forkNum, false);
38223814

38233815
/*
38243816
* WAL log creation if the relation is persistent, or this is the
@@ -3828,14 +3820,19 @@ CreateAndCopyRelationData(RelFileLocator src_rlocator,
38283820
log_smgrcreate(&dst_rlocator,forkNum);
38293821

38303822
/* Copy a fork's data, block by block. */
3831-
RelationCopyStorageUsingBuffer(src_rel,dst_rel,forkNum,
3823+
RelationCopyStorageUsingBuffer(src_rlocator,dst_rlocator,forkNum,
38323824
permanent);
38333825
}
38343826
}
38353827

3836-
/* Release fake relcache entries. */
3837-
FreeFakeRelcacheEntry(src_rel);
3838-
FreeFakeRelcacheEntry(dst_rel);
3828+
/* close source and destination smgr if exists. */
3829+
rlocator.backend=InvalidBackendId;
3830+
3831+
rlocator.locator=src_rlocator;
3832+
smgrcloserellocator(rlocator);
3833+
3834+
rlocator.locator=dst_rlocator;
3835+
smgrcloserellocator(rlocator);
38393836
}
38403837

38413838
/* ---------------------------------------------------------------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp