Skip to content

Commit 04d9f4d

Browse files
committed
Improve pg_dump's checkSeek() function to verify the functioning of ftello
as well as fseeko, and to not assume that fseeko(fp, 0, SEEK_CUR) proves anything. Also improve some related comments. Per my observation that the SEEK_CUR test didn't actually work on some platforms, and subsequent discussion with Robert Haas. Back-patch to 8.4. In earlier releases it's not that important whether we get the hasSeek test right, but with parallel restore it matters.
1 parent b779ea8 commit 04d9f4d

File tree

2 files changed

+44
-23
lines changed

2 files changed

+44
-23
lines changed

src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.185 2010/05/15 21:41:16 tgl Exp $
18+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.186 2010/06/28 02:07:02 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1755,6 +1755,11 @@ _discoverArchiveFormat(ArchiveHandle *AH)
17551755

17561756
if (strncmp(sig, "PGDMP", 5) == 0)
17571757
{
1758+
/*
1759+
* Finish reading (most of) a custom-format header.
1760+
*
1761+
* NB: this code must agree with ReadHead().
1762+
*/
17581763
AH->vmaj = fgetc(fh);
17591764
AH->vmin = fgetc(fh);
17601765

@@ -2981,7 +2986,12 @@ ReadHead(ArchiveHandle *AH)
29812986
int fmt;
29822987
struct tm crtm;
29832988

2984-
/* If we haven't already read the header... */
2989+
/*
2990+
* If we haven't already read the header, do so.
2991+
*
2992+
* NB: this code must agree with _discoverArchiveFormat(). Maybe find
2993+
* a way to unify the cases?
2994+
*/
29852995
if (!AH->readHeader)
29862996
{
29872997
if ((*AH->ReadBufPtr) (AH, tmpMag, 5) != 5)
@@ -3000,7 +3010,6 @@ ReadHead(ArchiveHandle *AH)
30003010

30013011
AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
30023012

3003-
30043013
if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
30053014
die_horribly(AH, modulename, "unsupported version (%d.%d) in file header\n",
30063015
AH->vmaj, AH->vmin);
@@ -3068,27 +3077,37 @@ ReadHead(ArchiveHandle *AH)
30683077

30693078
/*
30703079
* checkSeek
3071-
* check to see if fseek can be performed.
3080+
* check to see if ftell/fseek can be performed.
30723081
*/
30733082
bool
30743083
checkSeek(FILE *fp)
30753084
{
3076-
if (fseeko(fp, 0, SEEK_CUR) != 0)
3077-
return false;
3078-
else if (sizeof(pgoff_t) > sizeof(long))
3079-
{
3080-
/*
3081-
* At this point, pgoff_t is too large for long, so we return based on
3082-
* whether an pgoff_t version of fseek is available.
3083-
*/
3084-
#ifdef HAVE_FSEEKO
3085-
return true;
3086-
#else
3085+
pgoff_t tpos;
3086+
3087+
/*
3088+
* If pgoff_t is wider than long, we must have "real" fseeko and not
3089+
* an emulation using fseek. Otherwise report no seek capability.
3090+
*/
3091+
#ifndef HAVE_FSEEKO
3092+
if (sizeof(pgoff_t) > sizeof(long))
30873093
return false;
30883094
#endif
3089-
}
3090-
else
3091-
return true;
3095+
3096+
/* Check that ftello works on this file */
3097+
errno = 0;
3098+
tpos = ftello(fp);
3099+
if (errno)
3100+
return false;
3101+
3102+
/*
3103+
* Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
3104+
* this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
3105+
* successful no-op even on files that are otherwise unseekable.
3106+
*/
3107+
if (fseeko(fp, tpos, SEEK_SET) != 0)
3108+
return false;
3109+
3110+
return true;
30923111
}
30933112

30943113

src/bin/pg_dump/pg_backup_custom.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*
2020
*
2121
* IDENTIFICATION
22-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.45 2010/06/27 19:07:24 tgl Exp $
22+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.46 2010/06/28 02:07:02 tgl Exp $
2323
*
2424
*-------------------------------------------------------------------------
2525
*/
@@ -835,9 +835,10 @@ _CloseArchive(ArchiveHandle *AH)
835835
WriteDataChunks(AH);
836836

837837
/*
838-
* This is not an essential operation - it is really only needed if we
839-
* expect to be doing seeks to read the data back - it may be ok to
840-
* just use the existing self-consistent block formatting.
838+
* If possible, re-write the TOC in order to update the data offset
839+
* information. This is not essential, as pg_restore can cope in
840+
* most cases without it; but it can make pg_restore significantly
841+
* faster in some situations (especially parallel restore).
841842
*/
842843
if (ctx->hasSeek &&
843844
fseeko(AH->FH, tpos, SEEK_SET) == 0)
@@ -914,7 +915,8 @@ _getFilePos(ArchiveHandle *AH, lclContext *ctx)
914915

915916
/*
916917
* Prior to 1.7 (pg7.3) we relied on the internally maintained
917-
* pointer. Now we rely on pgoff_t always. pos = ctx->filePos;
918+
* pointer. Now we rely on ftello() always, unless the file has
919+
* been found to not support it.
918920
*/
919921
}
920922
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy