diff options
author | Michael Widenius <monty@askmonty.org> | 2011-09-09 19:44:07 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2011-09-09 19:44:07 +0300 |
commit | 8fb10c24d74cbddbfd6da0b5f4ea9409f8f88e57 (patch) | |
tree | 9aa9507d3be693856005e7718dd6742d160e0bf5 | |
parent | 13e4d54795c2e49e4a8654964de1ab899eae2b23 (diff) | |
download | mariadb-git-8fb10c24d74cbddbfd6da0b5f4ea9409f8f88e57.tar.gz |
Fixed that automatic killing of delayed insert thread (in flush, alter table etc) will not abort auto-repair of MyISAM table.
Give more information when finding an error in a MyISAM table.
When killing system thread, use KILL_SYSTEM_THREAD instead of KILL_CONNECTION to make it easier to ignore the signal in sensitive context (like auto-repair)
Added new kill level: KILL_SERVER that will in the future to be used to signal killed by shutdown.
Add more warnings about killed connections when warning level > 3
include/myisamchk.h:
Added counting of printed info/notes
mysys/mf_iocache.c:
Remove duplicate assignment
sql/handler.cc:
Added test of KILL_SERVER
sql/log.cc:
Ignore new 'kill' error ER_NEW_ABORTING_CONNECTION when requesting query error code.
sql/mysqld.cc:
Add more warnings for killed connections when warning level > 3
sql/scheduler.cc:
Added checks for new kill signals
sql/slave.cc:
Ignore new kill signal ER_NEW_ABORTING_CONNECTION
sql/sp_head.cc:
Fixed assignment to bool
Added testing of new kill signals
sql/sql_base.cc:
Use KILL_SYSTEM_THREAD to auto-kill system threads
sql/sql_class.cc:
Add more warnings for killed connections when warning level > 3
thd_killed() now ignores KILL_BAD_DATA and THD::KILL_SYSTEM_THREAD as these should not abort sensitive operations.
sql/sql_class.h:
Added KILL_SYSTEM_THREAD and KILL_SERVER
sql/sql_connect.cc:
Added handling of KILL_SERVER
sql/sql_insert.cc:
Use KILL_SYSTEM_THREAD to auto-kill system threads
Added handling of KILL_SERVER
sql/sql_parse.cc:
Add more warnings for killed connections when warning level > 3
Added checking that thd->abort_on_warning is reset at end of query.
sql/sql_show.cc:
Update condition for when a query is 'killed'
storage/myisam/ha_myisam.cc:
Added counting of info/notes printed
storage/myisam/mi_check.c:
Always print an an error if we find data errors when checking/repairing a MyISAM table.
When a repair was killed, don't retry repair.
Added assert if sort_get_next_record() returned an error without an error message.
Removed nonsence check "if (sort_param->read_cache.error < 0)" in repair.
storage/myisam/myisamchk.c:
Added counting of notes printed
storage/pbxt/src/thread_xt.cc:
Better error message.
-rw-r--r-- | include/myisamchk.h | 2 | ||||
-rw-r--r-- | mysql-test/suite/parts/r/partition_repair_myisam.result | 1 | ||||
-rw-r--r-- | mysys/mf_iocache.c | 8 | ||||
-rw-r--r-- | sql/handler.cc | 7 | ||||
-rw-r--r-- | sql/log.cc | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 35 | ||||
-rw-r--r-- | sql/scheduler.cc | 11 | ||||
-rw-r--r-- | sql/slave.cc | 1 | ||||
-rw-r--r-- | sql/sp_head.cc | 9 | ||||
-rw-r--r-- | sql/sql_base.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.cc | 14 | ||||
-rw-r--r-- | sql/sql_class.h | 2 | ||||
-rw-r--r-- | sql/sql_connect.cc | 3 | ||||
-rw-r--r-- | sql/sql_insert.cc | 17 | ||||
-rw-r--r-- | sql/sql_parse.cc | 17 | ||||
-rw-r--r-- | sql/sql_show.cc | 8 | ||||
-rw-r--r-- | storage/myisam/ha_myisam.cc | 1 | ||||
-rw-r--r-- | storage/myisam/mi_check.c | 37 | ||||
-rw-r--r-- | storage/myisam/myisamchk.c | 1 | ||||
-rw-r--r-- | storage/pbxt/src/thread_xt.cc | 2 |
20 files changed, 127 insertions, 56 deletions
diff --git a/include/myisamchk.h b/include/myisamchk.h index 7d7100bdd71..e8f1ce576bf 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -144,7 +144,7 @@ typedef struct st_handler_check_param time_t backup_time; /* To sign backup files */ ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY]; double new_rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY]; - uint out_flag, warning_printed, error_printed, verbose; + uint out_flag, warning_printed, error_printed, note_printed, verbose; uint opt_sort_key, total_files, max_level; uint key_cache_block_size, pagecache_block_size; int tmpfile_createflag, err_count; diff --git a/mysql-test/suite/parts/r/partition_repair_myisam.result b/mysql-test/suite/parts/r/partition_repair_myisam.result index 4af00ddcc6d..058aff4ea4d 100644 --- a/mysql-test/suite/parts/r/partition_repair_myisam.result +++ b/mysql-test/suite/parts/r/partition_repair_myisam.result @@ -264,6 +264,7 @@ Table Op Msg_type Msg_text test.t1_will_crash analyze status OK OPTIMIZE TABLE t1_will_crash; Table Op Msg_type Msg_text +test.t1_will_crash optimize info Found row block followed by deleted block test.t1_will_crash optimize warning Number of rows changed from 8 to 7 test.t1_will_crash optimize status OK CHECK TABLE t1_will_crash; diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index bf7c208d4d2..876ee941f27 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -178,11 +178,9 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize, if ((pos == (my_off_t) -1) && (my_errno == ESPIPE)) { /* - This kind of object doesn't support seek() or tell(). Don't set a - flag that will make us again try to seek() later and fail. - */ - info->seek_not_done= 0; - /* + This kind of object doesn't support seek() or tell(). Don't set a + seek_not_done that will make us again try to seek() later and fail. + Additionally, if we're supposed to start somewhere other than the the beginning of whatever this file is, then somebody made a bad assumption. diff --git a/sql/handler.cc b/sql/handler.cc index f5e7de371a4..0e683d38511 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1350,9 +1350,14 @@ int ha_rollback_trans(THD *thd, bool all) slave SQL thread, it would not stop the thread but just be printed in the error log; but we don't want users to wonder why they have this message in the error log, so we don't send it. + + We don't have to test for thd->killed == THD::KILL_SYSTEM_THREAD as + it doesn't matter if a warning is pushed to a system thread or not: + No one will see it... */ if (is_real_trans && thd->transaction.all.modified_non_trans_table && - !thd->slave_thread && thd->killed != THD::KILL_CONNECTION) + !thd->slave_thread && thd->killed != THD::KILL_CONNECTION && + thd->killed != THD::KILL_SERVER) push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARNING_NOT_COMPLETE_ROLLBACK, ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)); diff --git a/sql/log.cc b/sql/log.cc index 5f6656f27de..12369640b72 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4919,7 +4919,8 @@ int query_error_code(THD *thd, bool not_killed) is not set to these errors when specified not_killed by the caller. */ - if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED) + if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED || + error == ER_NEW_ABORTING_CONNECTION) error= 0; } else diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7131188b306..9c16561e8b3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1968,6 +1968,17 @@ void close_connection(THD *thd, uint errcode, bool lock) if (lock) (void) pthread_mutex_lock(&LOCK_thread_count); thd->killed= THD::KILL_CONNECTION; + + if (global_system_variables.log_warnings > 3) + { + Security_context *sctx= &thd->main_security_ctx; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + thd->thread_id,(thd->db ? thd->db : "unconnected"), + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, + (errcode ? ER(errcode) : "CLOSE_CONNECTION")); + } + if ((vio= thd->net.vio) != 0) { if (errcode) @@ -2129,24 +2140,6 @@ void flush_thread_cache() } -#ifdef THREAD_SPECIFIC_SIGPIPE -/** - Aborts a thread nicely. Comes here on SIGPIPE. - - @todo - One should have to fix that thr_alarm know about this thread too. -*/ -extern "C" sig_handler abort_thread(int sig __attribute__((unused))) -{ - THD *thd=current_thd; - DBUG_ENTER("abort_thread"); - if (thd) - thd->killed= THD::KILL_CONNECTION; - DBUG_VOID_RETURN; -} -#endif - - /****************************************************************************** Setup a signal thread with handles all signals. Because Linux doesn't support schemas use a mutex to check that @@ -2681,6 +2674,12 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n", case THD::KILL_QUERY: kreason= "KILL_QUERY"; break; + case THD::KILL_SYSTEM_THREAD: + kreason= "KILL_SYSTEM_THREAD"; + break; + case THD::KILL_SERVER: + kreason= "KILL_SERVER"; + break; case THD::KILLED_NO_VALUE: kreason= "KILLED_NO_VALUE"; break; diff --git a/sql/scheduler.cc b/sql/scheduler.cc index 5b8f834aecc..6dd93640dc5 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -376,7 +376,9 @@ void libevent_kill_thd_callback(int Fd, short, void*) { THD *thd= (THD*)list->data; list= list_rest(list); - if (thd->killed == THD::KILL_CONNECTION) + if (thd->killed == THD::KILL_CONNECTION || + thd->killed == THD::KILL_SYSTEM_THREAD || + thd->killed == THD::KILL_SERVER) { /* Delete from libevent and add to the processing queue. @@ -531,9 +533,10 @@ static void libevent_connection_close(THD *thd) static bool libevent_should_close_connection(THD* thd) { - return thd->net.error || - thd->net.vio == 0 || - thd->killed == THD::KILL_CONNECTION; + return (thd->net.error || + thd->net.vio == 0 || + thd->killed == THD::KILL_CONNECTION || + thd->killed == THD::KILL_SERVER); } diff --git a/sql/slave.cc b/sql/slave.cc index 435f3d8b95f..439b9d8f4d3 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -837,6 +837,7 @@ bool is_network_error(uint errorno) errorno == CR_SERVER_GONE_ERROR || errorno == CR_SERVER_LOST || errorno == ER_CON_COUNT_ERROR || + errorno == ER_NEW_ABORTING_CONNECTION || errorno == ER_SERVER_SHUTDOWN) return TRUE; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index dbaeb9467ae..f4bcf500727 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -386,8 +386,8 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr) thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; thd->abort_on_warning= - thd->variables.sql_mode & - (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES); + test(thd->variables.sql_mode & + (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)); thd->transaction.stmt.modified_non_trans_table= FALSE; /* Save the value in the field. Convert the value if needed. */ @@ -1374,7 +1374,10 @@ sp_head::execute(THD *thd) If the DB has changed, the pointer has changed too, but the original thd->db will then have been freed */ - if (cur_db_changed && thd->killed != THD::KILL_CONNECTION) + if (cur_db_changed && + thd->killed != THD::KILL_CONNECTION && + thd->killed != THD::KILL_SERVER && + thd->killed != THD::KILL_SYSTEM_THREAD) { /* Force switching back to the saved current database, because it may be diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4826603c720..01649c88b6b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -8743,7 +8743,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, { if (!in_use->killed) { - in_use->killed= THD::KILL_CONNECTION; + in_use->killed= THD::KILL_SYSTEM_THREAD; pthread_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { @@ -9077,7 +9077,7 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) && ! in_use->killed) { - in_use->killed= THD::KILL_CONNECTION; + in_use->killed= THD::KILL_SYSTEM_THREAD; pthread_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0b6a3ebf85e..41e59489429 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1254,6 +1254,15 @@ void THD::awake(THD::killed_state state_to_set) THD_CHECK_SENTRY(this); safe_mutex_assert_owner(&LOCK_thd_data); + if (global_system_variables.log_warnings > 3) + { + Security_context *sctx= security_ctx; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + thread_id,(db ? db : "unconnected"), + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, + "KILLED"); + } killed= state_to_set; if (state_to_set != THD::KILL_QUERY) { @@ -3280,7 +3289,10 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup) */ extern "C" int thd_killed(const MYSQL_THD thd) { - return(thd->killed); + if (thd->killed == THD::NOT_KILLED || thd->killed == THD::KILL_BAD_DATA || + thd->killed == THD::KILL_SYSTEM_THREAD) + return 0; + return thd->killed; } /** diff --git a/sql/sql_class.h b/sql/sql_class.h index 53c1db1a527..57fc3883b1c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1838,7 +1838,9 @@ public: NOT_KILLED=0, KILL_BAD_DATA=1, KILL_CONNECTION=ER_SERVER_SHUTDOWN, + KILL_SYSTEM_THREAD=ER_NEW_ABORTING_CONNECTION, /* Kill connection nicely */ KILL_QUERY=ER_QUERY_INTERRUPTED, + KILL_SERVER, /* Placeholder for shortdown */ KILLED_NO_VALUE /* means neither of the states */ }; killed_state volatile killed; diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index be53c60e8ca..ec9ea31d0a4 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1180,7 +1180,8 @@ pthread_handler_t handle_one_connection(void *arg) prepare_new_connection_state(thd); while (!net->error && net->vio != 0 && - !(thd->killed == THD::KILL_CONNECTION)) + thd->killed != THD::KILL_CONNECTION && + thd->killed != THD::KILL_SERVER) { if (do_command(thd)) break; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1286c56f30e..ca0a7ab8d22 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2314,7 +2314,7 @@ void kill_delayed_threads(void) Delayed_insert *di; while ((di= it++)) { - di->thd.killed= THD::KILL_CONNECTION; + di->thd.killed= THD::KILL_SYSTEM_THREAD; pthread_mutex_lock(&di->thd.LOCK_thd_data); if (di->thd.mysys_var) { @@ -2399,7 +2399,8 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) for (;;) { - if (thd->killed == THD::KILL_CONNECTION) + if (thd->killed == THD::KILL_CONNECTION || + thd->killed == THD::KILL_SYSTEM_THREAD || thd->killed == THD::KILL_SERVER) { uint lock_count; /* @@ -2447,7 +2448,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) break; if (error == ETIMEDOUT || error == ETIME) { - thd->killed= THD::KILL_CONNECTION; + thd->killed= THD::KILL_SYSTEM_THREAD; break; } } @@ -2480,7 +2481,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) { /* Fatal error */ di->dead= 1; - thd->killed= THD::KILL_CONNECTION; + thd->killed= THD::KILL_SYSTEM_THREAD; } pthread_cond_broadcast(&di->cond_client); } @@ -2490,7 +2491,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di) { /* Some fatal error */ di->dead= 1; - thd->killed= THD::KILL_CONNECTION; + thd->killed= THD::KILL_SYSTEM_THREAD; } } di->status=0; @@ -2550,7 +2551,7 @@ pthread_handler_t handle_delayed_insert(void *arg) thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; thd->set_current_time(); threads.append(thd); - thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; + thd->killed=abort_loop ? THD::KILL_SYSTEM_THREAD : THD::NOT_KILLED; pthread_mutex_unlock(&LOCK_thread_count); /* @@ -2584,7 +2585,7 @@ end: di->table=0; di->dead= 1; // If error - thd->killed= THD::KILL_CONNECTION; // If error + thd->killed= THD::KILL_SYSTEM_THREAD; // If error pthread_mutex_unlock(&di->mutex); close_thread_tables(thd); // Free the table @@ -2663,7 +2664,7 @@ bool Delayed_insert::handle_inserts(void) max_rows= delayed_insert_limit; if (thd.killed || table->needs_reopen_or_name_lock()) { - thd.killed= THD::KILL_CONNECTION; + thd.killed= THD::KILL_SYSTEM_THREAD; max_rows= ULONG_MAX; // Do as much as possible } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 0fdc0b1690c..2050350d450 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -789,7 +789,17 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion) if (res < 0) my_error(thd->killed_errno(), MYF(0)); else if ((res == 0) && do_release) + { thd->killed= THD::KILL_CONNECTION; + if (global_system_variables.log_warnings > 3) + { + Security_context *sctx= &thd->main_security_ctx; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + thd->thread_id,(thd->db ? thd->db : "unconnected"), + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, "RELEASE"); + } + } DBUG_RETURN(res); } @@ -1670,6 +1680,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd_proc_info(thd, 0); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); + + /* Check that some variables are reset properly */ + DBUG_ASSERT(thd->abort_on_warning == 0); DBUG_RETURN(error); } @@ -7258,6 +7271,10 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query) If user of both killer and killee are non-NULL, proceed with slayage if both are string-equal. + + It's ok to also kill DELAYED threads with KILL_CONNECTION instead of + KILL_SYSTEM_THREAD; The difference is that KILL_CONNECTION may be + faster and do a harder kill than KILL_SYSTEM_THREAD; */ if ((thd->security_ctx->master_access & SUPER_ACL) || diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e10488cb87c..0c422632f35 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1935,7 +1935,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) pthread_mutex_lock(&tmp->LOCK_thd_data); if ((mysys_var= tmp->mysys_var)) pthread_mutex_lock(&mysys_var->mutex); - thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0); + thd_info->proc_info= (char*) (tmp->killed != THD::NOT_KILLED && + tmp->killed != THD::KILL_BAD_DATA ? + "Killed" : 0); #ifndef EMBEDDED_LIBRARY thd_info->state_info= (char*) (tmp->locked ? "Locked" : tmp->net.reading_or_writing ? @@ -2053,7 +2055,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) if ((mysys_var= tmp->mysys_var)) pthread_mutex_lock(&mysys_var->mutex); /* COMMAND */ - if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0))) + if ((val= (char *) ((tmp->killed != THD::NOT_KILLED && + tmp->killed != THD::KILL_BAD_DATA ? + "Killed" : 0)))) table->field[4]->store(val, strlen(val), cs); else table->field[4]->store(command_name[tmp->command].str, diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 84d9ce98cc4..13d59b63527 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -526,6 +526,7 @@ void mi_check_print_info(HA_CHECK *param, const char *fmt,...) va_list args; va_start(args, fmt); mi_check_print_msg(param, "info", fmt, args); + param->note_printed= 1; va_end(args); } diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index cde52dd473b..0e5da184f58 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -1346,7 +1346,7 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend) } if (param->testflag & T_INFO) { - if (param->warning_printed || param->error_printed) + if (param->warning_printed || param->error_printed || param->note_printed) puts(""); if (used != 0 && ! param->error_printed) { @@ -1540,8 +1540,7 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info, new_file= -1; sort_param.sort_info=&sort_info; param->retry_repair= 0; - param->warning_printed= 0; - param->error_printed= 0; + param->warning_printed= param->error_printed= param->note_printed= 0; if (!(param->testflag & T_SILENT)) { @@ -2248,8 +2247,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, } param->testflag|=T_REP; /* for easy checking */ param->retry_repair= 0; - param->warning_printed= 0; - param->error_printed= 0; + param->warning_printed= param->error_printed= param->note_printed= 0; if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)) param->testflag|=T_CALC_CHECKSUM; @@ -2577,6 +2575,8 @@ err: param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); + if (killed_ptr(param)) + param->retry_repair= 0; /* No use to retry repair */ } else if (key_map == share->state.key_map) share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS; @@ -3112,6 +3112,8 @@ err: param->retry_repair= 0; /* Safety */ } mi_mark_crashed_on_repair(info); + if (killed_ptr(param)) + param->retry_repair= 0; } else if (key_map == share->state.key_map) share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS; @@ -3147,7 +3149,13 @@ static int sort_key_read(MI_SORT_PARAM *sort_param, void *key) DBUG_ENTER("sort_key_read"); if ((error=sort_get_next_record(sort_param))) + { + DBUG_ASSERT(error < 0 || + sort_info->param->error_printed || + sort_info->param->warning_printed || + sort_info->param->note_printed); DBUG_RETURN(error); + } if (info->state->records == sort_info->max_records) { mi_check_print_error(sort_info->param, @@ -3264,7 +3272,12 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) DBUG_ENTER("sort_get_next_record"); if (killed_ptr(param)) + { + mi_check_print_error(param, "Repair killed by user with cause: %d", + (int) killed_ptr(param)); + param->retry_repair= 0; DBUG_RETURN(1); + } switch (share->data_file_type) { case BLOCK_RECORD: @@ -3353,6 +3366,8 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) } if (searching && ! sort_param->fix_datafile) { + mi_check_print_info(param, + "Datafile is corrupted; Restart repair with option to copy datafile"); param->error_printed=1; param->retry_repair=1; param->testflag|=T_RETRY_WITHOUT_QUICK; @@ -3414,6 +3429,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) } if (error) { + DBUG_ASSERT(param->note_printed); if (found_record) goto try_next; searching=1; @@ -3454,7 +3470,11 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) share->state.split++; } if (found_record) + { + mi_check_print_info(param, + "Found row block followed by deleted block"); goto try_next; + } if (searching) { pos+=MI_DYN_ALIGN_SIZE; @@ -3488,6 +3508,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) mi_check_print_error(param,"Not enough memory for blob at %s (need %lu)", llstr(sort_param->start_recpos,llbuff), (ulong) block_info.rec_len); + DBUG_ASSERT(param->error_printed); DBUG_RETURN(1); } else @@ -3569,8 +3590,6 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) if (_mi_rec_unpack(info,sort_param->record,sort_param->rec_buff, sort_param->find_length) != MY_FILE_ERROR) { - if (sort_param->read_cache.error < 0) - DBUG_RETURN(1); if (sort_param->calc_checksum) info->checksum= (*info->s->calc_check_checksum)(info, sort_param->record); @@ -3596,6 +3615,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) sort_param->key+1, llstr(sort_param->start_recpos,llbuff)); try_next: + DBUG_ASSERT(param->error_printed || param->note_printed); pos=(sort_param->start_recpos+=MI_DYN_ALIGN_SIZE); searching=1; } @@ -3664,6 +3684,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param) DBUG_RETURN(0); } } + DBUG_ASSERT(0); /* Impossible */ DBUG_RETURN(1); /* Impossible */ } @@ -3725,7 +3746,7 @@ int sort_write_record(MI_SORT_PARAM *sort_param) if (sort_info->buff_length < reclength) { if (!(sort_info->buff=my_realloc(sort_info->buff, (uint) reclength, - MYF(MY_FREE_ON_ERROR | + MYF(MY_FREE_ON_ERROR | MY_WME | MY_ALLOW_ZERO_PTR)))) DBUG_RETURN(1); sort_info->buff_length=reclength; diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index 8c54d7f0411..83a106c7941 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -1757,6 +1757,7 @@ void mi_check_print_info(HA_CHECK *param __attribute__((unused)), { va_list args; + param->note_printed=1; va_start(args,fmt); VOID(vfprintf(stdout, fmt, args)); VOID(fputc('\n',stdout)); diff --git a/storage/pbxt/src/thread_xt.cc b/storage/pbxt/src/thread_xt.cc index 52c2c6c29c5..985d33840d3 100644 --- a/storage/pbxt/src/thread_xt.cc +++ b/storage/pbxt/src/thread_xt.cc @@ -1175,7 +1175,7 @@ xtPublic XTThreadPtr xt_init_threading(u_int max_threads) #ifdef XT_TRACK_CONNECTIONS if (xt_thr_maximum_threads > XT_TRACK_MAX_CONNS) { xt_log_error(XT_NS_CONTEXT, XT_LOG_FATAL, XT_ERR_TOO_MANY_THREADS, 0, - "XT_TRACK_CONNECTIONS is enabled and xt_thr_maximum_threads > XT_TRACK_MAX_CONNS"); + "XT_TRACK_CONNECTIONS (debugging aid) is enabled and xt_thr_maximum_threads > XT_TRACK_MAX_CONNS. To continue restart with a smaller value for --max-connections"); goto failed; } #endif |