mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
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.
This commit is contained in:
parent
b779ea8a9a
commit
04d9f4dab4
src/bin/pg_dump
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.185 2010/05/15 21:41:16 tgl Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.186 2010/06/28 02:07:02 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -1755,6 +1755,11 @@ _discoverArchiveFormat(ArchiveHandle *AH)
|
|||||||
|
|
||||||
if (strncmp(sig, "PGDMP", 5) == 0)
|
if (strncmp(sig, "PGDMP", 5) == 0)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Finish reading (most of) a custom-format header.
|
||||||
|
*
|
||||||
|
* NB: this code must agree with ReadHead().
|
||||||
|
*/
|
||||||
AH->vmaj = fgetc(fh);
|
AH->vmaj = fgetc(fh);
|
||||||
AH->vmin = fgetc(fh);
|
AH->vmin = fgetc(fh);
|
||||||
|
|
||||||
@ -2981,7 +2986,12 @@ ReadHead(ArchiveHandle *AH)
|
|||||||
int fmt;
|
int fmt;
|
||||||
struct tm crtm;
|
struct tm crtm;
|
||||||
|
|
||||||
/* If we haven't already read the header... */
|
/*
|
||||||
|
* If we haven't already read the header, do so.
|
||||||
|
*
|
||||||
|
* NB: this code must agree with _discoverArchiveFormat(). Maybe find
|
||||||
|
* a way to unify the cases?
|
||||||
|
*/
|
||||||
if (!AH->readHeader)
|
if (!AH->readHeader)
|
||||||
{
|
{
|
||||||
if ((*AH->ReadBufPtr) (AH, tmpMag, 5) != 5)
|
if ((*AH->ReadBufPtr) (AH, tmpMag, 5) != 5)
|
||||||
@ -3000,7 +3010,6 @@ ReadHead(ArchiveHandle *AH)
|
|||||||
|
|
||||||
AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
|
AH->version = ((AH->vmaj * 256 + AH->vmin) * 256 + AH->vrev) * 256 + 0;
|
||||||
|
|
||||||
|
|
||||||
if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
|
if (AH->version < K_VERS_1_0 || AH->version > K_VERS_MAX)
|
||||||
die_horribly(AH, modulename, "unsupported version (%d.%d) in file header\n",
|
die_horribly(AH, modulename, "unsupported version (%d.%d) in file header\n",
|
||||||
AH->vmaj, AH->vmin);
|
AH->vmaj, AH->vmin);
|
||||||
@ -3068,27 +3077,37 @@ ReadHead(ArchiveHandle *AH)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* checkSeek
|
* checkSeek
|
||||||
* check to see if fseek can be performed.
|
* check to see if ftell/fseek can be performed.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
checkSeek(FILE *fp)
|
checkSeek(FILE *fp)
|
||||||
{
|
{
|
||||||
if (fseeko(fp, 0, SEEK_CUR) != 0)
|
pgoff_t tpos;
|
||||||
return false;
|
|
||||||
else if (sizeof(pgoff_t) > sizeof(long))
|
/*
|
||||||
{
|
* If pgoff_t is wider than long, we must have "real" fseeko and not
|
||||||
/*
|
* an emulation using fseek. Otherwise report no seek capability.
|
||||||
* At this point, pgoff_t is too large for long, so we return based on
|
*/
|
||||||
* whether an pgoff_t version of fseek is available.
|
#ifndef HAVE_FSEEKO
|
||||||
*/
|
if (sizeof(pgoff_t) > sizeof(long))
|
||||||
#ifdef HAVE_FSEEKO
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
else
|
/* Check that ftello works on this file */
|
||||||
return true;
|
errno = 0;
|
||||||
|
tpos = ftello(fp);
|
||||||
|
if (errno)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that fseeko(SEEK_SET) works, too. NB: we used to try to test
|
||||||
|
* this with fseeko(fp, 0, SEEK_CUR). But some platforms treat that as a
|
||||||
|
* successful no-op even on files that are otherwise unseekable.
|
||||||
|
*/
|
||||||
|
if (fseeko(fp, tpos, SEEK_SET) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.45 2010/06/27 19:07:24 tgl Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_custom.c,v 1.46 2010/06/28 02:07:02 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -835,9 +835,10 @@ _CloseArchive(ArchiveHandle *AH)
|
|||||||
WriteDataChunks(AH);
|
WriteDataChunks(AH);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is not an essential operation - it is really only needed if we
|
* If possible, re-write the TOC in order to update the data offset
|
||||||
* expect to be doing seeks to read the data back - it may be ok to
|
* information. This is not essential, as pg_restore can cope in
|
||||||
* just use the existing self-consistent block formatting.
|
* most cases without it; but it can make pg_restore significantly
|
||||||
|
* faster in some situations (especially parallel restore).
|
||||||
*/
|
*/
|
||||||
if (ctx->hasSeek &&
|
if (ctx->hasSeek &&
|
||||||
fseeko(AH->FH, tpos, SEEK_SET) == 0)
|
fseeko(AH->FH, tpos, SEEK_SET) == 0)
|
||||||
@ -914,7 +915,8 @@ _getFilePos(ArchiveHandle *AH, lclContext *ctx)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Prior to 1.7 (pg7.3) we relied on the internally maintained
|
* Prior to 1.7 (pg7.3) we relied on the internally maintained
|
||||||
* pointer. Now we rely on pgoff_t always. pos = ctx->filePos;
|
* pointer. Now we rely on ftello() always, unless the file has
|
||||||
|
* been found to not support it.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user