BUG#25712 - insert delayed and check table run together report crashed

            tables

In case system doesn't have native pread/pwrite calls (e.g. Windows)
and there is CHECK TABLE runs concurrently with another statement that
reads from a table, the table may be reported as crashed.

This is fixed by locking file descriptor when my_seek is executed on
MyISAM index file and emulated pread/pwrite may be executed concurrently.

Affects MyISAM tables on platforms that do not have native
pread/pwrite calls (e.g. Windows).

No deterministic test case for this bug.
parent 0c7631e7
...@@ -336,7 +336,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info) ...@@ -336,7 +336,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
flush_key_blocks(info->s->key_cache, flush_key_blocks(info->s->key_cache,
info->s->kfile, FLUSH_FORCE_WRITE); info->s->kfile, FLUSH_FORCE_WRITE);
size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0)); size= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
if ((skr=(my_off_t) info->state->key_file_length) != size) if ((skr=(my_off_t) info->state->key_file_length) != size)
{ {
if (skr > size) if (skr > size)
...@@ -595,7 +595,8 @@ static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo, ...@@ -595,7 +595,8 @@ static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
{ {
/* purecov: begin tested */ /* purecov: begin tested */
/* Give it a chance to fit in the real file size. */ /* Give it a chance to fit in the real file size. */
my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(0)); my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END,
MYF(MY_THREADSAFE));
mi_check_print_error(param, "Invalid key block position: %s " mi_check_print_error(param, "Invalid key block position: %s "
"key block size: %u file_length: %s", "key block size: %u file_length: %s",
llstr(page, llbuff), keyinfo->block_length, llstr(page, llbuff), keyinfo->block_length,
...@@ -4039,10 +4040,10 @@ int test_if_almost_full(MI_INFO *info) ...@@ -4039,10 +4040,10 @@ int test_if_almost_full(MI_INFO *info)
{ {
if (info->s->options & HA_OPTION_COMPRESS_RECORD) if (info->s->options & HA_OPTION_COMPRESS_RECORD)
return 0; return 0;
return (my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0))/10*9 > return my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE)) / 10 * 9 >
(my_off_t) (info->s->base.max_key_file_length) || (my_off_t) info->s->base.max_key_file_length ||
my_seek(info->dfile,0L,MY_SEEK_END,MYF(0))/10*9 > my_seek(info->dfile, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 >
(my_off_t) info->s->base.max_data_file_length); (my_off_t) info->s->base.max_data_file_length;
} }
/* Recreate table with bigger more alloced record-data */ /* Recreate table with bigger more alloced record-data */
......
...@@ -24,7 +24,9 @@ ...@@ -24,7 +24,9 @@
my_off_t pos The expected position (absolute or relative) my_off_t pos The expected position (absolute or relative)
int whence A direction parameter and one of int whence A direction parameter and one of
{SEEK_SET, SEEK_CUR, SEEK_END} {SEEK_SET, SEEK_CUR, SEEK_END}
myf MyFlags Not used. myf MyFlags MY_THREADSAFE must be set in case my_seek may be mixed
with my_pread/my_pwrite calls and fd is shared among
threads.
DESCRIPTION DESCRIPTION
The my_seek function is a wrapper around the system call lseek and The my_seek function is a wrapper around the system call lseek and
...@@ -51,7 +53,16 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, ...@@ -51,7 +53,16 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
whence, MyFlags)); whence, MyFlags));
DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */ DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */
newpos=lseek(fd, pos, whence); #if defined(THREAD) && !defined(HAVE_PREAD)
if (MyFlags & MY_THREADSAFE)
{
pthread_mutex_lock(&my_file_info[fd].mutex);
newpos= lseek(fd, pos, whence);
pthread_mutex_lock(&my_file_info[fd].mutex);
}
else
#endif
newpos= lseek(fd, pos, whence);
if (newpos == (os_off_t) -1) if (newpos == (os_off_t) -1)
{ {
my_errno=errno; my_errno=errno;
......
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