Commit c87c4298 authored by vasil's avatar vasil

branches/5.1:

 
Fix Bug#34823:
fsync() occasionally returns ENOLCK and causes InnoDB to restart mysqld

Create a wrapper to fsync(2) that retries the operation if the error is
ENOLCK. Use that wrapper instead of fsync(2).

Approved by:	Heikki
parent 3fe4b483
......@@ -1810,6 +1810,55 @@ os_file_set_eof(
#endif /* __WIN__ */
}
#ifndef __WIN__
/***************************************************************************
Wrapper to fsync(2) that retries the call on some errors.
Returns the value 0 if successful; otherwise the value -1 is returned and
the global variable errno is set to indicate the error. */
static
int
os_file_fsync(
/*==========*/
/* out: 0 if success, -1 otherwise */
os_file_t file) /* in: handle to a file */
{
int ret;
int failures;
ibool retry;
failures = 0;
do {
ret = fsync(file);
os_n_fsyncs++;
if (ret == -1 && errno == ENOLCK) {
if (failures % 100 == 0) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: fsync(): "
"No locks available; retrying\n");
}
os_thread_sleep(200000 /* 0.2 sec */);
failures++;
retry = TRUE;
} else {
retry = FALSE;
}
} while (retry);
return(ret);
}
#endif /* !__WIN__ */
/***************************************************************************
Flushes the write buffers of a given file to the disk. */
......@@ -1867,21 +1916,19 @@ os_file_flush(
/* If we are not on an operating system that supports this,
then fall back to a plain fsync. */
ret = fsync(file);
ret = os_file_fsync(file);
} else {
ret = fcntl(file, F_FULLFSYNC, NULL);
if (ret) {
/* If we are not on a file system that supports this,
then fall back to a plain fsync. */
ret = fsync(file);
ret = os_file_fsync(file);
}
}
#else
/* fprintf(stderr, "Flushing to file %p\n", file); */
ret = fsync(file);
ret = os_file_fsync(file);
#endif
os_n_fsyncs++;
if (ret == 0) {
return(TRUE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment