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

Commit1926906

Browse files
committed
1. Fix md memory leak:
mdunlink() and mdclose() (too !!!) now free MdfdVec for relation and add it to free list, so it may be re-used for another relation later.2. Fix VFD-manager memory leak (found by Massimo ... and me): mdunlink() has to call FileUnlink() to free allocation for fileName and add the Vfd slot to the free list.
1 parentff8ce52 commit1926906

File tree

2 files changed

+136
-56
lines changed

2 files changed

+136
-56
lines changed

‎src/backend/storage/smgr/md.c

Lines changed: 128 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.12 1997/05/06 02:03:20 vadim Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.13 1997/05/22 17:08:33 vadim Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -42,25 +42,29 @@
4242
*/
4343

4444
typedefstruct_MdfdVec {
45-
intmdfd_vfd;/* fd number in vfd pool */
46-
uint16mdfd_flags;/* clean, dirty */
47-
intmdfd_lstbcnt;/* most recent block count */
48-
struct_MdfdVec*mdfd_chain;/* for large relations */
45+
intmdfd_vfd;/* fd number in vfd pool */
46+
uint16mdfd_flags;/* clean, dirty, free */
47+
intmdfd_lstbcnt;/* most recent block count */
48+
intmdfd_nextFree;/* next free vector */
49+
struct_MdfdVec*mdfd_chain;/* for large relations */
4950
}MdfdVec;
5051

5152
staticintNfds=100;
5253
staticMdfdVec*Md_fdvec= (MdfdVec*)NULL;
54+
staticintMd_Free=-1;
5355
staticintCurFd=0;
5456
staticMemoryContextMdCxt;
5557

5658
#defineMDFD_DIRTY(uint16) 0x01
59+
#defineMDFD_FREE(uint16) 0x02
5760

5861
#defineRELSEG_SIZE262144/* (2 ** 31) / 8192 -- 2GB file */
5962

6063
/* routines declared here */
6164
staticMdfdVec*_mdfd_openseg(Relationreln,intsegno,intoflags);
6265
staticMdfdVec*_mdfd_getseg(Relationreln,intblkno,intoflag);
63-
staticint_fdvec_ext(void);
66+
staticint_fdvec_alloc (void);
67+
staticvoid_fdvec_free (int);
6468
staticBlockNumber_mdnblocks(Filefile,Sizeblcksz);
6569

6670
/*
@@ -78,6 +82,7 @@ int
7882
mdinit()
7983
{
8084
MemoryContextoldcxt;
85+
inti;
8186

8287
MdCxt= (MemoryContext)CreateGlobalMemory("MdSmgr");
8388
if (MdCxt== (MemoryContext)NULL)
@@ -90,7 +95,16 @@ mdinit()
9095
if (Md_fdvec== (MdfdVec*)NULL)
9196
return (SM_FAIL);
9297

93-
memset(Md_fdvec,0,Nfds*sizeof(MdfdVec));
98+
memset(Md_fdvec,0,Nfds*sizeof(MdfdVec));
99+
100+
/* Set free list */
101+
for (i=0;i<Nfds;i++ )
102+
{
103+
Md_fdvec[i].mdfd_nextFree=i+1;
104+
Md_fdvec[i].mdfd_flags=MDFD_FREE;
105+
}
106+
Md_Free=0;
107+
Md_fdvec[Nfds-1].mdfd_nextFree=-1;
94108

95109
return (SM_SUCCESS);
96110
}
@@ -124,18 +138,15 @@ mdcreate(Relation reln)
124138
if (fd<0 )
125139
return (-1);
126140
}
141+
142+
vfd=_fdvec_alloc ();
143+
if (vfd<0 )
144+
return (-1);
127145

128-
if (CurFd >=Nfds) {
129-
if (_fdvec_ext()==SM_FAIL)
130-
return (-1);
131-
}
132-
133-
Md_fdvec[CurFd].mdfd_vfd=fd;
134-
Md_fdvec[CurFd].mdfd_flags= (uint16)0;
135-
Md_fdvec[CurFd].mdfd_chain= (MdfdVec*)NULL;
136-
Md_fdvec[CurFd].mdfd_lstbcnt=0;
137-
138-
vfd=CurFd++;
146+
Md_fdvec[vfd].mdfd_vfd=fd;
147+
Md_fdvec[vfd].mdfd_flags= (uint16)0;
148+
Md_fdvec[vfd].mdfd_chain= (MdfdVec*)NULL;
149+
Md_fdvec[vfd].mdfd_lstbcnt=0;
139150

140151
return (vfd);
141152
}
@@ -175,7 +186,9 @@ mdunlink(Relation reln)
175186
Md_fdvec[fd].mdfd_flags= (uint16)0;
176187

177188
oldcxt=MemoryContextSwitchTo(MdCxt);
178-
for (v=&Md_fdvec[fd];v!= (MdfdVec*)NULL; ) {
189+
for (v=&Md_fdvec[fd];v!= (MdfdVec*)NULL; )
190+
{
191+
FileUnlink(v->mdfd_vfd);
179192
ov=v;
180193
v=v->mdfd_chain;
181194
if (ov!=&Md_fdvec[fd])
@@ -184,6 +197,8 @@ mdunlink(Relation reln)
184197
Md_fdvec[fd].mdfd_chain= (MdfdVec*)NULL;
185198
(void)MemoryContextSwitchTo(oldcxt);
186199

200+
_fdvec_free (fd);
201+
187202
return (SM_SUCCESS);
188203
}
189204

@@ -235,11 +250,6 @@ mdopen(Relation reln)
235250
intfd;
236251
intvfd;
237252

238-
if (CurFd >=Nfds) {
239-
if (_fdvec_ext()==SM_FAIL)
240-
return (-1);
241-
}
242-
243253
path=relpath(&(reln->rd_rel->relname.data[0]));
244254

245255
fd=FileNameOpenFile(path,O_RDWR,0600);
@@ -248,52 +258,69 @@ mdopen(Relation reln)
248258
if (fd<0)
249259
fd=FileNameOpenFile(path,O_RDWR|O_CREAT|O_EXCL,0600);
250260

251-
Md_fdvec[CurFd].mdfd_vfd=fd;
252-
Md_fdvec[CurFd].mdfd_flags= (uint16)0;
253-
Md_fdvec[CurFd].mdfd_chain= (MdfdVec*)NULL;
254-
Md_fdvec[CurFd].mdfd_lstbcnt=_mdnblocks(fd,BLCKSZ);
261+
vfd=_fdvec_alloc ();
262+
if (vfd<0 )
263+
return (-1);
264+
265+
Md_fdvec[vfd].mdfd_vfd=fd;
266+
Md_fdvec[vfd].mdfd_flags= (uint16)0;
267+
Md_fdvec[vfd].mdfd_chain= (MdfdVec*)NULL;
268+
Md_fdvec[vfd].mdfd_lstbcnt=_mdnblocks(fd,BLCKSZ);
255269

256270
#ifdefDIAGNOSTIC
257-
if (Md_fdvec[CurFd].mdfd_lstbcnt>RELSEG_SIZE)
271+
if (Md_fdvec[vfd].mdfd_lstbcnt>RELSEG_SIZE)
258272
elog(FATAL,"segment too big on relopen!");
259273
#endif
260274

261-
vfd=CurFd++;
262-
263275
return (vfd);
264276
}
265277

266278
/*
267-
* mdclose() -- Close the specified relation.
279+
* mdclose() -- Close the specified relation
280+
*
281+
*AND FREE fd vector! It may be re-used for other relation!
282+
*reln should be flushed from cache after closing !..
268283
*
269284
*Returns SM_SUCCESS or SM_FAIL with errno set as appropriate.
270285
*/
271286
int
272287
mdclose(Relationreln)
273288
{
274289
intfd;
275-
MdfdVec*v;
290+
MdfdVec*v,*ov;
291+
MemoryContextoldcxt;
276292

277293
fd=RelationGetFile(reln);
278294

279-
for (v=&Md_fdvec[fd];v!= (MdfdVec*)NULL;v=v->mdfd_chain) {
280-
281-
/* may be closed already */
282-
if (v->mdfd_vfd<0)
283-
continue;
284-
285-
/*
286-
* We sync the file descriptor so that we don't need to reopen it at
287-
* transaction commit to force changes to disk.
288-
*/
289-
290-
FileSync(v->mdfd_vfd);
291-
FileClose(v->mdfd_vfd);
292-
293-
/* mark this file descriptor as clean in our private table */
294-
v->mdfd_flags &= ~MDFD_DIRTY;
295+
oldcxt=MemoryContextSwitchTo(MdCxt);
296+
for (v=&Md_fdvec[fd];v!= (MdfdVec*)NULL; )
297+
{
298+
/* if not closed already */
299+
if (v->mdfd_vfd >=0 )
300+
{
301+
/*
302+
* We sync the file descriptor so that we don't need to reopen it at
303+
* transaction commit to force changes to disk.
304+
*/
305+
306+
FileSync(v->mdfd_vfd);
307+
FileClose(v->mdfd_vfd);
308+
309+
/* mark this file descriptor as clean in our private table */
310+
v->mdfd_flags &= ~MDFD_DIRTY;
311+
}
312+
/* Now free vector */
313+
ov=v;
314+
v=v->mdfd_chain;
315+
if (ov!=&Md_fdvec[fd])
316+
pfree(ov);
295317
}
296318

319+
(void)MemoryContextSwitchTo(oldcxt);
320+
Md_fdvec[fd].mdfd_chain= (MdfdVec*)NULL;
321+
322+
_fdvec_free (fd);
323+
297324
return (SM_SUCCESS);
298325
}
299326

@@ -605,31 +632,77 @@ mdabort()
605632
}
606633

607634
/*
608-
*_fdvec_ext() --Extend the md file descriptor vector.
635+
*_fdvec_alloc() --grab a free (or new) md file descriptor vector.
609636
*
610-
*The file descriptor vector must be large enough to hold at least
611-
*'fd' entries.
612637
*/
613638
static
614-
int_fdvec_ext()
639+
int_fdvec_alloc()
615640
{
616641
MdfdVec*nvec;
642+
intfdvec,i;
617643
MemoryContextoldcxt;
644+
645+
if (Md_Free >=0 )/* get from free list */
646+
{
647+
fdvec=Md_Free;
648+
Md_Free=Md_fdvec[fdvec].mdfd_nextFree;
649+
Assert (Md_fdvec[fdvec].mdfd_flags==MDFD_FREE );
650+
Md_fdvec[fdvec].mdfd_flags=0;
651+
if (fdvec >=CurFd )
652+
{
653+
Assert (fdvec==CurFd );
654+
CurFd++;
655+
}
656+
return (fdvec);
657+
}
618658

659+
/* Must allocate more room */
660+
661+
if (Nfds!=CurFd )
662+
elog (FATAL,"_fdvec_alloc error");
663+
619664
Nfds *=2;
620665

621666
oldcxt=MemoryContextSwitchTo(MdCxt);
622667

623668
nvec= (MdfdVec*)palloc(Nfds*sizeof(MdfdVec));
624669
memset(nvec,0,Nfds*sizeof(MdfdVec));
625-
memmove(nvec, (char*)Md_fdvec,(Nfds /2)*sizeof(MdfdVec));
670+
memmove(nvec, (char*)Md_fdvec,CurFd*sizeof(MdfdVec));
626671
pfree(Md_fdvec);
627672

628673
(void)MemoryContextSwitchTo(oldcxt);
629674

630675
Md_fdvec=nvec;
631676

632-
return (SM_SUCCESS);
677+
/* Set new free list */
678+
for (i=CurFd;i<Nfds;i++ )
679+
{
680+
Md_fdvec[i].mdfd_nextFree=i+1;
681+
Md_fdvec[i].mdfd_flags=MDFD_FREE;
682+
}
683+
Md_fdvec[Nfds-1].mdfd_nextFree=-1;
684+
Md_Free=CurFd+1;
685+
686+
fdvec=CurFd;
687+
CurFd++;
688+
Md_fdvec[fdvec].mdfd_flags=0;
689+
690+
return (fdvec);
691+
}
692+
693+
/*
694+
* _fdvec_free () -- free md file descriptor vector.
695+
*
696+
*/
697+
static
698+
void_fdvec_free (intfdvec)
699+
{
700+
701+
Assert (Md_Free<0||Md_fdvec[Md_Free].mdfd_flags==MDFD_FREE );
702+
Md_fdvec[fdvec].mdfd_nextFree=Md_Free;
703+
Md_fdvec[fdvec].mdfd_flags=MDFD_FREE;
704+
Md_Free=fdvec;
705+
633706
}
634707

635708
staticMdfdVec*

‎src/backend/storage/smgr/smgr.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.5 1996/11/27 07:25:52 vadim Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/smgr.c,v 1.6 1997/05/22 17:08:35 vadim Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -189,6 +189,13 @@ smgropen(int16 which, Relation reln)
189189
/*
190190
* smgrclose() -- Close a relation.
191191
*
192+
* NOTE: mdclose frees fd vector! It may be re-used for other relation!
193+
* reln should be flushed from cache after closing !..
194+
*Currently, smgrclose is calling by
195+
*relcache.c:RelationPurgeLocalRelation() only.
196+
*It would be nice to have smgrfree(), but because of
197+
*smgrclose is called from single place...- vadim 05/22/97
198+
*
192199
*Returns SM_SUCCESS on success, aborts on failure.
193200
*/
194201
int

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp