Commit 4d7a2641 authored by unknown's avatar unknown

Fixed problem with INSERT DELAYED

Make killing threads safer


Docs/manual.texi:
  Portability fix
mysys/thr_lock.c:
  Fixed problem with INSERT DELAYED
sql/mysqld.cc:
  Make shutdown safer
sql/sql_class.cc:
  Make kill thread safer
sql/sql_insert.cc:
  Make kill thread safer
parent 473eba04
...@@ -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,9 @@ not yet 100% confident in this code. ...@@ -46712,6 +46712,9 @@ 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 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.
...@@ -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;
} }
...@@ -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));
} }
......
...@@ -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
......
...@@ -226,7 +226,7 @@ void THD::prepare_to_die() ...@@ -226,7 +226,7 @@ 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);
......
...@@ -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;
...@@ -842,7 +844,7 @@ void kill_delayed_threads(void) ...@@ -842,7 +844,7 @@ 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) 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);
...@@ -970,7 +972,7 @@ static pthread_handler_decl(handle_delayed_insert,arg) ...@@ -970,7 +972,7 @@ static pthread_handler_decl(handle_delayed_insert,arg)
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))
......
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