MDEV-11127 : Fix innochecksum to work with large files on Windows.
- don't use stat() for file size, it doesn not handle large size use GetFileSizeEx() instead - don't use lseek(), it can't handle large files, use _lseeki64() instead. - Also, switch off OS file buffering for innochecksum on Windows, to avoid thrashing file cache.
This commit is contained in:
parent
3321f1adc7
commit
ba11dd69fe
@ -243,10 +243,9 @@ int main(int argc, char **argv)
|
||||
time_t lastt; /* last time */
|
||||
ulint oldcsum, oldcsumfield, csum, csumfield, crc32, logseq, logseqfield;
|
||||
/* ulints for checksum storage */
|
||||
struct stat st; /* for stat, if you couldn't guess */
|
||||
unsigned long long int size; /* size of file (has to be 64 bits) */
|
||||
ulint pages; /* number of pages in file */
|
||||
off_t offset= 0;
|
||||
unsigned long long offset= 0;
|
||||
int fd;
|
||||
|
||||
printf("InnoDB offline file checksum utility.\n");
|
||||
@ -269,6 +268,47 @@ int main(int argc, char **argv)
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Switch off OS file buffering for the file. */
|
||||
|
||||
HANDLE h = CreateFile(filename, GENERIC_READ,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE, 0,
|
||||
OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, 0);
|
||||
|
||||
if (!h)
|
||||
{
|
||||
fprintf(stderr, "Error; cant open file\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!GetFileSizeEx(h, (LARGE_INTEGER *)&size))
|
||||
{
|
||||
fprintf(stderr, "Error; GetFileSize() failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
fd = _open_osfhandle ((intptr_t) h, _O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "Error; _open_osfhandle() failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
f = _fdopen(fd, "rb");
|
||||
if (!f)
|
||||
{
|
||||
fprintf(stderr, "Error; fdopen() failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
Disable stdio buffering (FILE_FLAG_NO_BUFFERING requires properly IO buffers
|
||||
which stdio does not guarantee.
|
||||
*/
|
||||
setvbuf(f, NULL, _IONBF, 0);
|
||||
|
||||
#else
|
||||
struct stat st;
|
||||
/* stat the file to get size and page count */
|
||||
if (stat(filename, &st))
|
||||
{
|
||||
@ -279,6 +319,8 @@ int main(int argc, char **argv)
|
||||
|
||||
/* Open the file for reading */
|
||||
f= fopen(filename, "rb");
|
||||
#endif
|
||||
|
||||
if (f == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error; %s cannot be opened", filename);
|
||||
@ -323,7 +365,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
else if (verbose)
|
||||
{
|
||||
printf("file %s = %llu bytes (%lu pages)...\n", filename, size, pages);
|
||||
printf("file %s = %llu bytes (%lu pages)...\n", filename, size, (ulong)pages);
|
||||
if (do_one_page)
|
||||
printf("InnoChecksum; checking page %lu\n", do_page);
|
||||
else
|
||||
@ -348,9 +390,12 @@ int main(int argc, char **argv)
|
||||
goto error;
|
||||
}
|
||||
|
||||
offset= (off_t)start_page * (off_t)physical_page_size;
|
||||
|
||||
offset= (ulonglong)start_page * (ulonglong)physical_page_size;
|
||||
#ifdef _WIN32
|
||||
if (_lseeki64(fd, offset, SEEK_SET) != offset)
|
||||
#else
|
||||
if (lseek(fd, offset, SEEK_SET) != offset)
|
||||
#endif
|
||||
{
|
||||
perror("Error; Unable to seek to necessary offset");
|
||||
goto error;
|
||||
|
Loading…
x
Reference in New Issue
Block a user