diff options
author | unknown <serg@serg.mylan> | 2003-08-21 10:45:43 +0200 |
---|---|---|
committer | unknown <serg@serg.mylan> | 2003-08-21 10:45:43 +0200 |
commit | 943233632e6afb8ad5da2c654cd2462b53db2563 (patch) | |
tree | 07366defe2bd16c540a1dc344f5517406d2f2fe1 /sql | |
parent | c7f517b53f0074ca131e5747e176ebce18cc6171 (diff) | |
parent | fd9b1775642e4da09697fd46a7bbb98d59b9843f (diff) | |
download | mariadb-git-943233632e6afb8ad5da2c654cd2462b53db2563.tar.gz |
Merge bk-internal:/home/bk/mysql-4.0/
into serg.mylan:/usr/home/serg/Abk/mysql-4.0
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 7 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 1 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 17 | ||||
-rw-r--r-- | sql/item_sum.cc | 67 | ||||
-rw-r--r-- | sql/item_sum.h | 32 | ||||
-rw-r--r-- | sql/item_uniq.h | 2 | ||||
-rw-r--r-- | sql/log.cc | 4 | ||||
-rw-r--r-- | sql/log_event.cc | 74 | ||||
-rw-r--r-- | sql/log_event.h | 26 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/net_serv.cc | 27 | ||||
-rw-r--r-- | sql/repl_failsafe.cc | 15 | ||||
-rw-r--r-- | sql/slave.cc | 81 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/sql_load.cc | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 1 | ||||
-rw-r--r-- | sql/sql_repl.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 | ||||
-rw-r--r-- | sql/sql_union.cc | 65 |
20 files changed, 254 insertions, 177 deletions
diff --git a/sql/field.cc b/sql/field.cc index e56d53b1bda..592252bb294 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4147,8 +4147,11 @@ void Field_blob::store(const char *from,uint len) } } #endif /* USE_TIS620 */ - value.copy(from,len); - from=value.ptr(); + if (from != value.ptr()) // For valgrind + { + value.copy(from, len); + from= value.ptr(); + } #ifdef USE_TIS620 my_free(th_ptr,MYF(MY_ALLOW_ZERO_PTR)); #endif diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 09119a4eb54..3619fefdd1b 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -28,7 +28,6 @@ InnoDB */ #include "mysql_priv.h" #include "slave.h" -#include "sql_cache.h" #ifdef HAVE_INNOBASE_DB #include <m_ctype.h> diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8c58c58a67d..7415fc5b98e 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1045,15 +1045,18 @@ void Item_func_in::fix_length_and_dec() array= new in_double(arg_count); break; } - uint j=0; - for (uint i=0 ; i < arg_count ; i++) + if (array && !(current_thd->fatal_error)) // If not EOM { - array->set(j,args[i]); - if (!args[i]->null_value) // Skip NULL values - j++; + uint j=0; + for (uint i=0 ; i < arg_count ; i++) + { + array->set(j,args[i]); + if (!args[i]->null_value) // Skip NULL values + j++; + } + if ((array->used_count=j)) + array->sort(); } - if ((array->used_count=j)) - array->sort(); } else { diff --git a/sql/item_sum.cc b/sql/item_sum.cc index d88894d4fb4..08385bb9ca6 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -300,15 +300,15 @@ void Item_sum_std::reset_field() } } -void Item_sum_std::update_field(int offset) +void Item_sum_std::update_field() { double nr,old_nr,old_sqr; longlong field_count; char *res=result_field->ptr; - float8get(old_nr,res+offset); - float8get(old_sqr,res+offset+sizeof(double)); - field_count=sint8korr(res+offset+sizeof(double)*2); + float8get(old_nr, res); + float8get(old_sqr, res+sizeof(double)); + field_count=sint8korr(res+sizeof(double)*2); nr=args[0]->val(); if (!args[0]->null_value) @@ -619,12 +619,12 @@ void Item_sum_bit::reset_field() ** calc next value and merge it with field_value */ -void Item_sum_sum::update_field(int offset) +void Item_sum_sum::update_field() { double old_nr,nr; char *res=result_field->ptr; - float8get(old_nr,res+offset); + float8get(old_nr,res); nr=args[0]->val(); if (!args[0]->null_value) { @@ -635,12 +635,12 @@ void Item_sum_sum::update_field(int offset) } -void Item_sum_count::update_field(int offset) +void Item_sum_count::update_field() { longlong nr; char *res=result_field->ptr; - nr=sint8korr(res+offset); + nr=sint8korr(res); if (!args[0]->maybe_null) nr++; else @@ -653,14 +653,14 @@ void Item_sum_count::update_field(int offset) } -void Item_sum_avg::update_field(int offset) +void Item_sum_avg::update_field() { double nr,old_nr; longlong field_count; char *res=result_field->ptr; - float8get(old_nr,res+offset); - field_count=sint8korr(res+offset+sizeof(double)); + float8get(old_nr,res); + field_count=sint8korr(res+sizeof(double)); nr=args[0]->val(); if (!args[0]->null_value) @@ -673,78 +673,66 @@ void Item_sum_avg::update_field(int offset) int8store(res,field_count); } -void Item_sum_hybrid::update_field(int offset) +void Item_sum_hybrid::update_field() { if (hybrid_type == STRING_RESULT) - min_max_update_str_field(offset); + min_max_update_str_field(); else if (hybrid_type == INT_RESULT) - min_max_update_int_field(offset); + min_max_update_int_field(); else - min_max_update_real_field(offset); + min_max_update_real_field(); } void -Item_sum_hybrid::min_max_update_str_field(int offset) +Item_sum_hybrid::min_max_update_str_field() { String *res_str=args[0]->val_str(&value); - if (args[0]->null_value) - result_field->copy_from_tmp(offset); // Use old value - else + if (!args[0]->null_value) { res_str->strip_sp(); - result_field->ptr+=offset; // Get old max/min result_field->val_str(&tmp_value,&tmp_value); - result_field->ptr-=offset; if (result_field->is_null() || (cmp_sign * (binary ? stringcmp(res_str,&tmp_value) : sortcmp(res_str,&tmp_value)) < 0)) result_field->store(res_str->ptr(),res_str->length()); - else - { // Use old value - char *res=result_field->ptr; - memcpy(res,res+offset,result_field->pack_length()); - } result_field->set_notnull(); } } void -Item_sum_hybrid::min_max_update_real_field(int offset) +Item_sum_hybrid::min_max_update_real_field() { double nr,old_nr; - result_field->ptr+=offset; old_nr=result_field->val_real(); nr=args[0]->val(); if (!args[0]->null_value) { - if (result_field->is_null(offset) || + if (result_field->is_null(0) || (cmp_sign > 0 ? old_nr > nr : old_nr < nr)) old_nr=nr; result_field->set_notnull(); } - else if (result_field->is_null(offset)) + else if (result_field->is_null(0)) result_field->set_null(); - result_field->ptr-=offset; result_field->store(old_nr); } void -Item_sum_hybrid::min_max_update_int_field(int offset) +Item_sum_hybrid::min_max_update_int_field() { longlong nr,old_nr; - result_field->ptr+=offset; old_nr=result_field->val_int(); nr=args[0]->val_int(); if (!args[0]->null_value) { - if (result_field->is_null(offset)) + if (result_field->is_null(0)) old_nr=nr; else { @@ -757,30 +745,29 @@ Item_sum_hybrid::min_max_update_int_field(int offset) } result_field->set_notnull(); } - else if (result_field->is_null(offset)) + else if (result_field->is_null(0)) result_field->set_null(); - result_field->ptr-=offset; result_field->store(old_nr); } -void Item_sum_or::update_field(int offset) +void Item_sum_or::update_field() { ulonglong nr; char *res=result_field->ptr; - nr=uint8korr(res+offset); + nr=uint8korr(res); nr|= (ulonglong) args[0]->val_int(); int8store(res,nr); } -void Item_sum_and::update_field(int offset) +void Item_sum_and::update_field() { ulonglong nr; char *res=result_field->ptr; - nr=uint8korr(res+offset); + nr=uint8korr(res); nr&= (ulonglong) args[0]->val_int(); int8store(res,nr); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 2369b5d1d7e..5189566fdfb 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -56,7 +56,7 @@ public: virtual void reset()=0; virtual bool add()=0; virtual void reset_field()=0; - virtual void update_field(int offset)=0; + virtual void update_field()=0; virtual bool keep_field_type(void) const { return 0; } virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } virtual const char *func_name() const { return "?"; } @@ -116,7 +116,7 @@ class Item_sum_sum :public Item_sum_num bool add(); double val(); void reset_field(); - void update_field(int offset); + void update_field(); void no_rows_in_result() {} const char *func_name() const { return "sum"; } unsigned int size_of() { return sizeof(*this);} @@ -141,7 +141,7 @@ class Item_sum_count :public Item_sum_int void make_const(longlong count_arg) { count=count_arg; used_table_cache=0; } longlong val_int(); void reset_field(); - void update_field(int offset); + void update_field(); const char *func_name() const { return "count"; } unsigned int size_of() { return sizeof(*this);} }; @@ -193,7 +193,7 @@ class Item_sum_count_distinct :public Item_sum_int bool add(); longlong val_int(); void reset_field() { return ;} // Never called - void update_field(int offset) { return ; } // Never called + void update_field() { return ; } // Never called const char *func_name() const { return "count_distinct"; } bool setup(THD *thd); void no_rows_in_result() {} @@ -235,7 +235,7 @@ class Item_sum_avg :public Item_sum_num bool add(); double val(); void reset_field(); - void update_field(int offset); + void update_field(); Item *result_item(Field *field) { return new Item_avg_field(this); } const char *func_name() const { return "avg"; } @@ -273,7 +273,7 @@ class Item_sum_std :public Item_sum_num bool add(); double val(); void reset_field(); - void update_field(int offset); + void update_field(); Item *result_item(Field *field) { return new Item_std_field(this); } const char *func_name() const { return "std"; } @@ -316,10 +316,10 @@ class Item_sum_hybrid :public Item_sum void make_const() { used_table_cache=0; } bool keep_field_type(void) const { return 1; } enum Item_result result_type () const { return hybrid_type; } - void update_field(int offset); - void min_max_update_str_field(int offset); - void min_max_update_real_field(int offset); - void min_max_update_int_field(int offset); + void update_field(); + void min_max_update_str_field(); + void min_max_update_real_field(); + void min_max_update_int_field(); unsigned int size_of() { return sizeof(*this);} }; @@ -371,7 +371,7 @@ class Item_sum_or :public Item_sum_bit public: Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {} bool add(); - void update_field(int offset); + void update_field(); const char *func_name() const { return "bit_or"; } unsigned int size_of() { return sizeof(*this);} }; @@ -382,7 +382,7 @@ class Item_sum_and :public Item_sum_bit public: Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ~(ulonglong) LL(0)) {} bool add(); - void update_field(int offset); + void update_field(); const char *func_name() const { return "bit_and"; } unsigned int size_of() { return sizeof(*this);} }; @@ -414,7 +414,7 @@ public: void reset(); bool add(); void reset_field() {}; - void update_field(int offset_arg) {}; + void update_field() {}; unsigned int size_of() { return sizeof(*this);} }; @@ -482,7 +482,7 @@ class Item_sum_udf_float :public Item_sum_num double val() { return 0.0; } void reset() {} bool add() { return 0; } - void update_field(int offset) {} + void update_field() {} }; @@ -497,7 +497,7 @@ public: double val() { return 0; } void reset() {} bool add() { return 0; } - void update_field(int offset) {} + void update_field() {} }; @@ -515,7 +515,7 @@ public: enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } void reset() {} bool add() { return 0; } - void update_field(int offset) {} + void update_field() {} }; #endif /* HAVE_DLOPEN */ diff --git a/sql/item_uniq.h b/sql/item_uniq.h index cc087832f49..de239d3a8ec 100644 --- a/sql/item_uniq.h +++ b/sql/item_uniq.h @@ -42,7 +42,7 @@ public: void reset() {} bool add() { return 0; } void reset_field() {} - void update_field(int offset) {} + void update_field() {} bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;} unsigned int size_of() { return sizeof(*this);} }; diff --git a/sql/log.cc b/sql/log.cc index 4dce26d23ea..ee774ea3700 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -263,7 +263,8 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, an extension for the binary log files. In this case we write a standard header to it. */ - if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC, BIN_LOG_HEADER_SIZE)) + if (my_b_safe_write(&log_file, (byte*) BINLOG_MAGIC, + BIN_LOG_HEADER_SIZE)) goto err; bytes_written += BIN_LOG_HEADER_SIZE; write_file_name_to_index_file=1; @@ -1067,6 +1068,7 @@ bool MYSQL_LOG::write(Log_event* event_info) #else IO_CACHE *file = &log_file; #endif + DBUG_PRINT("info",("event type=%d",event_info->get_type_code())); /* In the future we need to add to the following if tests like "do the involved tables match (to be implemented) diff --git a/sql/log_event.cc b/sql/log_event.cc index 2a1669737f8..9e7546dd635 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -119,12 +119,11 @@ const char* Log_event::get_type_str() #ifndef MYSQL_CLIENT Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans) - :temp_buf(0), exec_time(0), cached_event_len(0), flags(flags_arg), - thd(thd_arg) + :log_pos(0), temp_buf(0), exec_time(0), cached_event_len(0), + flags(flags_arg), thd(thd_arg) { server_id = thd->server_id; when = thd->start_time; - log_pos = thd->log_pos; cache_stmt= (using_trans && (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))); } @@ -1606,11 +1605,12 @@ void Create_file_log_event::pack_info(String* packet) #endif #ifndef MYSQL_CLIENT -Append_block_log_event::Append_block_log_event(THD* thd_arg, char* block_arg, +Append_block_log_event::Append_block_log_event(THD* thd_arg, const char* db_arg, + char* block_arg, uint block_len_arg, bool using_trans) :Log_event(thd_arg,0, using_trans), block(block_arg), - block_len(block_len_arg), file_id(thd_arg->file_id) + block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg) { } #endif @@ -1654,8 +1654,9 @@ void Append_block_log_event::pack_info(String* packet) net_store_data(packet, buf1); } -Delete_file_log_event::Delete_file_log_event(THD* thd_arg, bool using_trans) - :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id) +Delete_file_log_event::Delete_file_log_event(THD* thd_arg, const char* db_arg, + bool using_trans) + :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg) { } #endif @@ -1700,8 +1701,9 @@ void Delete_file_log_event::pack_info(String* packet) #ifndef MYSQL_CLIENT -Execute_load_log_event::Execute_load_log_event(THD* thd_arg, bool using_trans) - :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id) +Execute_load_log_event::Execute_load_log_event(THD* thd_arg, const char* db_arg, + bool using_trans) + :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg) { } #endif @@ -1905,7 +1907,19 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, DBUG_ASSERT(thd->query == 0); thd->query = 0; // Should not be needed thd->query_error = 0; - + + /* + We test replicate_*_db rules. Note that we have already prepared the file to + load, even if we are going to ignore and delete it now. So it is possible + that we did a lot of disk writes for nothing. In other words, a big LOAD + DATA INFILE on the master will still consume a lot of space on the slave + (space in the relay log + space of temp files: twice the space of the file + to load...) even if it will finally be ignored. + TODO: fix this; this can be done by testing rules in + Create_file_log_event::exec_event() and then discarding Append_block and + al. Another way is do the filtering in the I/O thread (more efficient: no + disk writes at all). + */ if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); @@ -2210,7 +2224,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf); + slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf); goto err; } @@ -2221,7 +2235,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) if (write_base(&file)) { strmov(p, ".info"); // to have it right in the error message - slave_print_error(rli,my_errno, "Could not write to file '%s'", fname_buf); + slave_print_error(rli,my_errno, "Error in Create_file event: could not write to file '%s'", fname_buf); goto err; } end_io_cache(&file); @@ -2231,16 +2245,14 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) if ((fd = my_open(fname_buf, O_WRONLY|O_CREAT|O_BINARY|O_TRUNC, MYF(MY_WME))) < 0) { - slave_print_error(rli,my_errno, "Could not open file '%s'", fname_buf); + slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf); goto err; } if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP))) { - slave_print_error(rli,my_errno, "Write to '%s' failed", fname_buf); + slave_print_error(rli,my_errno, "Error in Create_file event: write to '%s' failed", fname_buf); goto err; } - if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); error=0; // Everything is ok err: @@ -2259,8 +2271,6 @@ int Delete_file_log_event::exec_event(struct st_relay_log_info* rli) (void) my_delete(fname, MYF(MY_WME)); memcpy(p, ".info", 6); (void) my_delete(fname, MYF(MY_WME)); - if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); return Log_event::exec_event(rli); } @@ -2274,16 +2284,14 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli) memcpy(p, ".data", 6); if ((fd = my_open(fname, O_WRONLY|O_APPEND|O_BINARY, MYF(MY_WME))) < 0) { - slave_print_error(rli,my_errno, "Could not open file '%s'", fname); + slave_print_error(rli,my_errno, "Error in Append_block event: could not open file '%s'", fname); goto err; } if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP))) { - slave_print_error(rli,my_errno, "Write to '%s' failed", fname); + slave_print_error(rli,my_errno, "Error in Append_block event: write to '%s' failed", fname); goto err; } - if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); error=0; err: @@ -2298,7 +2306,6 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) char *p= slave_load_file_stem(fname, file_id, server_id); int fd; int error = 1; - ulong save_options; IO_CACHE file; Load_log_event* lev = 0; @@ -2307,7 +2314,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0, MYF(MY_WME|MY_NABP))) { - slave_print_error(rli,my_errno, "Could not open file '%s'", fname); + slave_print_error(rli,my_errno, "Error in Exec_load event: could not open file '%s'", fname); goto err; } if (!(lev = (Load_log_event*)Log_event::read_log_event(&file, @@ -2315,21 +2322,16 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) (bool)0)) || lev->get_type_code() != NEW_LOAD_EVENT) { - slave_print_error(rli,0, "File '%s' appears corrupted", fname); + slave_print_error(rli,0, "Error in Exec_load event: file '%s' appears corrupted", fname); goto err; } - /* - We want to disable binary logging in slave thread because we need the file - events to appear in the same order as they do on the master relative to - other events, so that we can preserve ascending order of log sequence - numbers - needed to handle failover . - */ - save_options = thd->options; - thd->options &= ~ (ulong) (OPTION_BIN_LOG); + lev->thd = thd; /* lev->exec_event should use rli only for errors - i.e. should not advance rli's position + i.e. should not advance rli's position. + lev->exec_event is the place where the table is loaded (it calls + mysql_load()). */ if (lev->exec_event(0,rli,1)) { @@ -2350,15 +2352,11 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) tmp, fname); my_free(tmp,MYF(0)); } - thd->options= save_options; goto err; } - thd->options = save_options; (void) my_delete(fname, MYF(MY_WME)); memcpy(p, ".data", 6); (void) my_delete(fname, MYF(MY_WME)); - if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); error = 0; err: diff --git a/sql/log_event.h b/sql/log_event.h index 1031b940528..227c0243b9c 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -687,9 +687,20 @@ public: char* block; uint block_len; uint file_id; - + /* + 'db' is filled when the event is created in mysql_load() (the event needs to + have a 'db' member to be well filtered by binlog-*-db rules). 'db' is not + written to the binlog (it's not used by Append_block_log_event::write()), so + it can't be read in the Append_block_log_event(const char* buf, int + event_len) constructor. + In other words, 'db' is used only for filtering by binlog-*-db rules. + Create_file_log_event is different: its 'db' (which is inherited from + Load_log_event) is written to the binlog and can be re-read. + */ + const char* db; + #ifndef MYSQL_CLIENT - Append_block_log_event(THD* thd, char* block_arg, + Append_block_log_event(THD* thd, const char* db_arg, char* block_arg, uint block_len_arg, bool using_trans); int exec_event(struct st_relay_log_info* rli); void pack_info(String* packet); @@ -703,6 +714,7 @@ public: int get_data_size() { return block_len + APPEND_BLOCK_HEADER_LEN ;} bool is_valid() { return block != 0; } int write_data(IO_CACHE* file); + const char* get_db() { return db; } }; @@ -710,9 +722,10 @@ class Delete_file_log_event: public Log_event { public: uint file_id; + const char* db; /* see comment in Append_block_log_event */ #ifndef MYSQL_CLIENT - Delete_file_log_event(THD* thd, bool using_trans); + Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans); void pack_info(String* packet); int exec_event(struct st_relay_log_info* rli); #else @@ -725,15 +738,17 @@ public: int get_data_size() { return DELETE_FILE_HEADER_LEN ;} bool is_valid() { return file_id != 0; } int write_data(IO_CACHE* file); + const char* get_db() { return db; } }; class Execute_load_log_event: public Log_event { public: uint file_id; - + const char* db; /* see comment in Append_block_log_event */ + #ifndef MYSQL_CLIENT - Execute_load_log_event(THD* thd, bool using_trans); + Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans); void pack_info(String* packet); int exec_event(struct st_relay_log_info* rli); #else @@ -746,6 +761,7 @@ public: int get_data_size() { return EXEC_LOAD_HEADER_LEN ;} bool is_valid() { return file_id != 0; } int write_data(IO_CACHE* file); + const char* get_db() { return db; } }; #ifdef MYSQL_CLIENT diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d9ba97ad11a..b90ab1a4a3a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3833,7 +3833,7 @@ replicating a LOAD DATA INFILE command", "Max packetlength to send/receive from to server.", (gptr*) &global_system_variables.max_allowed_packet, (gptr*) &max_system_variables.max_allowed_packet, 0, GET_ULONG, - REQUIRED_ARG, 1024*1024L, 80, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, + REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0}, {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE, "Can be used to restrict the total size used to cache a multi-transaction query.", (gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0, diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 13f786e0e75..8f0d659daf2 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -215,10 +215,12 @@ int net_flush(NET *net) *****************************************************************************/ /* -** Write a logical packet with packet header -** Format: Packet length (3 bytes), packet number(1 byte) -** When compression is used a 3 byte compression length is added -** NOTE: If compression is used the original package is modified! + Write a logical packet with packet header + Format: Packet length (3 bytes), packet number(1 byte) + When compression is used a 3 byte compression length is added + + NOTE + If compression is used the original package is modified! */ int @@ -315,8 +317,8 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) The cached buffer can be sent as it is with 'net_flush()'. In this code we have to be careful to not send a packet longer than - MAX_PACKET_LENGTH to net_real_write() if we are using the compressed protocol - as we store the length of the compressed packet in 3 bytes. + MAX_PACKET_LENGTH to net_real_write() if we are using the compressed + protocol as we store the length of the compressed packet in 3 bytes. RETURN 0 ok @@ -821,20 +823,23 @@ my_net_read(NET *net) { /* We are using the compressed protocol */ - ulong buf_length= net->buf_length; - ulong start_of_packet= net->buf_length - net->remain_in_buf; - ulong first_packet_offset=start_of_packet; + ulong buf_length; + ulong start_of_packet; + ulong first_packet_offset; uint read_length, multi_byte_packet=0; if (net->remain_in_buf) { + buf_length= net->buf_length; // Data left in old packet + first_packet_offset= start_of_packet= (net->buf_length - + net->remain_in_buf); /* Restore the character that was overwritten by the end 0 */ - net->buff[start_of_packet]=net->save_char; + net->buff[start_of_packet]= net->save_char; } else { /* reuse buffer, as there is nothing in it that we need */ - buf_length=start_of_packet=first_packet_offset=0; + buf_length= start_of_packet= first_packet_offset= 0; } for (;;) { diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 0a5f90617d1..dc3f3c87dde 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -249,6 +249,18 @@ static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg) /* Impossible */ } +/* + Before 4.0.15 we had a member of THD called log_pos, it was meant for + failsafe replication code in repl_failsafe.cc which is disabled until + it is reworked. Event's log_pos used to be preserved through + log-slave-updates to make code in repl_failsafe.cc work (this + function, SHOW NEW MASTER); but on the other side it caused unexpected + values in Exec_master_log_pos in A->B->C replication setup, + synchronization problems in master_pos_wait(), ... So we + (Dmitri & Guilhem) removed it. + + So for now this function is broken. +*/ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) { @@ -414,6 +426,9 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, return (Slave_log_event*)ev; } +/* + This function is broken now. See comment for translate_master(). + */ int show_new_master(THD* thd) { diff --git a/sql/slave.cc b/sql/slave.cc index 85a9bc0d49e..32ed228e119 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2253,7 +2253,6 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) if (!ev->when) ev->when = time(NULL); ev->thd = thd; - thd->log_pos = ev->log_pos; exec_res = ev->exec_event(rli); DBUG_ASSERT(rli->sql_thd==thd); delete ev; @@ -2758,7 +2757,7 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) if (unlikely(net_request_file(net,cev->fname))) { sql_print_error("Slave I/O: failed requesting download of '%s'", - cev->fname); + cev->fname); goto err; } @@ -2768,56 +2767,56 @@ static int process_io_create_file(MASTER_INFO* mi, Create_file_log_event* cev) in the loop */ { - Append_block_log_event aev(thd,0,0,0); + Append_block_log_event aev(thd,0,0,0,0); for (;;) { if (unlikely((num_bytes=my_net_read(net)) == packet_error)) { - sql_print_error("Network read error downloading '%s' from master", - cev->fname); - goto err; + sql_print_error("Network read error downloading '%s' from master", + cev->fname); + goto err; } if (unlikely(!num_bytes)) /* eof */ { - send_ok(net); /* 3.23 master wants it */ - Execute_load_log_event xev(thd,0); - xev.log_pos = mi->master_log_pos; - if (unlikely(mi->rli.relay_log.append(&xev))) - { - sql_print_error("Slave I/O: error writing Exec_load event to \ + send_ok(net); /* 3.23 master wants it */ + Execute_load_log_event xev(thd,0,0); + xev.log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(&xev))) + { + sql_print_error("Slave I/O: error writing Exec_load event to \ relay log"); - goto err; - } - mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); - break; + goto err; + } + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); + break; } if (unlikely(cev_not_written)) { - cev->block = (char*)net->read_pos; - cev->block_len = num_bytes; - cev->log_pos = mi->master_log_pos; - if (unlikely(mi->rli.relay_log.append(cev))) - { - sql_print_error("Slave I/O: error writing Create_file event to \ + cev->block = (char*)net->read_pos; + cev->block_len = num_bytes; + cev->log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(cev))) + { + sql_print_error("Slave I/O: error writing Create_file event to \ relay log"); - goto err; - } - cev_not_written=0; - mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); + goto err; + } + cev_not_written=0; + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); } else { - aev.block = (char*)net->read_pos; - aev.block_len = num_bytes; - aev.log_pos = mi->master_log_pos; - if (unlikely(mi->rli.relay_log.append(&aev))) - { - sql_print_error("Slave I/O: error writing Append_block event to \ + aev.block = (char*)net->read_pos; + aev.block_len = num_bytes; + aev.log_pos = mi->master_log_pos; + if (unlikely(mi->rli.relay_log.append(&aev))) + { + sql_print_error("Slave I/O: error writing Append_block event to \ relay log"); - goto err; - } - mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ; + goto err; + } + mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total) ; } } } @@ -2901,6 +2900,12 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, tmp_buf[event_len]=0; // Create_file constructor wants null-term buffer buf = (const char*)tmp_buf; } + /* + This will transform LOAD_EVENT into CREATE_FILE_EVENT, ask the master to + send the loaded file, and write it to the relay log in the form of + Append_block/Exec_load (the SQL thread needs the data, as that thread is not + connected to the master). + */ Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg, 1 /*old format*/ ); if (unlikely(!ev)) @@ -2930,6 +2935,12 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, inc_pos= 0; break; case CREATE_FILE_EVENT: + /* + Yes it's possible to have CREATE_FILE_EVENT here, even if we're in + queue_old_event() which is for 3.23 events which don't comprise + CREATE_FILE_EVENT. This is because read_log_event() above has just + transformed LOAD_EVENT into CREATE_FILE_EVENT. + */ { /* We come here when and only when tmp_buf != 0 */ DBUG_ASSERT(tmp_buf); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2a65291c273..132e0d7745f 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -125,7 +125,6 @@ THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), where="field list"; server_id = ::server_id; slave_net = 0; - log_pos = 0; command=COM_CONNECT; set_query_id=1; db_access=NO_ACCESS; diff --git a/sql/sql_class.h b/sql/sql_class.h index c4511652b23..49a364856eb 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -472,7 +472,6 @@ public: */ ulong slave_proxy_id; NET* slave_net; // network connection from slave -> m. - my_off_t log_pos; /* Used by the sys_var class to store temporary values */ union diff --git a/sql/sql_load.cc b/sql/sql_load.cc index ee573672c35..593cfb82b1c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -299,7 +299,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, which is nonsense. */ read_info.end_io_cache(); - Delete_file_log_event d(thd, log_delayed); + Delete_file_log_event d(thd, db, log_delayed); mysql_bin_log.write(&d); } } @@ -331,7 +331,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, read_info.end_io_cache(); // make sure last block gets logged if (lf_info.wrote_create_file) { - Execute_load_log_event e(thd, log_delayed); + Execute_load_log_event e(thd, db, log_delayed); mysql_bin_log.write(&e); } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1d82ac6110b..1479a611b5a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1458,6 +1458,7 @@ mysql_execute_command(void) { if (check_global_access(thd, REPL_SLAVE_ACL)) goto error; + /* This query don't work now. See comment in repl_failsafe.cc */ #ifndef WORKING_NEW_MASTER net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "SHOW NEW MASTER"); res= 1; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index cdd0bca4a0e..5a42614dff4 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1216,7 +1216,7 @@ int log_loaded_block(IO_CACHE* file) lf_info->last_pos_in_file = file->pos_in_file; if (lf_info->wrote_create_file) { - Append_block_log_event a(lf_info->thd, buffer, block_len, + Append_block_log_event a(lf_info->thd, lf_info->db, buffer, block_len, lf_info->log_delayed); mysql_bin_log.write(&a); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7922af04ea8..560f5f5dc79 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7224,7 +7224,7 @@ update_tmptable_sum_func(Item_sum **func_ptr, { Item_sum *func; while ((func= *(func_ptr++))) - func->update_field(0); + func->update_field(); } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index bd7bc7027d3..34acd79f18b 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -31,9 +31,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ORDER *order; List<Item> item_list; TABLE *table; - int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0; int res; - bool found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS; + ulonglong add_rows= 0; + ulong found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS; + ulong describe= lex->select_lex.options & SELECT_DESCRIBE; TABLE_LIST result_table_list; TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first; TMP_TABLE_PARAM tmp_table_param; @@ -135,14 +136,44 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) union_result->tmp_table_param=&tmp_table_param; for (sl= &lex->select_lex; sl; sl=sl->next) { + ha_rows records_at_start; lex->select=sl; - thd->offset_limit=sl->offset_limit; - thd->select_limit=sl->select_limit+sl->offset_limit; + /* Don't use offset for the last union if there is no braces */ + if (sl != lex_sl) + { + thd->offset_limit= sl->offset_limit; + thd->select_limit=sl->select_limit+sl->offset_limit; + } + else + { + thd->offset_limit= 0; + /* + We can't use LIMIT at this stage if we are using ORDER BY for the + whole query + */ + thd->select_limit= HA_POS_ERROR; + if (! sl->order_list.first) + thd->select_limit= sl->select_limit+sl->offset_limit; + } if (thd->select_limit < sl->select_limit) thd->select_limit= HA_POS_ERROR; // no limit + + /* + When using braces, SQL_CALC_FOUND_ROWS affects the whole query. + We don't calculate found_rows() per union part + */ if (thd->select_limit == HA_POS_ERROR || sl->braces) sl->options&= ~OPTION_FOUND_ROWS; + else + { + /* + We are doing an union without braces. In this case + SQL_CALC_FOUND_ROWS should be done on all sub parts + */ + sl->options|= found_rows_for_union; + } + records_at_start= table->file->records; res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ? first_table : (TABLE_LIST*) sl->table_list.first, sl->item_list, @@ -153,10 +184,23 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) sl->having, (ORDER*) NULL, sl->options | thd->options | SELECT_NO_UNLOCK | - ((describe) ? SELECT_DESCRIBE : 0), + describe, union_result); if (res) goto exit; + /* Needed for the following test and for records_at_start in next loop */ + table->file->info(HA_STATUS_VARIABLE); + if (found_rows_for_union & sl->options) + { + /* + This is a union without braces. Remember the number of rows that could + also have been part of the result set. + We get this from the difference of between total number of possible + rows and actual rows added to the temporary table. + */ + add_rows+= (ulonglong) (thd->limit_found_rows - (table->file->records - + records_at_start)); + } } if (union_result->flush()) { @@ -172,19 +216,14 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) /* Create a list of fields in the temporary table */ List_iterator<Item> it(item_list); Field **field; -#if 0 - List<Item_func_match> ftfunc_list; - ftfunc_list.empty(); -#else thd->lex.select_lex.ftfunc_list.empty(); -#endif for (field=table->field ; *field ; field++) { (void) it++; (void) it.replace(new Item_field(*field)); } - if (!thd->fatal_error) // Check if EOM + if (!thd->fatal_error) // Check if EOM { if (lex_sl) { @@ -209,8 +248,8 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) item_list, NULL, (describe) ? 0 : order, (ORDER*) NULL, NULL, (ORDER*) NULL, thd->options, result); - if (found_rows_for_union && !res) - thd->limit_found_rows = (ulonglong)table->file->records; + if (!res) + thd->limit_found_rows = (ulonglong)table->file->records + add_rows; } } |