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

Commit642107d

Browse files
committed
Avoid unnecessary lseek() calls by cleanups in md.c. mdfd_lstbcnt was
not being consulted anywhere, so remove it and remove the _mdnblocks()calls that were used to set it. Change smgrextend interface to pass inthe target block number (ie, current file length) --- the caller alwaysknows this already, having already done smgrnblocks(), so it's silly todo it over again inside mdextend. Net result: extension of a file nowtakes one lseek(SEEK_END) and a write(), not three lseeks and a write.
1 parenta26ad8a commit642107d

File tree

6 files changed

+127
-104
lines changed

6 files changed

+127
-104
lines changed

‎src/backend/commands/sequence.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.54 2001/04/04 15:43:25 vadim Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/sequence.c,v 1.55 2001/05/10 20:38:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -569,7 +569,7 @@ read_info(char *caller, SeqTable elm, Buffer *buf)
569569
sequence_magic*sm;
570570
Form_pg_sequenceseq;
571571

572-
if (RelationGetNumberOfBlocks(elm->rel)!=1)
572+
if (elm->rel->rd_nblocks>1)
573573
elog(ERROR,"%s.%s: invalid number of blocks in sequence",
574574
elm->name,caller);
575575

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

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.109 2001/03/22 03:59:44 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.110 2001/05/10 20:38:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -173,9 +173,9 @@ ReadBufferWithBufferLock(Relation reln,
173173
boolbufferLockHeld)
174174
{
175175
BufferDesc*bufHdr;
176-
intextend;/* extending the file by one block */
177176
intstatus;
178177
boolfound;
178+
boolextend;/* extending the file by one block */
179179
boolisLocalBuf;
180180

181181
extend= (blockNum==P_NEW);
@@ -207,21 +207,13 @@ ReadBufferWithBufferLock(Relation reln,
207207
/* if it's already in the buffer pool, we're done */
208208
if (found)
209209
{
210-
211210
/*
212-
*This happens when a bogusbuffer wasreturned previously and is
213-
*floating around in the buffer pool.A routine calling this
214-
*would want this extended.
211+
*Could see found && extend if abuffer wasalready created for
212+
*the next page position, but then smgrextend failed to write
213+
*the page. Must fall through and try to extend file again.
215214
*/
216-
if (extend)
217-
{
218-
/* new buffers are zero-filled */
219-
MemSet((char*)MAKE_PTR(bufHdr->data),0,BLCKSZ);
220-
smgrextend(DEFAULT_SMGR,reln,
221-
(char*)MAKE_PTR(bufHdr->data));
222-
}
223-
returnBufferDescriptorGetBuffer(bufHdr);
224-
215+
if (!extend)
216+
returnBufferDescriptorGetBuffer(bufHdr);
225217
}
226218

227219
/*
@@ -232,17 +224,25 @@ ReadBufferWithBufferLock(Relation reln,
232224
{
233225
/* new buffers are zero-filled */
234226
MemSet((char*)MAKE_PTR(bufHdr->data),0,BLCKSZ);
235-
status=smgrextend(DEFAULT_SMGR,reln,
227+
status=smgrextend(DEFAULT_SMGR,reln,bufHdr->tag.blockNum,
236228
(char*)MAKE_PTR(bufHdr->data));
237229
}
238230
else
239231
{
240-
status=smgrread(DEFAULT_SMGR,reln,blockNum,
232+
status=smgrread(DEFAULT_SMGR,reln,bufHdr->tag.blockNum,
241233
(char*)MAKE_PTR(bufHdr->data));
242234
}
243235

244236
if (isLocalBuf)
237+
{
238+
/* No shared buffer state to update... */
239+
if (status==SM_FAIL)
240+
{
241+
bufHdr->flags |=BM_IO_ERROR;
242+
returnInvalidBuffer;
243+
}
245244
returnBufferDescriptorGetBuffer(bufHdr);
245+
}
246246

247247
/* lock buffer manager again to update IO IN PROGRESS */
248248
SpinAcquire(BufMgrLock);
@@ -302,13 +302,11 @@ BufferAlloc(Relation reln,
302302
*buf2;
303303
BufferTagnewTag;/* identity of requested block */
304304
boolinProgress;/* buffer undergoing IO */
305-
boolnewblock= FALSE;
306305

307306
/* create a new tag so we can lookup the buffer */
308307
/* assume that the relation is already open */
309308
if (blockNum==P_NEW)
310309
{
311-
newblock= TRUE;
312310
blockNum=smgrnblocks(DEFAULT_SMGR,reln);
313311
}
314312

@@ -1102,7 +1100,8 @@ BufferReplace(BufferDesc *bufHdr)
11021100

11031101
/*
11041102
* RelationGetNumberOfBlocks
1105-
*Returns the buffer descriptor associated with a page in a relation.
1103+
*Determines the current number of pages in the relation.
1104+
*Side effect: relation->rd_nblocks is updated.
11061105
*
11071106
* Note:
11081107
*XXX may fail for huge relations.
@@ -1112,9 +1111,16 @@ BufferReplace(BufferDesc *bufHdr)
11121111
BlockNumber
11131112
RelationGetNumberOfBlocks(Relationrelation)
11141113
{
1115-
return ((relation->rd_myxactonly) ?relation->rd_nblocks :
1116-
((relation->rd_rel->relkind==RELKIND_VIEW) ?0 :
1117-
smgrnblocks(DEFAULT_SMGR,relation)));
1114+
/*
1115+
* relation->rd_nblocks should be accurate already if the relation
1116+
* is myxactonly. (XXX how safe is that really?) Don't call smgr
1117+
* on a view, either.
1118+
*/
1119+
if (relation->rd_rel->relkind==RELKIND_VIEW)
1120+
relation->rd_nblocks=0;
1121+
elseif (!relation->rd_myxactonly)
1122+
relation->rd_nblocks=smgrnblocks(DEFAULT_SMGR,relation);
1123+
returnrelation->rd_nblocks;
11181124
}
11191125

11201126
/* ---------------------------------------------------------------------

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

Lines changed: 75 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.83 2001/04/02 23:20:24 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.84 2001/05/1020:38:49 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -54,10 +54,9 @@ typedef struct _MdfdVec
5454
intmdfd_flags;/* fd status flags */
5555

5656
/* these are the assigned bits in mdfd_flags: */
57-
#defineMDFD_FREE(1 << 0)/* unused entry */
57+
#defineMDFD_FREE(1 << 0)/* unused entry */
5858

59-
intmdfd_lstbcnt;/* most recent block count */
60-
intmdfd_nextFree;/* next free vector */
59+
intmdfd_nextFree;/* link to next freelist member, if free */
6160
#ifndefLET_OS_MANAGE_FILESIZE
6261
struct_MdfdVec*mdfd_chain;/* for large relations */
6362
#endif
@@ -164,7 +163,6 @@ mdcreate(Relation reln)
164163

165164
Md_fdvec[vfd].mdfd_vfd=fd;
166165
Md_fdvec[vfd].mdfd_flags= (uint16)0;
167-
Md_fdvec[vfd].mdfd_lstbcnt=0;
168166
#ifndefLET_OS_MANAGE_FILESIZE
169167
Md_fdvec[vfd].mdfd_chain= (MdfdVec*)NULL;
170168
#endif
@@ -225,52 +223,69 @@ mdunlink(RelFileNode rnode)
225223
/*
226224
*mdextend() -- Add a block to the specified relation.
227225
*
226+
*The semantics are basically the same as mdwrite(): write at the
227+
*specified position. However, we are expecting to extend the
228+
*relation (ie, blocknum is the current EOF), and so in case of
229+
*failure we clean up by truncating.
230+
*
228231
*This routine returns SM_FAIL or SM_SUCCESS, with errno set as
229232
*appropriate.
233+
*
234+
* Note: this routine used to call mdnblocks() to get the block position
235+
* to write at, but that's pretty silly since the caller needs to know where
236+
* the block will be written, and accordingly must have done mdnblocks()
237+
* already. Might as well pass in the position and save a seek.
230238
*/
231239
int
232-
mdextend(Relationreln,char*buffer)
240+
mdextend(Relationreln,BlockNumberblocknum,char*buffer)
233241
{
234-
longpos,
235-
nbytes;
236-
intnblocks;
242+
longseekpos;
243+
intnbytes;
237244
MdfdVec*v;
238245

239-
nblocks=mdnblocks(reln);
240-
v=_mdfd_getseg(reln,nblocks);
246+
v=_mdfd_getseg(reln,blocknum);
241247

242-
if ((pos=FileSeek(v->mdfd_vfd,0L,SEEK_END))<0)
243-
returnSM_FAIL;
248+
#ifndefLET_OS_MANAGE_FILESIZE
249+
seekpos= (long) (BLCKSZ* (blocknum %RELSEG_SIZE));
250+
#ifdefDIAGNOSTIC
251+
if (seekpos >=BLCKSZ*RELSEG_SIZE)
252+
elog(FATAL,"seekpos too big!");
253+
#endif
254+
#else
255+
seekpos= (long) (BLCKSZ* (blocknum));
256+
#endif
244257

245-
if (pos %BLCKSZ!=0)/* the last block is incomplete */
246-
{
247-
pos-=pos %BLCKSZ;
248-
if (FileSeek(v->mdfd_vfd,pos,SEEK_SET)<0)
249-
returnSM_FAIL;
250-
}
258+
/*
259+
* Note: because caller obtained blocknum by calling mdnblocks, which
260+
* did a seek(SEEK_END), this seek is often redundant and will be
261+
* optimized away by fd.c. It's not redundant, however, if there is a
262+
* partial page at the end of the file. In that case we want to try to
263+
* overwrite the partial page with a full page. It's also not redundant
264+
* if bufmgr.c had to dump another buffer of the same file to make room
265+
* for the new page's buffer.
266+
*/
267+
if (FileSeek(v->mdfd_vfd,seekpos,SEEK_SET)!=seekpos)
268+
returnSM_FAIL;
251269

252270
if ((nbytes=FileWrite(v->mdfd_vfd,buffer,BLCKSZ))!=BLCKSZ)
253271
{
254272
if (nbytes>0)
255273
{
256-
FileTruncate(v->mdfd_vfd,pos);
257-
FileSeek(v->mdfd_vfd,pos,SEEK_SET);
274+
intsave_errno=errno;
275+
276+
/* Remove the partially-written page */
277+
FileTruncate(v->mdfd_vfd,seekpos);
278+
FileSeek(v->mdfd_vfd,seekpos,SEEK_SET);
279+
errno=save_errno;
258280
}
259281
returnSM_FAIL;
260282
}
261283

262-
/* try to keep the last block count current, though it's just a hint */
263284
#ifndefLET_OS_MANAGE_FILESIZE
264-
if ((v->mdfd_lstbcnt= (++nblocks %RELSEG_SIZE))==0)
265-
v->mdfd_lstbcnt=RELSEG_SIZE;
266-
267285
#ifdefDIAGNOSTIC
268-
if (_mdnblocks(v->mdfd_vfd,BLCKSZ)>RELSEG_SIZE
269-
||v->mdfd_lstbcnt>RELSEG_SIZE)
286+
if (_mdnblocks(v->mdfd_vfd,BLCKSZ)>RELSEG_SIZE)
270287
elog(FATAL,"segment too big!");
271288
#endif
272-
#else
273-
v->mdfd_lstbcnt=++nblocks;
274289
#endif
275290

276291
returnSM_SUCCESS;
@@ -319,12 +334,11 @@ mdopen(Relation reln)
319334

320335
Md_fdvec[vfd].mdfd_vfd=fd;
321336
Md_fdvec[vfd].mdfd_flags= (uint16)0;
322-
Md_fdvec[vfd].mdfd_lstbcnt=_mdnblocks(fd,BLCKSZ);
323337
#ifndefLET_OS_MANAGE_FILESIZE
324338
Md_fdvec[vfd].mdfd_chain= (MdfdVec*)NULL;
325339

326340
#ifdefDIAGNOSTIC
327-
if (Md_fdvec[vfd].mdfd_lstbcnt>RELSEG_SIZE)
341+
if (_mdnblocks(fd,BLCKSZ)>RELSEG_SIZE)
328342
elog(FATAL,"segment too big on relopen!");
329343
#endif
330344
#endif
@@ -440,9 +454,12 @@ mdread(Relation reln, BlockNumber blocknum, char *buffer)
440454
status=SM_SUCCESS;
441455
if ((nbytes=FileRead(v->mdfd_vfd,buffer,BLCKSZ))!=BLCKSZ)
442456
{
443-
if (nbytes==0)
444-
MemSet(buffer,0,BLCKSZ);
445-
elseif (blocknum==0&&nbytes>0&&mdnblocks(reln)==0)
457+
/*
458+
* If we are at EOF, return zeroes without complaining.
459+
* (XXX Is this still necessary/a good idea??)
460+
*/
461+
if (nbytes==0||
462+
(nbytes>0&&mdnblocks(reln)==blocknum))
446463
MemSet(buffer,0,BLCKSZ);
447464
else
448465
status=SM_FAIL;
@@ -459,7 +476,6 @@ mdread(Relation reln, BlockNumber blocknum, char *buffer)
459476
int
460477
mdwrite(Relationreln,BlockNumberblocknum,char*buffer)
461478
{
462-
intstatus;
463479
longseekpos;
464480
MdfdVec*v;
465481

@@ -478,11 +494,10 @@ mdwrite(Relation reln, BlockNumber blocknum, char *buffer)
478494
if (FileSeek(v->mdfd_vfd,seekpos,SEEK_SET)!=seekpos)
479495
returnSM_FAIL;
480496

481-
status=SM_SUCCESS;
482497
if (FileWrite(v->mdfd_vfd,buffer,BLCKSZ)!=BLCKSZ)
483-
status=SM_FAIL;
498+
returnSM_FAIL;
484499

485-
returnstatus;
500+
returnSM_SUCCESS;
486501
}
487502

488503
/*
@@ -662,31 +677,29 @@ mdnblocks(Relation reln)
662677
nblocks=_mdnblocks(v->mdfd_vfd,BLCKSZ);
663678
if (nblocks>RELSEG_SIZE)
664679
elog(FATAL,"segment too big in mdnblocks!");
665-
v->mdfd_lstbcnt=nblocks;
666-
if (nblocks==RELSEG_SIZE)
667-
{
668-
segno++;
680+
if (nblocks<RELSEG_SIZE)
681+
return (segno*RELSEG_SIZE)+nblocks;
682+
/*
683+
* If segment is exactly RELSEG_SIZE, advance to next one.
684+
*/
685+
segno++;
669686

687+
if (v->mdfd_chain== (MdfdVec*)NULL)
688+
{
689+
/*
690+
* Because we pass O_CREAT, we will create the next
691+
* segment (with zero length) immediately, if the last
692+
* segment is of length REL_SEGSIZE. This is unnecessary
693+
* but harmless, and testing for the case would take more
694+
* cycles than it seems worth.
695+
*/
696+
v->mdfd_chain=_mdfd_openseg(reln,segno,O_CREAT);
670697
if (v->mdfd_chain== (MdfdVec*)NULL)
671-
{
672-
673-
/*
674-
* Because we pass O_CREAT, we will create the next
675-
* segment (with zero length) immediately, if the last
676-
* segment is of length REL_SEGSIZE. This is unnecessary
677-
* but harmless, and testing for the case would take more
678-
* cycles than it seems worth.
679-
*/
680-
v->mdfd_chain=_mdfd_openseg(reln,segno,O_CREAT);
681-
if (v->mdfd_chain== (MdfdVec*)NULL)
682-
elog(ERROR,"cannot count blocks for %s -- open failed: %m",
683-
RelationGetRelationName(reln));
684-
}
685-
686-
v=v->mdfd_chain;
698+
elog(ERROR,"cannot count blocks for %s -- open failed: %m",
699+
RelationGetRelationName(reln));
687700
}
688-
else
689-
return (segno*RELSEG_SIZE)+nblocks;
701+
702+
v=v->mdfd_chain;
690703
}
691704
#else
692705
return_mdnblocks(v->mdfd_vfd,BLCKSZ);
@@ -761,7 +774,6 @@ mdtruncate(Relation reln, int nblocks)
761774

762775
if (FileTruncate(v->mdfd_vfd,lastsegblocks*BLCKSZ)<0)
763776
return-1;
764-
v->mdfd_lstbcnt=lastsegblocks;
765777
v=v->mdfd_chain;
766778
ov->mdfd_chain= (MdfdVec*)NULL;
767779
}
@@ -779,7 +791,6 @@ mdtruncate(Relation reln, int nblocks)
779791
#else
780792
if (FileTruncate(v->mdfd_vfd,nblocks*BLCKSZ)<0)
781793
return-1;
782-
v->mdfd_lstbcnt=nblocks;
783794
#endif
784795

785796
returnnblocks;
@@ -958,13 +969,12 @@ _mdfd_openseg(Relation reln, int segno, int oflags)
958969
/* fill the entry */
959970
v->mdfd_vfd=fd;
960971
v->mdfd_flags= (uint16)0;
961-
v->mdfd_lstbcnt=_mdnblocks(fd,BLCKSZ);
962972
#ifndefLET_OS_MANAGE_FILESIZE
963973
v->mdfd_chain= (MdfdVec*)NULL;
964974

965975
#ifdefDIAGNOSTIC
966-
if (v->mdfd_lstbcnt>RELSEG_SIZE)
967-
elog(FATAL,"segment too big onopen!");
976+
if (_mdnblocks(fd,BLCKSZ)>RELSEG_SIZE)
977+
elog(FATAL,"segment too big onopenseg!");
968978
#endif
969979
#endif
970980

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp