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

Commit1b94f8f

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 parentd6d1fbf commit1b94f8f

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
@@ -257,8 +257,8 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
257257
Pagepage;
258258
List*rnodelist=NIL;
259259
LockRelIdrelid;
260-
Relationrel;
261260
Snapshotsnapshot;
261+
SMgrRelationsmgr;
262262
BufferAccessStrategybstrategy;
263263

264264
/* Get pg_class relfilenode. */
@@ -275,16 +275,9 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
275275
rnode.dbNode=dbid;
276276
rnode.relNode=relfilenode;
277277

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

289282
/* Use a buffer access strategy since this is a bulk read operation. */
290283
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 FindAndDropRelFileNodeBuffers(RelFileNode rnode,
487487
ForkNumberforkNum,
488488
BlockNumbernForkBlock,
489489
BlockNumberfirstDelBlock);
490-
staticvoidRelationCopyStorageUsingBuffer(Relationsrc,Relationdst,
491-
ForkNumberforkNum,
492-
boolisunlogged);
490+
staticvoidRelationCopyStorageUsingBuffer(RelFileNodesrcnode,
491+
RelFileNodedstnode,
492+
ForkNumberforkNum,boolpermanent);
493493
staticvoidAtProcExit_Buffers(intcode,Datumarg);
494494
staticvoidCheckForBufferLeaks(void);
495495
staticintrnode_comparator(constvoid*p1,constvoid*p2);
@@ -3702,8 +3702,9 @@ FlushRelationsAllBuffers(SMgrRelation *smgrs, int nrels)
37023702
* --------------------------------------------------------------------
37033703
*/
37043704
staticvoid
3705-
RelationCopyStorageUsingBuffer(Relationsrc,Relationdst,ForkNumberforkNum,
3706-
boolpermanent)
3705+
RelationCopyStorageUsingBuffer(RelFileNodesrcnode,
3706+
RelFileNodedstnode,
3707+
ForkNumberforkNum,boolpermanent)
37073708
{
37083709
BuffersrcBuf;
37093710
BufferdstBuf;
@@ -3723,7 +3724,8 @@ RelationCopyStorageUsingBuffer(Relation src, Relation dst, ForkNumber forkNum,
37233724
use_wal=XLogIsNeeded()&& (permanent||forkNum==INIT_FORKNUM);
37243725

37253726
/* Get number of blocks in the source relation. */
3726-
nblocks=smgrnblocks(RelationGetSmgr(src),forkNum);
3727+
nblocks=smgrnblocks(smgropen(srcnode,InvalidBackendId),
3728+
forkNum);
37273729

37283730
/* Nothing to copy; just return. */
37293731
if (nblocks==0)
@@ -3739,14 +3741,14 @@ RelationCopyStorageUsingBuffer(Relation src, Relation dst, ForkNumber forkNum,
37393741
CHECK_FOR_INTERRUPTS();
37403742

37413743
/* Read block from source relation. */
3742-
srcBuf=ReadBufferWithoutRelcache(src->rd_node,forkNum,blkno,
3744+
srcBuf=ReadBufferWithoutRelcache(srcnode,forkNum,blkno,
37433745
RBM_NORMAL,bstrategy_src,
37443746
permanent);
37453747
LockBuffer(srcBuf,BUFFER_LOCK_SHARE);
37463748
srcPage=BufferGetPage(srcBuf);
37473749

37483750
/* Use P_NEW to extend the destination relation. */
3749-
dstBuf=ReadBufferWithoutRelcache(dst->rd_node,forkNum,P_NEW,
3751+
dstBuf=ReadBufferWithoutRelcache(dstnode,forkNum,P_NEW,
37503752
RBM_NORMAL,bstrategy_dst,
37513753
permanent);
37523754
LockBuffer(dstBuf,BUFFER_LOCK_EXCLUSIVE);
@@ -3784,24 +3786,13 @@ void
37843786
CreateAndCopyRelationData(RelFileNodesrc_rnode,RelFileNodedst_rnode,
37853787
boolpermanent)
37863788
{
3787-
Relationsrc_rel;
3788-
Relationdst_rel;
3789+
RelFileNodeBackendrnode;
37893790
charrelpersistence;
37903791

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

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

38133804
/* copy main fork. */
3814-
RelationCopyStorageUsingBuffer(src_rel,dst_rel,MAIN_FORKNUM,permanent);
3805+
RelationCopyStorageUsingBuffer(src_rnode,dst_rnode,MAIN_FORKNUM,
3806+
permanent);
38153807

38163808
/* copy those extra forks that exist */
38173809
for (ForkNumberforkNum=MAIN_FORKNUM+1;
38183810
forkNum <=MAX_FORKNUM;forkNum++)
38193811
{
3820-
if (smgrexists(RelationGetSmgr(src_rel),forkNum))
3812+
if (smgrexists(smgropen(src_rnode,InvalidBackendId),forkNum))
38213813
{
3822-
smgrcreate(RelationGetSmgr(dst_rel),forkNum, false);
3814+
smgrcreate(smgropen(dst_rnode,InvalidBackendId),forkNum, false);
38233815

38243816
/*
38253817
* WAL log creation if the relation is persistent, or this is the
@@ -3829,14 +3821,19 @@ CreateAndCopyRelationData(RelFileNode src_rnode, RelFileNode dst_rnode,
38293821
log_smgrcreate(&dst_rnode,forkNum);
38303822

38313823
/* Copy a fork's data, block by block. */
3832-
RelationCopyStorageUsingBuffer(src_rel,dst_rel,forkNum,
3824+
RelationCopyStorageUsingBuffer(src_rnode,dst_rnode,forkNum,
38333825
permanent);
38343826
}
38353827
}
38363828

3837-
/* Release fake relcache entries. */
3838-
FreeFakeRelcacheEntry(src_rel);
3839-
FreeFakeRelcacheEntry(dst_rel);
3829+
/* close source and destination smgr if exists. */
3830+
rnode.backend=InvalidBackendId;
3831+
3832+
rnode.node=src_rnode;
3833+
smgrclosenode(rnode);
3834+
3835+
rnode.node=dst_rnode;
3836+
smgrclosenode(rnode);
38403837
}
38413838

38423839
/* ---------------------------------------------------------------------

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp