mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Bug #27571 asynchronousity in setting mysql_query::error and
Query_log_event::error_code A query can perform completely having the local var error of mysql_$query zero, where $query in insert, update, delete, load, and be binlogged with error_code e.g KILLED_QUERY while there is no reason do to so. That can happen because Query_log_event consults thd->killed flag to evaluate error_code. Fixed with implementing a scheme suggested and partly implemented at time of bug@22725 work-on. error_status is cached immediatly after the control leaves the main rows-loop and that instance always corresponds to `error' the local of mysql_$query functions. The cached value is passed to Query_log_event constructor, not the default thd->killed which can be changed in between of the caching and the constructing.
This commit is contained in:
@@ -85,7 +85,8 @@ static int read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
static bool write_execute_load_query_log_event(THD *thd,
|
||||
bool duplicates, bool ignore,
|
||||
bool transactional_table);
|
||||
bool transactional_table,
|
||||
THD::killed_state killed_status);
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
/*
|
||||
@@ -135,6 +136,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
char *tdb= thd->db ? thd->db : db; // Result is never null
|
||||
ulong skip_lines= ex->skip_lines;
|
||||
bool transactional_table;
|
||||
THD::killed_state killed_status= THD::NOT_KILLED;
|
||||
DBUG_ENTER("mysql_load");
|
||||
|
||||
#ifdef EMBEDDED_LIBRARY
|
||||
@@ -404,7 +406,16 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
free_blobs(table); /* if pack_blob was used */
|
||||
table->copy_blobs=0;
|
||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||
|
||||
/*
|
||||
simulated killing in the middle of per-row loop
|
||||
must be effective for binlogging
|
||||
*/
|
||||
DBUG_EXECUTE_IF("simulate_kill_bug27571",
|
||||
{
|
||||
error=1;
|
||||
thd->killed= THD::KILL_QUERY;
|
||||
};);
|
||||
killed_status= (error == 0)? THD::NOT_KILLED : thd->killed;
|
||||
/*
|
||||
We must invalidate the table in query cache before binlog writing and
|
||||
ha_autocommit_...
|
||||
@@ -446,7 +457,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
{
|
||||
if (thd->transaction.stmt.modified_non_trans_table)
|
||||
write_execute_load_query_log_event(thd, handle_duplicates,
|
||||
ignore, transactional_table);
|
||||
ignore, transactional_table,
|
||||
killed_status);
|
||||
else
|
||||
{
|
||||
Delete_file_log_event d(thd, db, transactional_table);
|
||||
@@ -477,7 +489,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
read_info.end_io_cache();
|
||||
if (lf_info.wrote_create_file)
|
||||
write_execute_load_query_log_event(thd, handle_duplicates,
|
||||
ignore, transactional_table);
|
||||
ignore, transactional_table,
|
||||
killed_status);
|
||||
}
|
||||
#endif /*!EMBEDDED_LIBRARY*/
|
||||
if (transactional_table)
|
||||
@@ -504,7 +517,8 @@ err:
|
||||
/* Not a very useful function; just to avoid duplication of code */
|
||||
static bool write_execute_load_query_log_event(THD *thd,
|
||||
bool duplicates, bool ignore,
|
||||
bool transactional_table)
|
||||
bool transactional_table,
|
||||
THD::killed_state killed_err_arg)
|
||||
{
|
||||
Execute_load_query_log_event
|
||||
e(thd, thd->query, thd->query_length,
|
||||
@@ -512,7 +526,7 @@ static bool write_execute_load_query_log_event(THD *thd,
|
||||
(char*)thd->lex->fname_end - (char*)thd->query,
|
||||
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
|
||||
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
|
||||
transactional_table, FALSE);
|
||||
transactional_table, FALSE, killed_err_arg);
|
||||
return mysql_bin_log.write(&e);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user