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

Commitf3e5d86

Browse files
committed
Prevent creating a boatload of empty segments when md.c is asked to
access a ridiculously large block number within a relation.
1 parentb54faa1 commitf3e5d86

File tree

1 file changed

+25
-7
lines changed
  • src/backend/storage/smgr

1 file changed

+25
-7
lines changed

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

Lines changed: 25 additions & 7 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.72 2000/06/28 03:32:14 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/storage/smgr/md.c,v 1.73 2000/07/10 04:32:00 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -714,9 +714,16 @@ mdnblocks(Relation reln)
714714

715715
if (v->mdfd_chain== (MdfdVec*)NULL)
716716
{
717+
/*
718+
* Because we pass O_CREAT, we will create the next segment
719+
* (with zero length) immediately, if the last segment is of
720+
* length REL_SEGSIZE. This is unnecessary but harmless, and
721+
* testing for the case would take more cycles than it seems
722+
* worth.
723+
*/
717724
v->mdfd_chain=_mdfd_openseg(reln,segno,O_CREAT);
718725
if (v->mdfd_chain== (MdfdVec*)NULL)
719-
elog(ERROR,"cannot count blocks for %s -- open failed",
726+
elog(ERROR,"cannot count blocks for %s -- open failed: %m",
720727
RelationGetRelationName(reln));
721728
}
722729

@@ -1038,11 +1045,20 @@ _mdfd_getseg(Relation reln, int blkno)
10381045

10391046
if (v->mdfd_chain== (MdfdVec*)NULL)
10401047
{
1041-
v->mdfd_chain=_mdfd_openseg(reln,i,O_CREAT);
1048+
/*
1049+
* We will create the next segment only if the target block
1050+
* is within it. This prevents Sorcerer's Apprentice syndrome
1051+
* if a bug at higher levels causes us to be handed a ridiculously
1052+
* large blkno --- otherwise we could create many thousands of
1053+
* empty segment files before reaching the "target" block. We
1054+
* should never need to create more than one new segment per call,
1055+
* so this restriction seems reasonable.
1056+
*/
1057+
v->mdfd_chain=_mdfd_openseg(reln,i, (segno==1) ?O_CREAT :0);
10421058

10431059
if (v->mdfd_chain== (MdfdVec*)NULL)
1044-
elog(ERROR,"cannot open segment %d of relation %s",
1045-
i,RelationGetRelationName(reln));
1060+
elog(ERROR,"cannot open segment %d of relation %s (target block %d): %m",
1061+
i,RelationGetRelationName(reln),blkno);
10461062
}
10471063
v=v->mdfd_chain;
10481064
}
@@ -1060,8 +1076,10 @@ _mdfd_getseg(Relation reln, int blkno)
10601076
* "blind" with no Relation struct. We assume that we are not likely to
10611077
* touch the same relation again soon, so we do not create an FD entry for
10621078
* the relation --- we just open a kernel file descriptor which will be
1063-
* used and promptly closed. The return value is the kernel descriptor,
1064-
* or -1 on failure.
1079+
* used and promptly closed. We also assume that the target block already
1080+
* exists, ie, we need not extend the relation.
1081+
*
1082+
* The return value is the kernel descriptor, or -1 on failure.
10651083
*/
10661084

10671085
staticint

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp