diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2018-05-02 17:23:13 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2018-05-02 17:23:13 +0300 |
commit | 445e31bdc749e56376993232e5c2cc4931161322 (patch) | |
tree | 4ca285864a772a64328fed930ec8f20964d15565 /src/backend | |
parent | 7f6570b3a8d1aa8e90ab0868eefa5a4236b0ada3 (diff) | |
download | postgresql-445e31bdc749e56376993232e5c2cc4931161322.tar.gz postgresql-445e31bdc749e56376993232e5c2cc4931161322.zip |
Fix some sloppiness in the new BufFileSize() and BufFileAppend() functions.
There were three related issues:
* BufFileAppend() incorrectly reset the seek position on the 'source' file.
As a result, if you had called BufFileRead() on the file before calling
BufFileAppend(), it got confused, and subsequent calls would read/write
at wrong position.
* BufFileSize() did not work with files opened with BufFileOpenShared().
* FileGetSize() only worked on temporary files.
To fix, change the way BufFileSize() works so that it works on shared
files. Remove FileGetSize() altogether, as it's no longer needed. Remove
buffilesize from TapeShare struct, as the leader process can simply call
BufFileSize() to get the tape's size, there's no need to pass it through
shared memory anymore.
Discussion: https://www.postgresql.org/message-id/CAH2-WznEDYe_NZXxmnOfsoV54oFkTdMy7YLE2NPBLuttO96vTQ@mail.gmail.com
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/storage/file/buffile.c | 18 | ||||
-rw-r--r-- | src/backend/storage/file/fd.c | 10 | ||||
-rw-r--r-- | src/backend/utils/sort/logtape.c | 11 | ||||
-rw-r--r-- | src/backend/utils/sort/tuplesort.c | 1 |
4 files changed, 22 insertions, 18 deletions
diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c index 9cdddba510e..d8a18dd3dcb 100644 --- a/src/backend/storage/file/buffile.c +++ b/src/backend/storage/file/buffile.c @@ -802,14 +802,24 @@ BufFileTellBlock(BufFile *file) #endif /* - * Return the current file size. Counts any holes left behind by - * BufFileViewAppend as part of the size. + * Return the current file size. + * + * Counts any holes left behind by BufFileAppend as part of the size. + * Returns -1 on error. */ off_t BufFileSize(BufFile *file) { + off_t lastFileSize; + + /* Get the size of the last physical file by seeking to end. */ + lastFileSize = FileSeek(file->files[file->numFiles - 1], 0, SEEK_END); + if (lastFileSize < 0) + return -1; + file->offsets[file->numFiles - 1] = lastFileSize; + return ((file->numFiles - 1) * (off_t) MAX_PHYSICAL_FILESIZE) + - FileGetSize(file->files[file->numFiles - 1]); + lastFileSize; } /* @@ -853,7 +863,7 @@ BufFileAppend(BufFile *target, BufFile *source) for (i = target->numFiles; i < newNumFiles; i++) { target->files[i] = source->files[i - target->numFiles]; - target->offsets[i] = 0L; + target->offsets[i] = source->offsets[i - target->numFiles]; } target->numFiles = newNumFiles; diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index afce5dadc09..441f18dcf56 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -2256,16 +2256,6 @@ FileGetRawMode(File file) } /* - * FileGetSize - returns the size of file - */ -off_t -FileGetSize(File file) -{ - Assert(FileIsValid(file)); - return VfdCache[file].fileSize; -} - -/* * Make room for another allocatedDescs[] array entry if needed and possible. * Returns true if an array element is available. */ diff --git a/src/backend/utils/sort/logtape.c b/src/backend/utils/sort/logtape.c index 19eb2fddcad..a0d6c75c37e 100644 --- a/src/backend/utils/sort/logtape.c +++ b/src/backend/utils/sort/logtape.c @@ -426,11 +426,17 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, { char filename[MAXPGPATH]; BufFile *file; + off_t filesize; lt = <s->tapes[i]; pg_itoa(i, filename); file = BufFileOpenShared(fileset, filename); + filesize = BufFileSize(file); + if (filesize < 0) + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not determine size of temporary file \"%s\"", filename))); /* * Stash first BufFile, and concatenate subsequent BufFiles to that. @@ -447,8 +453,8 @@ ltsConcatWorkerTapes(LogicalTapeSet *lts, TapeShare *shared, lt->offsetBlockNumber = BufFileAppend(lts->pfile, file); } /* Don't allocate more for read buffer than could possibly help */ - lt->max_size = Min(MaxAllocSize, shared[i].buffilesize); - tapeblocks = shared[i].buffilesize / BLCKSZ; + lt->max_size = Min(MaxAllocSize, filesize); + tapeblocks = filesize / BLCKSZ; nphysicalblocks += tapeblocks; } @@ -938,7 +944,6 @@ LogicalTapeFreeze(LogicalTapeSet *lts, int tapenum, TapeShare *share) { BufFileExportShared(lts->pfile); share->firstblocknumber = lt->firstBlockNumber; - share->buffilesize = BufFileSize(lts->pfile); } } diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c index e6a8d22feb2..9fb33b9035e 100644 --- a/src/backend/utils/sort/tuplesort.c +++ b/src/backend/utils/sort/tuplesort.c @@ -4395,7 +4395,6 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg) for (i = 0; i < nWorkers; i++) { shared->tapes[i].firstblocknumber = 0L; - shared->tapes[i].buffilesize = 0; } } |