Commit 43044b68 authored by unknown's avatar unknown

Fix for SAFE_MUTEX + MERGE tables


Docs/manual.texi:
  Fix for release
include/my_pthread.h:
  Fix for SAFE_MUTEX for windows
include/myisammrg.h:
  Fix for empty MERGE tables
myisam/ft_stopwords.c:
  Free used memory
myisammrg/myrg_open.c:
  Fix for empty MERGE tables
myisammrg/myrg_queue.c:
  Fix for empty MERGE tables
myisammrg/myrg_rfirst.c:
  cleanup
myisammrg/myrg_rkey.c:
  cleanup
mysys/my_thr_init.c:
  Fix SAFE_MUTEX for windows
mysys/my_winthread.c:
  Fix SAFE_MUTEX for windows
mysys/thr_mutex.c:
  Fix SAFE_MUTEX for windows
sql/ha_myisammrg.cc:
  Fix for empty MERGE tables
sql/mysqld.cc:
  Fix type
parent 73826420
...@@ -40860,6 +40860,9 @@ Fixed @code{DISTINCT} with calculated columns. ...@@ -40860,6 +40860,9 @@ Fixed @code{DISTINCT} with calculated columns.
@itemize @bullet @itemize @bullet
@item @item
@code{mysqldump} on a @code{MERGE} table doesn't include the current
mapped tables.
@item
For the moment @code{MATCH} only works with @code{SELECT} statements. For the moment @code{MATCH} only works with @code{SELECT} statements.
@item @item
You cannot build in another directory when using You cannot build in another directory when using
...@@ -60,6 +60,7 @@ typedef int pthread_mutexattr_t; ...@@ -60,6 +60,7 @@ typedef int pthread_mutexattr_t;
#define pthread_handler_decl(A,B) unsigned __cdecl A(void *B) #define pthread_handler_decl(A,B) unsigned __cdecl A(void *B)
typedef unsigned (__cdecl *pthread_handler)(void *); typedef unsigned (__cdecl *pthread_handler)(void *);
void win_pthread_init(void);
int win_pthread_setspecific(void *A,void *B,uint length); int win_pthread_setspecific(void *A,void *B,uint length);
int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *); int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
......
...@@ -59,7 +59,7 @@ typedef struct st_myrg_info ...@@ -59,7 +59,7 @@ typedef struct st_myrg_info
ulonglong records; /* records in tables */ ulonglong records; /* records in tables */
ulonglong del; /* Removed records */ ulonglong del; /* Removed records */
ulonglong data_file_length; ulonglong data_file_length;
uint tables,options,reclength; uint tables,options,reclength,keys;
my_bool cache_in_use; my_bool cache_in_use;
LIST open_list; LIST open_list;
QUEUE by_key; QUEUE by_key;
......
...@@ -72,6 +72,7 @@ void ft_free_stopwords() ...@@ -72,6 +72,7 @@ void ft_free_stopwords()
if (stopwords3) if (stopwords3)
{ {
delete_tree(stopwords3); /* purecov: inspected */ delete_tree(stopwords3); /* purecov: inspected */
my_free((char*) stopwords3,MYF(0));
stopwords3=0; stopwords3=0;
} }
} }
...@@ -86,6 +86,7 @@ int handle_locking; ...@@ -86,6 +86,7 @@ int handle_locking;
*m_info=info; *m_info=info;
m_info->open_tables=(MYRG_TABLE *) (m_info+1); m_info->open_tables=(MYRG_TABLE *) (m_info+1);
m_info->tables=files; m_info->tables=files;
errpos=2;
for (i=files ; i-- > 0 ; ) for (i=files ; i-- > 0 ; )
{ {
...@@ -104,16 +105,21 @@ int handle_locking; ...@@ -104,16 +105,21 @@ int handle_locking;
m_info->open_tables[i].file_offset=(my_off_t) file_offset; m_info->open_tables[i].file_offset=(my_off_t) file_offset;
file_offset+=m_info->open_tables[i].table->state->data_file_length; file_offset+=m_info->open_tables[i].table->state->data_file_length;
} }
errpos=2;
if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L) if (sizeof(my_off_t) == 4 && file_offset > (ulonglong) (ulong) ~0L)
{ {
my_errno=HA_ERR_RECORD_FILE_FULL; my_errno=HA_ERR_RECORD_FILE_FULL;
goto err; goto err;
} }
/* Allocate memory for queue */ /* Allocate memory for queue */
if (m_info->open_tables->table->s->base.keys && m_info->keys=0;
if (files)
{
if ((m_info->keys=m_info->open_tables->table->s->base.keys) &&
_myrg_init_queue(m_info,0,HA_READ_KEY_EXACT)) _myrg_init_queue(m_info,0,HA_READ_KEY_EXACT))
goto err; goto err;
}
else
bzero((char*) &m_info->by_key,sizeof(m_info->by_key));
m_info->end_table=m_info->open_tables+files; m_info->end_table=m_info->open_tables+files;
m_info->last_used_table=m_info->open_tables; m_info->last_used_table=m_info->open_tables;
......
...@@ -34,6 +34,8 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag) ...@@ -34,6 +34,8 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
int error=0; int error=0;
QUEUE *q= &(info->by_key); QUEUE *q= &(info->by_key);
if (inx < (int) info->keys)
{
if (!is_queue_inited(q)) if (!is_queue_inited(q))
{ {
if (init_queue(q,info->tables, 0, if (init_queue(q,info->tables, 0,
...@@ -50,5 +52,6 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag) ...@@ -50,5 +52,6 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag)
info->open_tables->table->s->keyinfo[inx].seg)) info->open_tables->table->s->keyinfo[inx].seg))
error=my_errno; error=my_errno;
} }
}
return error; return error;
} }
...@@ -27,7 +27,7 @@ int myrg_rfirst(MYRG_INFO *info, byte *buf, int inx) ...@@ -27,7 +27,7 @@ int myrg_rfirst(MYRG_INFO *info, byte *buf, int inx)
if (_myrg_init_queue(info,inx,HA_READ_KEY_OR_NEXT)) if (_myrg_init_queue(info,inx,HA_READ_KEY_OR_NEXT))
return my_errno; return my_errno;
for (table=info->open_tables ; table < info->end_table ; table++) for (table=info->open_tables ; table != info->end_table ; table++)
{ {
if ((err=mi_rfirst(table->table,NULL,inx))) if ((err=mi_rfirst(table->table,NULL,inx)))
{ {
......
...@@ -49,7 +49,7 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key, ...@@ -49,7 +49,7 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key,
if (_myrg_init_queue(info,inx,search_flag)) if (_myrg_init_queue(info,inx,search_flag))
return my_errno; return my_errno;
for (table=info->open_tables ; table < info->end_table ; table++) for (table=info->open_tables ; table != info->end_table ; table++)
{ {
mi=table->table; mi=table->table;
......
...@@ -35,9 +35,6 @@ pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache, ...@@ -35,9 +35,6 @@ pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
#ifndef HAVE_LOCALTIME_R #ifndef HAVE_LOCALTIME_R
pthread_mutex_t LOCK_localtime_r; pthread_mutex_t LOCK_localtime_r;
#endif #endif
#ifdef __WIN__
pthread_mutex_t THR_LOCK_thread;
#endif
/* FIXME Note. TlsAlloc does not set an auto destructor, so /* FIXME Note. TlsAlloc does not set an auto destructor, so
the function my_thread_global_free must be called from the function my_thread_global_free must be called from
...@@ -60,7 +57,7 @@ my_bool my_thread_global_init(void) ...@@ -60,7 +57,7 @@ my_bool my_thread_global_init(void)
pthread_mutex_init(&THR_LOCK_net,NULL); pthread_mutex_init(&THR_LOCK_net,NULL);
pthread_mutex_init(&THR_LOCK_charset,NULL); pthread_mutex_init(&THR_LOCK_charset,NULL);
#ifdef __WIN__ #ifdef __WIN__
pthread_mutex_init(&THR_LOCK_thread,NULL); win_pthread_init();
#endif #endif
#ifndef HAVE_LOCALTIME_R #ifndef HAVE_LOCALTIME_R
pthread_mutex_init(&LOCK_localtime_r,NULL); pthread_mutex_init(&LOCK_localtime_r,NULL);
...@@ -78,7 +75,7 @@ void my_thread_global_end(void) ...@@ -78,7 +75,7 @@ void my_thread_global_end(void)
static long thread_id=0; static long thread_id=0;
/* /*
We can't use mutex_locks here if we re using windows as We can't use mutex_locks here if we are using windows as
we may have compiled the program with SAFE_MUTEX, in which we may have compiled the program with SAFE_MUTEX, in which
case the checking of mutex_locks will not work until case the checking of mutex_locks will not work until
the pthread_self thread specific variable is initialized. the pthread_self thread specific variable is initialized.
......
...@@ -19,13 +19,16 @@ ...@@ -19,13 +19,16 @@
** Simulation of posix threads calls for WIN95 and NT ** Simulation of posix threads calls for WIN95 and NT
*****************************************************************************/ *****************************************************************************/
/* SAFE_MUTEX will not work until the thread structure is up to date */
#undef SAFE_MUTEX
#include "mysys_priv.h" #include "mysys_priv.h"
#if defined(THREAD) && defined(__WIN__) #if defined(THREAD) && defined(__WIN__)
#include <m_string.h> #include <m_string.h>
#undef getpid #undef getpid
#include <process.h> #include <process.h>
extern pthread_mutex_t THR_LOCK_thread; static pthread_mutex_t THR_LOCK_thread;
struct pthread_map struct pthread_map
{ {
...@@ -34,6 +37,11 @@ struct pthread_map ...@@ -34,6 +37,11 @@ struct pthread_map
void *param; void *param;
}; };
void win_pthread_init(void)
{
pthread_mutex_init(&THR_LOCK_thread,NULL);
}
/* /*
** We have tried to use '_beginthreadex' instead of '_beginthread' here ** We have tried to use '_beginthreadex' instead of '_beginthread' here
** but in this case the program leaks about 512 characters for each ** but in this case the program leaks about 512 characters for each
......
...@@ -67,6 +67,7 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line) ...@@ -67,6 +67,7 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
{ {
fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d\n", fprintf(stderr,"safe_mutex: Trying to lock mutex at %s, line %d, when the mutex was already locked at %s, line %d\n",
file,line,mp->file,mp->line); file,line,mp->file,mp->line);
fflush(stderr);
abort(); abort();
} }
pthread_mutex_unlock(&mp->global); pthread_mutex_unlock(&mp->global);
...@@ -75,11 +76,13 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line) ...@@ -75,11 +76,13 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
{ {
fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %d\n", fprintf(stderr,"Got error %d when trying to lock mutex at %s, line %d\n",
error, file, line); error, file, line);
fflush(stderr);
abort(); abort();
} }
if (mp->count++) if (mp->count++)
{ {
fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, line %d more than 1 time\n", file,line); fprintf(stderr,"safe_mutex: Error in thread libray: Got mutex at %s, line %d more than 1 time\n", file,line);
fflush(stderr);
abort(); abort();
} }
mp->thread=pthread_self(); mp->thread=pthread_self();
...@@ -98,12 +101,14 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line) ...@@ -98,12 +101,14 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
{ {
fprintf(stderr,"safe_mutex: Trying to unlock mutex that wasn't locked at %s, line %d\n Last used at %s, line: %d\n", fprintf(stderr,"safe_mutex: Trying to unlock mutex that wasn't locked at %s, line %d\n Last used at %s, line: %d\n",
file,line,mp->file ? mp->file : "",mp->line); file,line,mp->file ? mp->file : "",mp->line);
fflush(stderr);
abort(); abort();
} }
if (!pthread_equal(pthread_self(),mp->thread)) if (!pthread_equal(pthread_self(),mp->thread))
{ {
fprintf(stderr,"safe_mutex: Trying to unlock mutex at %s, line %d that was locked by another thread at: %s, line: %d\n", fprintf(stderr,"safe_mutex: Trying to unlock mutex at %s, line %d that was locked by another thread at: %s, line: %d\n",
file,line,mp->file,mp->line); file,line,mp->file,mp->line);
fflush(stderr);
abort(); abort();
} }
mp->count--; mp->count--;
...@@ -115,6 +120,7 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line) ...@@ -115,6 +120,7 @@ int safe_mutex_unlock(safe_mutex_t *mp,const char *file, uint line)
if (error) if (error)
{ {
fprintf(stderr,"safe_mutex: Got error: %d when trying to unlock mutex at %s, line %d\n", error, file, line); fprintf(stderr,"safe_mutex: Got error: %d when trying to unlock mutex at %s, line %d\n", error, file, line);
fflush(stderr);
abort(); abort();
} }
#endif /* __WIN__ */ #endif /* __WIN__ */
...@@ -131,12 +137,14 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, ...@@ -131,12 +137,14 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
if (mp->count == 0) if (mp->count == 0)
{ {
fprintf(stderr,"safe_mutex: Trying to cond_wait on a unlocked mutex at %s, line %d\n",file,line); fprintf(stderr,"safe_mutex: Trying to cond_wait on a unlocked mutex at %s, line %d\n",file,line);
fflush(stderr);
abort(); abort();
} }
if (!pthread_equal(pthread_self(),mp->thread)) if (!pthread_equal(pthread_self(),mp->thread))
{ {
fprintf(stderr,"safe_mutex: Trying to cond_wait on a mutex at %s, line %d that was locked by another thread at: %s, line: %d\n", fprintf(stderr,"safe_mutex: Trying to cond_wait on a mutex at %s, line %d that was locked by another thread at: %s, line: %d\n",
file,line,mp->file,mp->line); file,line,mp->file,mp->line);
fflush(stderr);
abort(); abort();
} }
...@@ -144,6 +152,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, ...@@ -144,6 +152,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
{ {
fprintf(stderr,"safe_mutex: Count was %d on locked mutex at %s, line %d\n", fprintf(stderr,"safe_mutex: Count was %d on locked mutex at %s, line %d\n",
mp->count+1, file, line); mp->count+1, file, line);
fflush(stderr);
abort(); abort();
} }
pthread_mutex_unlock(&mp->global); pthread_mutex_unlock(&mp->global);
...@@ -152,6 +161,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, ...@@ -152,6 +161,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
if (error) if (error)
{ {
fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_wait at %s, line %d\n", error, file, line); fprintf(stderr,"safe_mutex: Got error: %d when doing a safe_mutex_wait at %s, line %d\n", error, file, line);
fflush(stderr);
abort(); abort();
} }
if (mp->count++) if (mp->count++)
...@@ -159,6 +169,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file, ...@@ -159,6 +169,7 @@ int safe_cond_wait(pthread_cond_t *cond, safe_mutex_t *mp, const char *file,
fprintf(stderr, fprintf(stderr,
"safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d\n", "safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d\n",
mp->count-1, my_thread_id(), file, line); mp->count-1, my_thread_id(), file, line);
fflush(stderr);
abort(); abort();
} }
mp->thread=pthread_self(); mp->thread=pthread_self();
...@@ -178,6 +189,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, ...@@ -178,6 +189,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
if (mp->count != 1 || !pthread_equal(pthread_self(),mp->thread)) if (mp->count != 1 || !pthread_equal(pthread_self(),mp->thread))
{ {
fprintf(stderr,"safe_mutex: Trying to cond_wait at %s, line %d on a not hold mutex\n",file,line); fprintf(stderr,"safe_mutex: Trying to cond_wait at %s, line %d on a not hold mutex\n",file,line);
fflush(stderr);
abort(); abort();
} }
mp->count--; /* Mutex will be released */ mp->count--; /* Mutex will be released */
...@@ -195,6 +207,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, ...@@ -195,6 +207,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
fprintf(stderr, fprintf(stderr,
"safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d (error: %d)\n", "safe_mutex: Count was %d in thread %lx when locking mutex at %s, line %d (error: %d)\n",
mp->count-1, my_thread_id(), file, line, error); mp->count-1, my_thread_id(), file, line, error);
fflush(stderr);
abort(); abort();
} }
mp->thread=pthread_self(); mp->thread=pthread_self();
...@@ -211,6 +224,7 @@ int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line) ...@@ -211,6 +224,7 @@ int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
{ {
fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %d\n", fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %d\n",
mp->file,mp->line, file, line); mp->file,mp->line, file, line);
fflush(stderr);
abort(); abort();
} }
#ifdef __WIN__ #ifdef __WIN__
......
...@@ -48,7 +48,7 @@ int ha_myisammrg::open(const char *name, int mode, int test_if_locked) ...@@ -48,7 +48,7 @@ int ha_myisammrg::open(const char *name, int mode, int test_if_locked)
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST); info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED)) if (!(test_if_locked & HA_OPEN_WAIT_IF_LOCKED))
myrg_extra(file,HA_EXTRA_WAIT_LOCK); myrg_extra(file,HA_EXTRA_WAIT_LOCK);
if (table->reclength != mean_rec_length) if (table->reclength != mean_rec_length && mean_rec_length)
{ {
DBUG_PRINT("error",("reclength: %d mean_rec_length: %d", DBUG_PRINT("error",("reclength: %d mean_rec_length: %d",
table->reclength, mean_rec_length)); table->reclength, mean_rec_length));
......
...@@ -2400,7 +2400,7 @@ struct show_var_st init_vars[]= { ...@@ -2400,7 +2400,7 @@ struct show_var_st init_vars[]= {
{"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG}, {"interactive_timeout", (char*) &net_interactive_timeout, SHOW_LONG},
{"key_buffer_size", (char*) &keybuff_size, SHOW_LONG}, {"key_buffer_size", (char*) &keybuff_size, SHOW_LONG},
{"language", language, SHOW_CHAR}, {"language", language, SHOW_CHAR},
#ifdef HAVE_MEMLOCKALL #ifdef HAVE_MLOCKALL
{"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL}, {"locked_in_memory", (char*) &locked_in_memory, SHOW_BOOL},
#endif #endif
{"log", (char*) &opt_log, SHOW_BOOL}, {"log", (char*) &opt_log, SHOW_BOOL},
......
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