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

Commit403bdc4

Browse files
committed
Back-patch fix for 'Sorcerer's Apprentice' syndrome wherein md.c would
create a vast quantity of zero-length files if asked to access a blocknumber far beyond the actual end of a relation.
1 parentaa09aaa commit403bdc4

File tree

1 file changed

+42
-14
lines changed
  • src/backend/storage/smgr

1 file changed

+42
-14
lines changed

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

Lines changed: 42 additions & 14 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.68 2000/05/25 23:30:20 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.68.2.1 2000/09/23 22:11:41 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -130,6 +130,7 @@ mdcreate(Relation reln)
130130
char*path;
131131

132132
Assert(reln->rd_unlinked&&reln->rd_fd<0);
133+
133134
path=relpath(RelationGetPhysicalRelationName(reln));
134135
#ifndef__CYGWIN32__
135136
fd=FileNameOpenFile(path,O_RDWR |O_CREAT |O_EXCL,0600);
@@ -138,19 +139,21 @@ mdcreate(Relation reln)
138139
#endif
139140

140141
/*
141-
* During bootstrap processing, we skip that check, because pg_time,
142-
* pg_variable, and pg_log get created before their .bki file entries
143-
* are processed.
144-
*
145-
* For cataloged relations,pg_class is guaranteed to have an unique
142+
* For cataloged relations, pg_class is guaranteed to have a unique
146143
* record with the same relname by the unique index. So we are able to
147-
* reuse existent files for newcatloged relations. Currently we reuse
144+
* reuse existent files for newcataloged relations. Currently we reuse
148145
* them in the following cases. 1. they are empty. 2. they are used
149146
* for Index relations and their size == BLCKSZ * 2.
147+
*
148+
* During bootstrap processing, we skip that check, because pg_time,
149+
* pg_variable, and pg_log get created before their .bki file entries
150+
* are processed.
150151
*/
151152

152153
if (fd<0)
153154
{
155+
intsave_errno=errno;
156+
154157
if (!IsBootstrapProcessingMode()&&
155158
reln->rd_rel->relkind==RELKIND_UNCATALOGED)
156159
return-1;
@@ -161,11 +164,15 @@ mdcreate(Relation reln)
161164
fd=FileNameOpenFile(path,O_RDWR |O_BINARY,0600);
162165
#endif
163166
if (fd<0)
167+
{
168+
/* be sure to return the error reported by create, not open */
169+
errno=save_errno;
164170
return-1;
171+
}
165172
if (!IsBootstrapProcessingMode())
166173
{
167174
boolreuse= false;
168-
intlen=FileSeek(fd,0L,SEEK_END);
175+
longlen=FileSeek(fd,0L,SEEK_END);
169176

170177
if (len==0)
171178
reuse= true;
@@ -175,9 +182,12 @@ mdcreate(Relation reln)
175182
if (!reuse)
176183
{
177184
FileClose(fd);
185+
/* be sure to return the error reported by create */
186+
errno=save_errno;
178187
return-1;
179188
}
180189
}
190+
errno=0;
181191
}
182192
reln->rd_unlinked= false;
183193

@@ -733,9 +743,16 @@ mdnblocks(Relation reln)
733743

734744
if (v->mdfd_chain== (MdfdVec*)NULL)
735745
{
746+
/*
747+
* Because we pass O_CREAT, we will create the next segment
748+
* (with zero length) immediately, if the last segment is of
749+
* length REL_SEGSIZE. This is unnecessary but harmless, and
750+
* testing for the case would take more cycles than it seems
751+
* worth.
752+
*/
736753
v->mdfd_chain=_mdfd_openseg(reln,segno,O_CREAT);
737754
if (v->mdfd_chain== (MdfdVec*)NULL)
738-
elog(ERROR,"cannot count blocks for %s -- open failed",
755+
elog(ERROR,"cannot count blocks for %s -- open failed: %m",
739756
RelationGetRelationName(reln));
740757
}
741758

@@ -1075,11 +1092,20 @@ _mdfd_getseg(Relation reln, int blkno)
10751092

10761093
if (v->mdfd_chain== (MdfdVec*)NULL)
10771094
{
1078-
v->mdfd_chain=_mdfd_openseg(reln,i,O_CREAT);
1095+
/*
1096+
* We will create the next segment only if the target block
1097+
* is within it. This prevents Sorcerer's Apprentice syndrome
1098+
* if a bug at higher levels causes us to be handed a ridiculously
1099+
* large blkno --- otherwise we could create many thousands of
1100+
* empty segment files before reaching the "target" block. We
1101+
* should never need to create more than one new segment per call,
1102+
* so this restriction seems reasonable.
1103+
*/
1104+
v->mdfd_chain=_mdfd_openseg(reln,i, (segno==1) ?O_CREAT :0);
10791105

10801106
if (v->mdfd_chain== (MdfdVec*)NULL)
1081-
elog(ERROR,"cannot open segment %d of relation %s",
1082-
i,RelationGetRelationName(reln));
1107+
elog(ERROR,"cannot open segment %d of relation %s (target block %d): %m",
1108+
i,RelationGetRelationName(reln),blkno);
10831109
}
10841110
v=v->mdfd_chain;
10851111
}
@@ -1097,8 +1123,10 @@ _mdfd_getseg(Relation reln, int blkno)
10971123
* "blind" with no Relation struct. We assume that we are not likely to
10981124
* touch the same relation again soon, so we do not create an FD entry for
10991125
* the relation --- we just open a kernel file descriptor which will be
1100-
* used and promptly closed. The return value is the kernel descriptor,
1101-
* or -1 on failure.
1126+
* used and promptly closed. We also assume that the target block already
1127+
* exists, ie, we need not extend the relation.
1128+
*
1129+
* The return value is the kernel descriptor, or -1 on failure.
11021130
*/
11031131

11041132
staticint

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp