Commit d42e4d27 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Merge work:/home/bk/mysql into hundin.mysql.fi:/my/bk/mysql

parents 7288e307 7f4aee1c
...@@ -7252,7 +7252,7 @@ MySQL. How well a certain platform is suited for a high-load ...@@ -7252,7 +7252,7 @@ MySQL. How well a certain platform is suited for a high-load
mission critical MySQL server is determined by the following mission critical MySQL server is determined by the following
factors: factors:
@itemize @itemize @bullet
@item @item
General stability of the thread library. A platform may have excellent General stability of the thread library. A platform may have excellent
reputation otherwise, but if the thread library is unstable in the code reputation otherwise, but if the thread library is unstable in the code
...@@ -7384,7 +7384,7 @@ If you want to configure @code{mysqld} with some extra features that are ...@@ -7384,7 +7384,7 @@ If you want to configure @code{mysqld} with some extra features that are
NOT in the standard binary distributions. Here is a list of the most NOT in the standard binary distributions. Here is a list of the most
common extra options that you may want to use: common extra options that you may want to use:
@itemize @itemize @bullet
@item @code{--with-berkeley-db} @item @code{--with-berkeley-db}
@item @code{--with-innodb} @item @code{--with-innodb}
@item @code{--with-raid} @item @code{--with-raid}
...@@ -23950,7 +23950,7 @@ to it clean up. ...@@ -23950,7 +23950,7 @@ to it clean up.
You should start by creating a wrapper library You should start by creating a wrapper library
/module with the following functions: /module with the following functions:
@itemize @itemize @bullet
@item @item
@code{safe_writer_connect()} @code{safe_writer_connect()}
@item @item
...@@ -26902,7 +26902,7 @@ flag again, the @code{SQL_MAX_JOIN_SIZE} variable will be ignored. ...@@ -26902,7 +26902,7 @@ flag again, the @code{SQL_MAX_JOIN_SIZE} variable will be ignored.
You can set a default value for this variable by starting @code{mysqld} with You can set a default value for this variable by starting @code{mysqld} with
@code{-O max_join_size=#}. @code{-O max_join_size=#}.
@item SQL_SAFE_MODE = 0 | 1 @item SQL_SAFE_UPDATES = 0 | 1
If set to @code{1}, MySQL will abort if an @code{UPDATE} or If set to @code{1}, MySQL will abort if an @code{UPDATE} or
@code{DELETE} is attempted that doesn't use a key or @code{LIMIT} in the @code{DELETE} is attempted that doesn't use a key or @code{LIMIT} in the
@code{WHERE} clause. This makes it possible to catch wrong updates @code{WHERE} clause. This makes it possible to catch wrong updates
...@@ -34893,7 +34893,7 @@ effectiveness. Modifying the default behavior will, in most cases, ...@@ -34893,7 +34893,7 @@ effectiveness. Modifying the default behavior will, in most cases,
only make the search results worse. Do not alter the MySQL sources only make the search results worse. Do not alter the MySQL sources
unless you know what you are doing! unless you know what you are doing!
@itemize @itemize @bullet
@item @item
Minimal length of word to be indexed is defined in Minimal length of word to be indexed is defined in
...@@ -42849,7 +42849,7 @@ Unfortunately, we have not yet written full documentation for it - we plan to ...@@ -42849,7 +42849,7 @@ Unfortunately, we have not yet written full documentation for it - we plan to
do this shortly. You can, however, look at our current test cases and use do this shortly. You can, however, look at our current test cases and use
them as an example. The following points should help you get started: them as an example. The following points should help you get started:
@itemize @itemize @bullet
@item @item
The tests are located in @code{mysql-test/t/*.test} The tests are located in @code{mysql-test/t/*.test}
...@@ -46712,6 +46712,12 @@ not yet 100% confident in this code. ...@@ -46712,6 +46712,12 @@ not yet 100% confident in this code.
@appendixsubsec Changes in release 3.23.42 @appendixsubsec Changes in release 3.23.42
@itemize @bullet @itemize @bullet
@item @item
Fixed rare hang when doing @code{mysqladmin shutdown} when there was
a lot of activity in other threads.
@item
Fixed problem with @code{INSERT DELAYED} where delay thread could be
hanging on @code{upgrading locks} without any apparent reasons.
@item
Fixed problem with @code{myisampack} and @code{BLOB}. Fixed problem with @code{myisampack} and @code{BLOB}.
@item @item
Fixes problem when one edited @code{.MRG} tables by hand. Fixes problem when one edited @code{.MRG} tables by hand.
...@@ -575,12 +575,14 @@ extern int pthread_dummy(int); ...@@ -575,12 +575,14 @@ extern int pthread_dummy(int);
struct st_my_thread_var struct st_my_thread_var
{ {
int thr_errno; int thr_errno;
pthread_cond_t suspend, *current_cond; pthread_cond_t suspend;
pthread_mutex_t mutex, *current_mutex; pthread_mutex_t mutex;
pthread_mutex_t * volatile current_mutex;
pthread_cond_t * volatile current_cond;
pthread_t pthread_self; pthread_t pthread_self;
long id; long id;
int cmp_length; int cmp_length;
volatile int abort; int volatile abort;
#ifndef DBUG_OFF #ifndef DBUG_OFF
gptr dbug; gptr dbug;
char name[THREAD_NAME_SIZE+1]; char name[THREAD_NAME_SIZE+1];
......
...@@ -115,7 +115,7 @@ my_bool init_thr_lock() ...@@ -115,7 +115,7 @@ my_bool init_thr_lock()
static uint found_errors=0; static uint found_errors=0;
static int check_lock(struct st_lock_list *list, const char* lock_type, static int check_lock(struct st_lock_list *list, const char* lock_type,
const char *where, my_bool same_thread) const char *where, my_bool same_thread, bool no_cond)
{ {
THR_LOCK_DATA *data,**prev; THR_LOCK_DATA *data,**prev;
uint count=0; uint count=0;
...@@ -148,6 +148,13 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, ...@@ -148,6 +148,13 @@ static int check_lock(struct st_lock_list *list, const char* lock_type,
lock_type,where); lock_type,where);
return 1; return 1;
} }
if (no_cond && data->cond)
{
fprintf(stderr,
"Warning: Found active lock with not reset cond %s: %s\n",
lock_type,where);
return 1;
}
prev= &data->next; prev= &data->next;
} }
if (data) if (data)
...@@ -172,10 +179,10 @@ static void check_locks(THR_LOCK *lock, const char *where, ...@@ -172,10 +179,10 @@ static void check_locks(THR_LOCK *lock, const char *where,
uint old_found_errors=found_errors; uint old_found_errors=found_errors;
if (found_errors < MAX_FOUND_ERRORS) if (found_errors < MAX_FOUND_ERRORS)
{ {
if (check_lock(&lock->write,"write",where,1) | if (check_lock(&lock->write,"write",where,1,1) |
check_lock(&lock->write_wait,"write_wait",where,0) | check_lock(&lock->write_wait,"write_wait",where,0,0) |
check_lock(&lock->read,"read",where,0) | check_lock(&lock->read,"read",where,0,1) |
check_lock(&lock->read_wait,"read_wait",where,0)) check_lock(&lock->read_wait,"read_wait",where,0,0))
found_errors++; found_errors++;
if (found_errors < MAX_FOUND_ERRORS) if (found_errors < MAX_FOUND_ERRORS)
...@@ -326,6 +333,7 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *param) ...@@ -326,6 +333,7 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data, void *param)
data->thread=pthread_self(); data->thread=pthread_self();
data->thread_id=my_thread_id(); /* for debugging */ data->thread_id=my_thread_id(); /* for debugging */
data->status_param=param; data->status_param=param;
data->cond=0;
} }
...@@ -366,16 +374,16 @@ static my_bool wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, ...@@ -366,16 +374,16 @@ static my_bool wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
} }
/* Set up control struct to allow others to abort locks */ /* Set up control struct to allow others to abort locks */
pthread_mutex_lock(&thread_var->mutex);
thread_var->current_mutex= &data->lock->mutex; thread_var->current_mutex= &data->lock->mutex;
thread_var->current_cond= cond; thread_var->current_cond= cond;
pthread_mutex_unlock(&thread_var->mutex);
data->cond=cond; data->cond=cond;
do while (!thread_var->abort || in_wait_list)
{ {
pthread_cond_wait(cond,&data->lock->mutex); pthread_cond_wait(cond,&data->lock->mutex);
} while (data->cond == cond && (!thread_var->abort || in_wait_list)); if (data->cond != cond)
break;
}
if (data->cond || data->type == TL_UNLOCK) if (data->cond || data->type == TL_UNLOCK)
{ {
...@@ -416,6 +424,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type) ...@@ -416,6 +424,7 @@ int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type)
DBUG_ENTER("thr_lock"); DBUG_ENTER("thr_lock");
data->next=0; data->next=0;
data->cond=0; /* safety */
data->type=lock_type; data->type=lock_type;
data->thread=pthread_self(); /* Must be reset ! */ data->thread=pthread_self(); /* Must be reset ! */
data->thread_id=my_thread_id(); /* Must be reset ! */ data->thread_id=my_thread_id(); /* Must be reset ! */
...@@ -977,6 +986,10 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data) ...@@ -977,6 +986,10 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
lock->write_wait.data=data; lock->write_wait.data=data;
check_locks(lock,"upgrading lock",0); check_locks(lock,"upgrading lock",0);
} }
else
{
check_locks(lock,"waiting for lock",0);
}
DBUG_RETURN(wait_for_lock(&lock->write_wait,data,1)); DBUG_RETURN(wait_for_lock(&lock->write_wait,data,1));
} }
......
...@@ -1500,11 +1500,9 @@ longlong Item_func_get_lock::val_int() ...@@ -1500,11 +1500,9 @@ longlong Item_func_get_lock::val_int()
/* structure is now initialized. Try to get the lock */ /* structure is now initialized. Try to get the lock */
/* Set up control struct to allow others to abort locks */ /* Set up control struct to allow others to abort locks */
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->proc_info="User lock"; thd->proc_info="User lock";
thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond; thd->mysys_var->current_cond= &ull->cond;
pthread_mutex_unlock(&thd->mysys_var->mutex);
#ifdef HAVE_TIMESPEC_TS_SEC #ifdef HAVE_TIMESPEC_TS_SEC
abstime.ts_sec=time((time_t*) 0)+(time_t) timeout; abstime.ts_sec=time((time_t*) 0)+(time_t) timeout;
...@@ -1514,15 +1512,11 @@ longlong Item_func_get_lock::val_int() ...@@ -1514,15 +1512,11 @@ longlong Item_func_get_lock::val_int()
abstime.tv_nsec=0; abstime.tv_nsec=0;
#endif #endif
while ((error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime)) while (!thd->killed &&
!= ETIME && error != ETIMEDOUT && ull->locked) (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
{ != ETIME && error != ETIMEDOUT && ull->locked) ;
if (thd->killed || abort_loop) if (thd->killed)
{ error=EINTR; // Return NULL
error=EINTR; // Return NULL
break;
}
}
if (ull->locked) if (ull->locked)
{ {
if (!--ull->count) if (!--ull->count)
......
...@@ -65,11 +65,9 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count) ...@@ -65,11 +65,9 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
} }
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= &LOCK_open; thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh; thd->mysys_var->current_cond= &COND_refresh;
thd->proc_info="Waiting for table"; thd->proc_info="Waiting for table";
pthread_mutex_unlock(&thd->mysys_var->mutex);
while (global_read_lock && ! thd->killed && while (global_read_lock && ! thd->killed &&
thd->version == refresh_version) thd->version == refresh_version)
......
...@@ -509,12 +509,14 @@ static void close_connections(void) ...@@ -509,12 +509,14 @@ static void close_connections(void)
if (tmp->mysys_var) if (tmp->mysys_var)
{ {
tmp->mysys_var->abort=1; tmp->mysys_var->abort=1;
if (tmp->mysys_var->current_mutex) pthread_mutex_lock(&tmp->mysys_var->mutex);
if (tmp->mysys_var->current_cond)
{ {
pthread_mutex_lock(tmp->mysys_var->current_mutex); pthread_mutex_lock(tmp->mysys_var->current_mutex);
pthread_cond_broadcast(tmp->mysys_var->current_cond); pthread_cond_broadcast(tmp->mysys_var->current_cond);
pthread_mutex_unlock(tmp->mysys_var->current_mutex); pthread_mutex_unlock(tmp->mysys_var->current_mutex);
} }
pthread_mutex_unlock(&tmp->mysys_var->mutex);
} }
} }
(void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
......
...@@ -358,11 +358,9 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, ...@@ -358,11 +358,9 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
*/ */
if (!tables) if (!tables)
kill_delayed_threads(); kill_delayed_threads();
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= &LOCK_open; thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh; thd->mysys_var->current_cond= &COND_refresh;
thd->proc_info="Flushing tables"; thd->proc_info="Flushing tables";
pthread_mutex_unlock(&thd->mysys_var->mutex);
close_old_data_files(thd,thd->open_tables,1,1); close_old_data_files(thd,thd->open_tables,1,1);
bool found=1; bool found=1;
...@@ -667,13 +665,12 @@ void wait_for_refresh(THD *thd) ...@@ -667,13 +665,12 @@ void wait_for_refresh(THD *thd)
{ {
/* Wait until the current table is up to date */ /* Wait until the current table is up to date */
const char *proc_info; const char *proc_info;
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= &LOCK_open; thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh; thd->mysys_var->current_cond= &COND_refresh;
proc_info=thd->proc_info; proc_info=thd->proc_info;
thd->proc_info="Waiting for table"; thd->proc_info="Waiting for table";
pthread_mutex_unlock(&thd->mysys_var->mutex); if (!thd->killed)
(void) pthread_cond_wait(&COND_refresh,&LOCK_open); (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
pthread_mutex_unlock(&LOCK_open); // Must be unlocked first pthread_mutex_unlock(&LOCK_open); // Must be unlocked first
pthread_mutex_lock(&thd->mysys_var->mutex); pthread_mutex_lock(&thd->mysys_var->mutex);
...@@ -2182,7 +2179,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, ...@@ -2182,7 +2179,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
{ {
in_use->killed=1; in_use->killed=1;
pthread_mutex_lock(&in_use->mysys_var->mutex); pthread_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_mutex) if (in_use->mysys_var->current_cond)
{ {
pthread_mutex_lock(in_use->mysys_var->current_mutex); pthread_mutex_lock(in_use->mysys_var->current_mutex);
pthread_cond_broadcast(in_use->mysys_var->current_cond); pthread_cond_broadcast(in_use->mysys_var->current_cond);
......
...@@ -226,12 +226,12 @@ void THD::prepare_to_die() ...@@ -226,12 +226,12 @@ void THD::prepare_to_die()
pthread_mutex_lock(&mysys_var->mutex); pthread_mutex_lock(&mysys_var->mutex);
if (!system_thread) // Don't abort locks if (!system_thread) // Don't abort locks
mysys_var->abort=1; mysys_var->abort=1;
if (mysys_var->current_mutex) if (mysys_var->current_cond)
{ {
pthread_mutex_lock(mysys_var->current_mutex); pthread_mutex_lock(mysys_var->current_mutex);
pthread_cond_broadcast(mysys_var->current_cond); pthread_cond_broadcast(mysys_var->current_cond);
pthread_mutex_unlock(mysys_var->current_mutex); pthread_mutex_unlock(mysys_var->current_mutex);
} }
pthread_mutex_unlock(&mysys_var->mutex); pthread_mutex_unlock(&mysys_var->mutex);
} }
} }
......
...@@ -326,11 +326,9 @@ class THD :public ilink { ...@@ -326,11 +326,9 @@ class THD :public ilink {
const char* msg) const char* msg)
{ {
const char* old_msg = proc_info; const char* old_msg = proc_info;
pthread_mutex_lock(&mysys_var->mutex);
mysys_var->current_mutex = mutex; mysys_var->current_mutex = mutex;
mysys_var->current_cond = cond; mysys_var->current_cond = cond;
proc_info = msg; proc_info = msg;
pthread_mutex_unlock(&mysys_var->mutex);
return old_msg; return old_msg;
} }
inline void exit_cond(const char* old_msg) inline void exit_cond(const char* old_msg)
......
...@@ -482,7 +482,7 @@ class delayed_insert :public ilink { ...@@ -482,7 +482,7 @@ class delayed_insert :public ilink {
COPY_INFO info; COPY_INFO info;
I_List<delayed_row> rows; I_List<delayed_row> rows;
uint group_count; uint group_count;
TABLE_LIST *table_list; // Argument TABLE_LIST table_list; // Argument
delayed_insert() delayed_insert()
:locks_in_memory(0), :locks_in_memory(0),
...@@ -511,10 +511,12 @@ class delayed_insert :public ilink { ...@@ -511,10 +511,12 @@ class delayed_insert :public ilink {
delayed_row *row; delayed_row *row;
while ((row=rows.get())) while ((row=rows.get()))
delete row; delete row;
pthread_mutex_destroy(&mutex);
if (table) if (table)
close_thread_tables(&thd); close_thread_tables(&thd);
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
pthread_cond_destroy(&cond_client);
thd.unlink(); // Must be unlinked under lock thd.unlink(); // Must be unlinked under lock
x_free(thd.query); x_free(thd.query);
thd.user=thd.host=0; thd.user=thd.host=0;
...@@ -609,7 +611,9 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list) ...@@ -609,7 +611,9 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
pthread_mutex_unlock(&LOCK_delayed_create); pthread_mutex_unlock(&LOCK_delayed_create);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
tmp->table_list=table_list; // Needed to open table tmp->table_list= *table_list; // Needed to open table
tmp->table_list.db= tmp->thd.db;
tmp->table_list.name= tmp->table_list.real_name=tmp->thd.query;
tmp->lock(); tmp->lock();
pthread_mutex_lock(&tmp->mutex); pthread_mutex_lock(&tmp->mutex);
if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib, if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib,
...@@ -842,13 +846,11 @@ void kill_delayed_threads(void) ...@@ -842,13 +846,11 @@ void kill_delayed_threads(void)
if (tmp->thd.mysys_var) if (tmp->thd.mysys_var)
{ {
pthread_mutex_lock(&tmp->thd.mysys_var->mutex); pthread_mutex_lock(&tmp->thd.mysys_var->mutex);
if (tmp->thd.mysys_var->current_mutex) if (tmp->thd.mysys_var->current_cond)
{ {
if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) pthread_mutex_lock(tmp->thd.mysys_var->current_mutex);
pthread_mutex_lock(tmp->thd.mysys_var->current_mutex);
pthread_cond_broadcast(tmp->thd.mysys_var->current_cond); pthread_cond_broadcast(tmp->thd.mysys_var->current_cond);
if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex);
pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex);
} }
pthread_mutex_unlock(&tmp->thd.mysys_var->mutex); pthread_mutex_unlock(&tmp->thd.mysys_var->mutex);
} }
...@@ -873,6 +875,7 @@ static pthread_handler_decl(handle_delayed_insert,arg) ...@@ -873,6 +875,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
thd->thread_id=thread_id++; thd->thread_id=thread_id++;
thd->end_time(); thd->end_time();
threads.append(thd); threads.append(thd);
thd->killed=abort_loop;
pthread_mutex_unlock(&LOCK_thread_count); pthread_mutex_unlock(&LOCK_thread_count);
pthread_mutex_lock(&di->mutex); pthread_mutex_lock(&di->mutex);
...@@ -903,7 +906,7 @@ static pthread_handler_decl(handle_delayed_insert,arg) ...@@ -903,7 +906,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
/* open table */ /* open table */
if (!(di->table=open_ltable(thd,di->table_list,TL_WRITE_DELAYED))) if (!(di->table=open_ltable(thd,&di->table_list,TL_WRITE_DELAYED)))
{ {
thd->fatal_error=1; // Abort waiting inserts thd->fatal_error=1; // Abort waiting inserts
goto end; goto end;
...@@ -911,7 +914,7 @@ static pthread_handler_decl(handle_delayed_insert,arg) ...@@ -911,7 +914,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
if (di->table->file->has_transactions()) if (di->table->file->has_transactions())
{ {
thd->fatal_error=1; thd->fatal_error=1;
my_error(ER_ILLEGAL_HA, MYF(0), di->table_list->real_name); my_error(ER_ILLEGAL_HA, MYF(0), di->table_list.real_name);
goto end; goto end;
} }
di->table->copy_blobs=1; di->table->copy_blobs=1;
...@@ -963,14 +966,12 @@ static pthread_handler_decl(handle_delayed_insert,arg) ...@@ -963,14 +966,12 @@ static pthread_handler_decl(handle_delayed_insert,arg)
#endif #endif
/* Information for pthread_kill */ /* Information for pthread_kill */
pthread_mutex_lock(&di->thd.mysys_var->mutex);
di->thd.mysys_var->current_mutex= &di->mutex; di->thd.mysys_var->current_mutex= &di->mutex;
di->thd.mysys_var->current_cond= &di->cond; di->thd.mysys_var->current_cond= &di->cond;
pthread_mutex_unlock(&di->thd.mysys_var->mutex);
di->thd.proc_info=0; di->thd.proc_info=0;
DBUG_PRINT("info",("Waiting for someone to insert rows")); DBUG_PRINT("info",("Waiting for someone to insert rows"));
for ( ; ;) while (!thd->killed)
{ {
int error; int error;
#if (defined(HAVE_BROKEN_COND_TIMEDWAIT) || defined(HAVE_LINUXTHREADS)) #if (defined(HAVE_BROKEN_COND_TIMEDWAIT) || defined(HAVE_LINUXTHREADS))
...@@ -994,10 +995,13 @@ static pthread_handler_decl(handle_delayed_insert,arg) ...@@ -994,10 +995,13 @@ static pthread_handler_decl(handle_delayed_insert,arg)
break; break;
} }
} }
/* We can't lock di->mutex and mysys_var->mutex at the same time */
pthread_mutex_unlock(&di->mutex);
pthread_mutex_lock(&di->thd.mysys_var->mutex); pthread_mutex_lock(&di->thd.mysys_var->mutex);
di->thd.mysys_var->current_mutex= 0; di->thd.mysys_var->current_mutex= 0;
di->thd.mysys_var->current_cond= 0; di->thd.mysys_var->current_cond= 0;
pthread_mutex_unlock(&di->thd.mysys_var->mutex); pthread_mutex_unlock(&di->thd.mysys_var->mutex);
pthread_mutex_lock(&di->mutex);
} }
if (di->tables_in_use && ! thd->lock) if (di->tables_in_use && ! thd->lock)
......
...@@ -414,12 +414,10 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -414,12 +414,10 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
log.error=0; log.error=0;
// tell the kill thread how to wake us up // tell the kill thread how to wake us up
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex = log_lock; thd->mysys_var->current_mutex = log_lock;
thd->mysys_var->current_cond = &COND_binlog_update; thd->mysys_var->current_cond = &COND_binlog_update;
const char* proc_info = thd->proc_info; const char* proc_info = thd->proc_info;
thd->proc_info = "Slave connection: waiting for binlog update"; thd->proc_info = "Slave connection: waiting for binlog update";
pthread_mutex_unlock(&thd->mysys_var->mutex);
bool read_packet = 0, fatal_error = 0; bool read_packet = 0, fatal_error = 0;
...@@ -444,7 +442,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags) ...@@ -444,7 +442,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, ulong pos, ushort flags)
break; break;
case LOG_READ_EOF: case LOG_READ_EOF:
DBUG_PRINT("wait",("waiting for data on binary log")); DBUG_PRINT("wait",("waiting for data on binary log"));
pthread_cond_wait(&COND_binlog_update, log_lock); if (!thd->killed)
pthread_cond_wait(&COND_binlog_update, log_lock);
break; break;
default: default:
...@@ -694,9 +693,9 @@ void kill_zombie_dump_threads(uint32 slave_server_id) ...@@ -694,9 +693,9 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
thr_alarm_kill(tmp->real_id); thr_alarm_kill(tmp->real_id);
tmp->killed = 1; tmp->killed = 1;
pthread_mutex_lock(&tmp->mysys_var->mutex);
tmp->mysys_var->abort = 1; tmp->mysys_var->abort = 1;
if(tmp->mysys_var->current_mutex) pthread_mutex_lock(&tmp->mysys_var->mutex);
if(tmp->mysys_var->current_cond)
{ {
pthread_mutex_lock(tmp->mysys_var->current_mutex); pthread_mutex_lock(tmp->mysys_var->current_mutex);
pthread_cond_broadcast(tmp->mysys_var->current_cond); pthread_cond_broadcast(tmp->mysys_var->current_cond);
......
...@@ -53,11 +53,9 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists) ...@@ -53,11 +53,9 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
/* mark for close and remove all cached entries */ /* mark for close and remove all cached entries */
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= &LOCK_open; thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh; thd->mysys_var->current_cond= &COND_refresh;
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
pthread_mutex_unlock(&thd->mysys_var->mutex);
if (global_read_lock) if (global_read_lock)
{ {
......
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