Commit 0b751edc authored by unknown's avatar unknown

Rollback UPDATE/DELETE statements on kill

nsure that rows in a multi-row INSERT DELAYED are inserted atomicly


mysql-test/mysql-test-run.sh:
  Make test case safe for openserver/unixware (Bug #2700)
sql/sql_delete.cc:
  Rollback statement on kill
sql/sql_insert.cc:
  Ensure that rows in a multi-row INSERT DELAYED are inserted atomicly (without releasing logs).
  This is needed to ensure that the mysqlbinlog is consistent.
  Bug #2491
sql/sql_list.h:
  Ensure that rows in a multi-row INSERT DELAYED is inserted atomicly (without releasing logs).
  This is needed to ensure that the mysqlbinlog is consistent.
  Bug #2491
sql/sql_update.cc:
  Rollback statement on kill
parent eadfe4dd
...@@ -17,7 +17,14 @@ MY_TZ=GMT-3 ...@@ -17,7 +17,14 @@ MY_TZ=GMT-3
TZ=$MY_TZ; export TZ # for UNIX_TIMESTAMP tests to work TZ=$MY_TZ; export TZ # for UNIX_TIMESTAMP tests to work
# For query_cache test # For query_cache test
ulimit -n 1024 case "$SYSTEM" in
SCO_SV | UnixWare | OpenUNIX )
# do nothing (Causes strange behavior)
;;
* )
ulimit -n 1024
;;
esac
#++ #++
# Program Definitions # Program Definitions
......
...@@ -167,6 +167,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, ...@@ -167,6 +167,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
else else
table->file->unlock_row(); // Row failed selection, release lock on it table->file->unlock_row(); // Row failed selection, release lock on it
} }
if (thd->killed && !error)
error= 1; // Aborted
thd->proc_info="end"; thd->proc_info="end";
end_read_record(&info); end_read_record(&info);
free_io_cache(table); // Will not do any harm free_io_cache(table); // Will not do any harm
...@@ -366,6 +368,7 @@ bool multi_delete::send_data(List<Item> &values) ...@@ -366,6 +368,7 @@ bool multi_delete::send_data(List<Item> &values)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
void multi_delete::send_error(uint errcode,const char *err) void multi_delete::send_error(uint errcode,const char *err)
{ {
DBUG_ENTER("multi_delete::send_error"); DBUG_ENTER("multi_delete::send_error");
...@@ -450,15 +453,13 @@ int multi_delete::do_deletes(bool from_send_error) ...@@ -450,15 +453,13 @@ int multi_delete::do_deletes(bool from_send_error)
if ((local_error=table->file->delete_row(table->record[0]))) if ((local_error=table->file->delete_row(table->record[0])))
{ {
table->file->print_error(local_error,MYF(0)); table->file->print_error(local_error,MYF(0));
if (transactional_tables)
{
DBUG_RETURN(local_error);
}
break; break;
} }
deleted++; deleted++;
} }
end_read_record(&info); end_read_record(&info);
if (thd->killed && !local_error)
local_error= 1;
if (local_error == -1) // End of file if (local_error == -1) // End of file
local_error = 0; local_error = 0;
} }
......
...@@ -1236,8 +1236,15 @@ bool delayed_insert::handle_inserts(void) ...@@ -1236,8 +1236,15 @@ bool delayed_insert::handle_inserts(void)
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
delete row; delete row;
/* Let READ clients do something once in a while */ /*
if (group_count++ == max_rows) Let READ clients do something once in a while
We should however not break in the middle of a multi-line insert
if we have binary logging enabled as we don't want other commands
on this table until all entries has been processed
*/
if (group_count++ >= max_rows && (row= rows.head()) &&
(!(row->log_query & DELAYED_LOG_BIN && using_bin_log) ||
row->query))
{ {
group_count=0; group_count=0;
if (stacked_inserts || tables_in_use) // Let these wait a while if (stacked_inserts || tables_in_use) // Let these wait a while
......
...@@ -322,6 +322,10 @@ class base_ilist ...@@ -322,6 +322,10 @@ class base_ilist
first_link->unlink(); // Unlink from list first_link->unlink(); // Unlink from list
return first_link; return first_link;
} }
inline struct ilink *head()
{
return (first != &last) ? first : 0;
}
friend class base_list_iterator; friend class base_list_iterator;
}; };
...@@ -353,6 +357,7 @@ class I_List :private base_ilist ...@@ -353,6 +357,7 @@ class I_List :private base_ilist
inline void append(T* a) { base_ilist::append(a); } inline void append(T* a) { base_ilist::append(a); }
inline void push_back(T* a) { base_ilist::push_back(a); } inline void push_back(T* a) { base_ilist::push_back(a); }
inline T* get() { return (T*) base_ilist::get(); } inline T* get() { return (T*) base_ilist::get(); }
inline T* head() { return (T*) base_ilist::head(); }
#ifndef _lint #ifndef _lint
friend class I_List_iterator<T>; friend class I_List_iterator<T>;
#endif #endif
......
...@@ -238,6 +238,8 @@ int mysql_update(THD *thd, ...@@ -238,6 +238,8 @@ int mysql_update(THD *thd,
} }
} }
} }
if (thd->killed && !error)
error= 1; // Aborted
limit= tmp_limit; limit= tmp_limit;
end_read_record(&info); end_read_record(&info);
/* Change select to use tempfile */ /* Change select to use tempfile */
...@@ -309,6 +311,8 @@ int mysql_update(THD *thd, ...@@ -309,6 +311,8 @@ int mysql_update(THD *thd,
else else
table->file->unlock_row(); table->file->unlock_row();
} }
if (thd->killed && !error)
error= 1; // Aborted
end_read_record(&info); end_read_record(&info);
free_io_cache(table); // If ORDER BY free_io_cache(table); // If ORDER BY
thd->proc_info="end"; thd->proc_info="end";
......
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