diff options
Diffstat (limited to 'sql')
45 files changed, 745 insertions, 615 deletions
diff --git a/sql/item_func.h b/sql/item_func.h index f7794028998..578c3034b32 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -180,15 +180,15 @@ class Item_num_op :public Item_func class Item_int_func :public Item_func { public: - Item_int_func() :Item_func() {} - Item_int_func(Item *a) :Item_func(a) {} - Item_int_func(Item *a,Item *b) :Item_func(a,b) {} - Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) {} - Item_int_func(List<Item> &list) :Item_func(list) {} + Item_int_func() :Item_func() { max_length=21; } + Item_int_func(Item *a) :Item_func(a) { max_length=21; } + Item_int_func(Item *a,Item *b) :Item_func(a,b) { max_length=21; } + Item_int_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { max_length=21; } + Item_int_func(List<Item> &list) :Item_func(list) { max_length=21; } double val() { return (double) val_int(); } String *val_str(String*str); enum Item_result result_type () const { return INT_RESULT; } - void fix_length_and_dec() { decimals=0; max_length=21; } + void fix_length_and_dec() {} Field *tmp_table_field(TABLE *t_arg) { if (!t_arg) return result_field; @@ -203,7 +203,7 @@ public: double val() { return args[0]->val(); } longlong val_int() { return args[0]->val_int(); } void fix_length_and_dec() - { decimals=0; max_length=args[0]->max_length; unsigned_flag=0; } + { max_length=args[0]->max_length; unsigned_flag=0; } }; class Item_func_unsigned :public Item_int_func @@ -213,7 +213,7 @@ public: double val() { return args[0]->val(); } longlong val_int() { return args[0]->val_int(); } void fix_length_and_dec() - { decimals=0; max_length=args[0]->max_length; unsigned_flag=1; } + { max_length=args[0]->max_length; unsigned_flag=1; } }; @@ -598,7 +598,6 @@ public: Item_func_ord(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "ord"; } - void fix_length_and_dec() { max_length=21; } }; class Item_func_find_in_set :public Item_int_func @@ -620,7 +619,7 @@ public: Item_func_bit_or(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "|"; } - void fix_length_and_dec() { decimals=0; max_length=21; } + void fix_length_and_dec() { unsigned_flag=1; } }; class Item_func_bit_and :public Item_int_func @@ -629,7 +628,7 @@ public: Item_func_bit_and(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "&"; } - void fix_length_and_dec() { decimals=0; max_length=21; } + void fix_length_and_dec() { unsigned_flag=1; } }; class Item_func_bit_count :public Item_int_func @@ -638,7 +637,7 @@ public: Item_func_bit_count(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "bit_count"; } - void fix_length_and_dec() { decimals=0; max_length=2; } + void fix_length_and_dec() { max_length=2; } }; class Item_func_shift_left :public Item_int_func @@ -647,7 +646,7 @@ public: Item_func_shift_left(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "<<"; } - void fix_length_and_dec() { decimals=0; max_length=21; } + void fix_length_and_dec() { unsigned_flag=1; } }; class Item_func_shift_right :public Item_int_func @@ -656,7 +655,6 @@ public: Item_func_shift_right(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return ">>"; } - void fix_length_and_dec() { decimals=0; max_length=21; } }; class Item_func_bit_neg :public Item_int_func @@ -665,7 +663,7 @@ public: Item_func_bit_neg(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "~"; } - void fix_length_and_dec() { decimals=0; max_length=21; } + void fix_length_and_dec() { unsigned_flag=1; } }; class Item_func_set_last_insert_id :public Item_int_func @@ -674,7 +672,7 @@ public: Item_func_set_last_insert_id(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "last_insert_id"; } - void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length; } + void fix_length_and_dec() { max_length=args[0]->max_length; } }; class Item_func_benchmark :public Item_int_func @@ -686,7 +684,7 @@ class Item_func_benchmark :public Item_int_func {} longlong val_int(); const char *func_name() const { return "benchmark"; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; } + void fix_length_and_dec() { max_length=1; maybe_null=0; } }; @@ -818,7 +816,7 @@ class Item_func_get_lock :public Item_int_func Item_func_get_lock(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "get_lock"; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} + void fix_length_and_dec() { max_length=1; maybe_null=1;} }; class Item_func_release_lock :public Item_int_func @@ -828,7 +826,7 @@ class Item_func_release_lock :public Item_int_func Item_func_release_lock(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "release_lock"; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} + void fix_length_and_dec() { max_length=1; maybe_null=1;} }; /* replication functions */ @@ -840,7 +838,7 @@ class Item_master_pos_wait :public Item_int_func Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {} longlong val_int(); const char *func_name() const { return "master_pos_wait"; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;} + void fix_length_and_dec() { max_length=1; maybe_null=1;} }; diff --git a/sql/lock.cc b/sql/lock.cc index 9f4f23b01e3..5d2856278b6 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -431,10 +431,11 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list) if (table->in_use == thd) DBUG_RETURN(0); - /* Create a table entry with the right key and with an old refresh version */ - /* Note that we must use my_malloc() here as this is freed by the table - cache */ - + /* + Create a table entry with the right key and with an old refresh version + Note that we must use my_malloc() here as this is freed by the table + cache + */ if (!(table= (TABLE*) my_malloc(sizeof(*table)+key_length, MYF(MY_WME | MY_ZEROFILL)))) DBUG_RETURN(-1); diff --git a/sql/log.cc b/sql/log.cc index 17b6ef4344c..13ebbd9a3e7 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -370,6 +370,7 @@ err: return error; } + int MYSQL_LOG::reset_logs(THD* thd) { LOG_INFO linfo; @@ -403,6 +404,7 @@ err: return error; } + int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) { // pre-conditions @@ -410,17 +412,17 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) DBUG_ASSERT(index_file >= 0); DBUG_ASSERT(rli->slave_running == 1); DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name)); - // assume that we have previously read the first log and - // stored it in rli->relay_log_name + /* + Assume that we have previously read the first log and + stored it in rli->relay_log_name + */ DBUG_ASSERT(rli->linfo.index_file_offset == strlen(rli->relay_log_name) + 1); - int tmp_fd; - - char* fname, *io_buf; int error = 0; - if (!(fname = (char*)my_malloc(IO_SIZE+FN_REFLEN, MYF(MY_WME)))) + + if (!(fname= (char*) my_malloc(IO_SIZE+FN_REFLEN, MYF(MY_WME)))) return 1; pthread_mutex_lock(&LOCK_index); my_seek(index_file,rli->linfo.index_file_offset, @@ -436,21 +438,22 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) for (;;) { int bytes_read; - bytes_read = my_read(index_file, io_buf, IO_SIZE, MYF(0)); - if (bytes_read < 0) // error + bytes_read = my_read(index_file, (byte*) io_buf, IO_SIZE, MYF(0)); + if (bytes_read < 0) // error { error=1; goto err; } if (!bytes_read) - break; // end of file + break; // end of file // otherwise, we've read something and need to write it out - if (my_write(tmp_fd, io_buf, bytes_read, MYF(MY_WME|MY_NABP))) + if (my_write(tmp_fd, (byte*) io_buf, bytes_read, MYF(MY_WME|MY_NABP))) { error=1; goto err; } } + err: if (tmp_fd) my_close(tmp_fd, MYF(MY_WME)); @@ -476,18 +479,20 @@ err: strnmov(rli->relay_log_name,rli->linfo.log_file_name, sizeof(rli->relay_log_name)); } - // no need to free io_buf because we allocated both fname and io_buf in - // one malloc() + /* + No need to free io_buf because we allocated both fname and io_buf in + one malloc() + */ + err2: pthread_mutex_unlock(&LOCK_index); my_free(fname, MYF(MY_WME)); return error; } + int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) { - if (index_file < 0) return LOG_INFO_INVALID; - if (no_rotate) return LOG_INFO_PURGE_NO_ROTATE; int error; char fname[FN_REFLEN]; char *p; @@ -498,6 +503,10 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) LINT_INIT(purge_offset); IO_CACHE io_cache; + if (index_file < 0) + return LOG_INFO_INVALID; + if (no_rotate) + return LOG_INFO_PURGE_NO_ROTATE; pthread_mutex_lock(&LOCK_index); if (init_io_cache(&io_cache,index_file, IO_SIZE*2, READ_CACHE, (my_off_t) 0, @@ -569,9 +578,10 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) sql_print_error("Error deleting %s during purge", l); } - // if we get killed -9 here, the sysadmin would have to do a small - // vi job on the log index file after restart - otherwise, this should - // be safe + /* + If we get killed -9 here, the sysadmin would have to edit + the log index file after restart - otherwise, this should be safe + */ #ifdef HAVE_FTRUNCATE if (ftruncate(index_file,0)) { @@ -737,14 +747,14 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...) pthread_mutex_lock(&LOCK_log); do { - if (my_b_append(&log_file,buf,len)) + if (my_b_append(&log_file,(byte*) buf,len)) { error = 1; break; } } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint))); - if ((uint)my_b_append_tell(&log_file) > max_binlog_size) + if ((uint) my_b_append_tell(&log_file) > max_binlog_size) { new_file(1); } @@ -755,6 +765,7 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...) return error; } + bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, const char *format,...) { diff --git a/sql/log_event.cc b/sql/log_event.cc index 4d6d5341312..648e9175e13 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -26,17 +26,19 @@ #include <assert.h> -inline int my_b_safe_write(IO_CACHE* file, const char* buf, - int len) -{ - // Sasha: We are not writing this with the ? operator to avoid hitting - // a possible compiler bug. At least gcc 2.95 cannot deal with - // several layers of ternary operators that evaluated comma(,) operator - // expressions inside - I do have a test case if somebody wants it +inline int my_b_safe_write(IO_CACHE* file, const byte *buf, + int len) +{ + /* + Sasha: We are not writing this with the ? operator to avoid hitting + a possible compiler bug. At least gcc 2.95 cannot deal with + several layers of ternary operators that evaluated comma(,) operator + expressions inside - I do have a test case if somebody wants it + */ if (file->type == SEQ_READ_APPEND) - return my_b_append(file,buf,len); - return my_b_write(file,buf,len); - } + return my_b_append(file, buf,len); + return my_b_write(file, buf,len); +} #ifdef MYSQL_CLIENT static void pretty_print_str(FILE* file, char* str, int len) @@ -94,6 +96,7 @@ static void pretty_print_str(String* packet, char* str, int len) packet->append('\''); } + static inline char* slave_load_file_stem(char*buf, uint file_id, int event_server_id) { @@ -382,9 +385,9 @@ int Log_event::net_send(THD* thd, const char* log_name, my_off_t pos) event_type = get_type_str(); net_store_data(packet, event_type, strlen(event_type)); net_store_data(packet, server_id); - net_store_data(packet, log_pos); + net_store_data(packet, (longlong) log_pos); pack_info(packet); - return my_net_write(&thd->net, (char*)packet->ptr(), packet->length()); + return my_net_write(&thd->net, (char*) packet->ptr(), packet->length()); } #endif @@ -1218,31 +1221,30 @@ void Load_log_event::set_fields(List<Item> &fields) { uint i; const char* field = this->fields; - for(i = 0; i < num_fields; i++) - { - fields.push_back(new Item_field(db, table_name, field)); - field += field_lens[i] + 1; - } - + for (i = 0; i < num_fields; i++) + { + fields.push_back(new Item_field(db, table_name, field)); + field += field_lens[i] + 1; + } } + Slave_log_event::Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli): Log_event(thd_arg),mem_pool(0),master_host(0) { - if(!rli->inited) + if (!rli->inited) return; MASTER_INFO* mi = rli->mi; - // TODO: re-write this better without holding both - // locks at the same time + // TODO: re-write this better without holding both locks at the same time pthread_mutex_lock(&mi->data_lock); pthread_mutex_lock(&rli->data_lock); master_host_len = strlen(mi->host); master_log_len = strlen(rli->master_log_name); // on OOM, just do not initialize the structure and print the error - if((mem_pool = (char*)my_malloc(get_data_size() + 1, - MYF(MY_WME)))) + if ((mem_pool = (char*)my_malloc(get_data_size() + 1, + MYF(MY_WME)))) { master_host = mem_pool + SL_MASTER_HOST_OFFSET ; memcpy(master_host, mi->host, master_host_len + 1); @@ -1276,8 +1278,8 @@ void Slave_log_event::print(FILE* file, bool short_form, char* last_db) print_header(file); fputc('\n', file); fprintf(file, "Slave: master_host='%s' master_port=%d \ - master_log=%s master_pos=%s\n", master_host, master_port, master_log, - llstr(master_pos, llbuff)); + master_log=%s master_pos=%s\n", + master_host, master_port, master_log, llstr(master_pos, llbuff)); } #endif @@ -1753,11 +1755,13 @@ int Stop_log_event::exec_event(struct st_relay_log_info* rli) close_temporary_tables(thd); cleanup_load_tmpdir(); } - // we do not want to update master_log pos because we get a rotate event - // before stop, so by now master_log_name is set to the next log - // if we updated it, we will have incorrect master coordinates and this - // could give false triggers in MASTER_POS_WAIT() that we have reached - // the targed position when in fact we have not + /* + We do not want to update master_log pos because we get a rotate event + before stop, so by now master_log_name is set to the next log + if we updated it, we will have incorrect master coordinates and this + could give false triggers in MASTER_POS_WAIT() that we have reached + the targed position when in fact we have not + */ rli->inc_pos(get_event_len(), 0); flush_relay_log_info(rli); return 0; diff --git a/sql/log_event.h b/sql/log_event.h index 686d353d8bb..089d9589763 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -214,7 +214,7 @@ public: time_t when; ulong exec_time; uint32 server_id; - uint32 log_pos; + my_off_t log_pos; uint16 flags; int cached_event_len; char* temp_buf; @@ -351,12 +351,12 @@ protected: char* mem_pool; void init_from_mem_pool(int data_size); public: + my_off_t master_pos; char* master_host; - int master_host_len; - uint16 master_port; char* master_log; + int master_host_len; int master_log_len; - ulonglong master_pos; + uint16 master_port; #ifndef MYSQL_CLIENT Slave_log_event(THD* thd_arg, struct st_relay_log_info* rli); diff --git a/sql/mini_client.cc b/sql/mini_client.cc index a5879081566..c31fa573fea 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -399,7 +399,7 @@ max_allowed_packet on this server"); } -char * mc_mysql_error(MYSQL *mysql) +char *mc_mysql_error(MYSQL *mysql) { return (mysql)->net.last_error; } @@ -897,7 +897,7 @@ mc_mysql_close(MYSQL *mysql) DBUG_VOID_RETURN; } -void mc_mysql_free_result(MYSQL_RES *result) +void mc_mysql_free_result(MYSQL_RES *result) { DBUG_ENTER("mc_mysql_free_result"); DBUG_PRINT("enter",("mysql_res: %lx",result)); @@ -1280,17 +1280,17 @@ static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, return 0; } -my_ulonglong mc_mysql_num_rows(MYSQL_RES *res) +my_ulonglong mc_mysql_num_rows(MYSQL_RES *res) { return res->row_count; } -unsigned int mc_mysql_num_fields(MYSQL_RES *res) +unsigned int mc_mysql_num_fields(MYSQL_RES *res) { return res->field_count; } -void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row) +void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row) { MYSQL_ROWS *tmp=0; DBUG_PRINT("info",("mysql_data_seek(%ld)",(long) row)); @@ -1300,7 +1300,7 @@ void mc_mysql_data_seek(MYSQL_RES *result, my_ulonglong row) result->data_cursor = tmp; } -MYSQL_ROW mc_mysql_fetch_row(MYSQL_RES *res) +MYSQL_ROW STDCALL mc_mysql_fetch_row(MYSQL_RES *res) { DBUG_ENTER("mc_mysql_fetch_row"); if (!res->data) @@ -1335,7 +1335,7 @@ MYSQL_ROW mc_mysql_fetch_row(MYSQL_RES *res) } } -int mc_mysql_select_db(MYSQL *mysql, const char *db) +int mc_mysql_select_db(MYSQL *mysql, const char *db) { int error; DBUG_ENTER("mysql_select_db"); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b6e33a32b74..983218e42d2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1950,8 +1950,7 @@ The server will not act as a slave."); } if (!opt_noacl) (void) grant_init(); - if (max_user_connections || mqh_used) - init_max_user_conn(); + init_max_user_conn(); #ifdef HAVE_DLOPEN if (!opt_noacl) diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index eabba9c68fc..6cc7ef7404b 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -201,7 +201,7 @@ void end_slave_list() static int find_target_pos(LEX_MASTER_INFO* mi, IO_CACHE* log, char* errmsg) { - uint32 log_pos = mi->pos; + uint32 log_pos = (uint32) mi->pos; uint32 target_server_id = mi->server_id; for (;;) @@ -799,8 +799,7 @@ int load_master_data(THD* thd) { strmake(active_mi->master_log_name, row[0], sizeof(active_mi->master_log_name)); - // atoi() is ok, since offset is <= 1GB - active_mi->master_log_pos = atoi(row[1]); + active_mi->master_log_pos = strtoull(row[1], (char**) 0, 10); if (active_mi->master_log_pos < 4) active_mi->master_log_pos = 4; // don't hit the magic number active_mi->rli.pending = 0; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index c78da67f3de..950ca4f6623 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -236,3 +236,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 9a7dffb4ae2..d87ed4ee629 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -230,3 +230,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index dedf41ee394..c84c49dadc6 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -233,3 +233,4 @@ "Kan de query niet uitvoeren vanwege een conflicterende read lock", "Het combineren van transactionele en niet-transactionele tabellen is uitgeschakeld.", "Optie '%s' tweemaal gebruikt in opdracht", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 50cc4095038..5033449c266 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -227,3 +227,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 1e0fa15d2c0..6a83468eae5 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -232,3 +232,4 @@ "Ei suuda täita päringut konfliktse luku tõttu", "Transaktsioone toetavate ning mittetoetavate tabelite kooskasutamine ei ole lubatud", "Määrangut '%s' on lauses kasutatud topelt", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 11f70c7a997..cf3e3e845e4 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -227,3 +227,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index f277a4f08e8..19d46fabab8 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -230,3 +230,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index f36f2db98cf..f9b4f137f82 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -227,3 +227,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 2609e33a419..38877371243 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -229,3 +229,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index df091f9549e..e8cfd5a63a9 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -227,3 +227,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index f4d0e6069e4..98bc099954f 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -229,3 +229,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index d58c3db406e..f6cc890cb39 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -227,3 +227,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index b96e9a53e10..adffc27949f 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -229,3 +229,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index bf2afdb1c9b..09a1ea4684c 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -229,3 +229,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 69a619045e5..12a9bd358b5 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -231,3 +231,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 964c399628f..b7feb0a7b0d 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -227,3 +227,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 9fa6ceebaa4..8e48cabfc39 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -231,3 +231,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index cde0afca01f..8ed33ec21a0 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -230,3 +230,4 @@ "îÅ×ÏÚÍÏÖÎÏ ×ÙÐÏÌÎÉÔØ ÚÁÐÒÏÓ ÉÚ-ÚÁ ËÏÎÆÌÉËÔÎÏÊ ÂÌÏËÉÒÏ×ËÉ ÞÔÅÎÉÑ", "ïÄÎÏ×ÒÅÍÅÎÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ transactional É non-transactional ÔÁÂÌÉà ÏÔËÌÀÞÅÎÏ", "ïÐÃÉÑ '%s' ÉÓÐÏÌØÚÏ×ÁÎÁ Ä×ÁÖÄÙ", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 6814a34ef2f..06503cdf69e 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -235,3 +235,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 0f2b963b902..4240581c5b8 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -228,3 +228,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 53ab39f1544..e774f4a2c5c 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -227,3 +227,4 @@ "Kan inte utföra kommandot emedan du har ett READ lås", "Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", "Option '%s' användes två gånger", +"Användare '%-64s' har överskridit '%s' (nuvarande värde: %ld)", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index b2dfd1c887f..c4c89433331 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -232,3 +232,4 @@ "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", "Option '%s' used twice in statement", +"User '%-64s' has exceeded the '%s' resource (current value: %ld)", diff --git a/sql/slave.cc b/sql/slave.cc index 59e07040528..16c6751f853 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -268,7 +268,7 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, bool just_reset, const char** errmsg) pthread_mutex_lock(&rli->data_lock); rli->pending=0; rli->master_log_name[0]=0; - rli->master_log_pos=0; // 0 means uninitialized + rli->master_log_pos=0; // 0 means uninitialized if (rli->relay_log.reset_logs(rli->sql_thd) || rli->relay_log.find_first_log(&rli->linfo,"")) { @@ -990,7 +990,7 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) } if (init_relay_log_pos(rli,"",4,0/*no data mutex*/,&msg)) goto err; - rli->master_log_pos = 0; // uninitialized + rli->master_log_pos = 0; // uninitialized rli->info_fd = info_fd; } else // file exists @@ -1049,6 +1049,7 @@ err: return 1; } + int init_master_info(MASTER_INFO* mi, const char* master_info_fname, const char* slave_info_fname) { @@ -1058,14 +1059,16 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, return 1; mi->rli.mi = mi; mi->ignore_stop_event=0; - int fd,length,error; + int fd,error; MY_STAT stat_area; char fname[FN_REFLEN+128]; const char *msg; fn_format(fname, master_info_fname, mysql_data_home, "", 4+32); - // we need a mutex while we are changing master info parameters to - // keep other threads from reading bogus info + /* + We need a mutex while we are changing master info parameters to + keep other threads from reading bogus info + */ pthread_mutex_lock(&mi->data_lock); fd = mi->fd; @@ -1089,7 +1092,7 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, return 1; } mi->master_log_name[0] = 0; - mi->master_log_pos = 4; // skip magic number + mi->master_log_pos = 4; // skip magic number mi->fd = fd; if (master_host) @@ -1119,20 +1122,18 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, mi->fd = fd; if (init_strvar_from_file(mi->master_log_name, - sizeof(mi->master_log_name), &mi->file, - (char*)"") || - init_intvar_from_file((int*)&mi->master_log_pos, &mi->file, 4) - || - init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file, - master_host) || - init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file, - master_user) || - init_strvar_from_file(mi->password, HASH_PASSWORD_LENGTH+1, &mi->file, - master_password) || - init_intvar_from_file((int*)&mi->port, &mi->file, master_port) || - init_intvar_from_file((int*)&mi->connect_retry, &mi->file, - master_connect_retry) - ) + sizeof(mi->master_log_name), &mi->file, + (char*)"") || + init_intvar_from_file((int*)&mi->master_log_pos, &mi->file, 4) || + init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file, + master_host) || + init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file, + master_user) || + init_strvar_from_file(mi->password, HASH_PASSWORD_LENGTH+1, &mi->file, + master_password) || + init_intvar_from_file((int*)&mi->port, &mi->file, master_port) || + init_intvar_from_file((int*)&mi->connect_retry, &mi->file, + master_connect_retry)) { msg="Error reading master configuration"; goto err; @@ -1140,8 +1141,7 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, } mi->inited = 1; - // now change the cache from READ to WRITE - must do this - // before flush_master_info + // now change cache READ -> WRITE - must do this before flush_master_info reinit_io_cache(&mi->file, WRITE_CACHE,0L,0,1); error=test(flush_master_info(mi)); pthread_mutex_unlock(&mi->data_lock); @@ -1250,7 +1250,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi) net_store_data(packet, (uint32)mi->rli.last_slave_errno); net_store_data(packet, mi->rli.last_slave_error); net_store_data(packet, mi->rli.slave_skip_counter); - net_store_data(packet, (longlong)mi->rli.master_log_pos); + net_store_data(packet, (longlong) mi->rli.master_log_pos); pthread_mutex_unlock(&mi->rli.data_lock); pthread_mutex_unlock(&mi->data_lock); @@ -1408,7 +1408,8 @@ static int request_dump(MYSQL* mysql, MASTER_INFO* mi) int len; int binlog_flags = 0; // for now char* logname = mi->master_log_name; - int4store(buf, mi->master_log_pos); + // TODO if big log files: Change next to int8store() + int4store(buf, (longlong) mi->master_log_pos); int2store(buf + 4, binlog_flags); int4store(buf + 6, server_id); len = (uint) strlen(logname); @@ -1521,7 +1522,6 @@ point. If you are sure that your master is ok, run this query manually on the\ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) { - const char *error_msg; DBUG_ASSERT(rli->sql_thd==thd); Log_event * ev = next_event(rli); DBUG_ASSERT(rli->sql_thd==thd); @@ -1582,7 +1582,7 @@ This may also be a network problem, or just a bug in the master or slave code.\ pthread_handler_decl(handle_slave_io,arg) { #ifndef DBUG_OFF - slave_begin: +slave_begin: #endif THD *thd; // needs to be first for thread_stack MYSQL *mysql = NULL ; @@ -1604,12 +1604,12 @@ pthread_handler_decl(handle_slave_io,arg) pthread_detach_this_thread(); if (init_slave_thread(thd, SLAVE_THD_IO)) - { - pthread_cond_broadcast(&mi->start_cond); - pthread_mutex_unlock(&mi->run_lock); - sql_print_error("Failed during slave I/O thread initialization"); - goto err; - } + { + pthread_cond_broadcast(&mi->start_cond); + pthread_mutex_unlock(&mi->run_lock); + sql_print_error("Failed during slave I/O thread initialization"); + goto err; + } mi->io_thd = thd; thd->thread_stack = (char*)&thd; // remember where our stack is threads.append(thd); @@ -1633,11 +1633,11 @@ pthread_handler_decl(handle_slave_io,arg) #endif // we can get killed during safe_connect if (!safe_connect(thd, mysql, mi)) - sql_print_error("Slave I/O thread: connected to master '%s@%s:%d',\ + sql_print_error("Slave I/O thread: connected to master '%s@%s:%d',\ replication started in log '%s' at position %s", mi->user, - mi->host, mi->port, - IO_RPL_LOG_NAME, - llstr(mi->master_log_pos,llbuff)); + mi->host, mi->port, + IO_RPL_LOG_NAME, + llstr(mi->master_log_pos,llbuff)); else { sql_print_error("Slave I/O thread killed while connecting to master"); @@ -1649,14 +1649,14 @@ connected: thd->slave_net = &mysql->net; thd->proc_info = "Checking master version"; if (check_master_version(mysql, mi)) - { goto err; - } if (!mi->old_format) { - // register ourselves with the master - // if fails, this is not fatal - we just print the error message and go - // on with life + /* + Register ourselves with the master. + If fails, this is not fatal - we just print the error message and go + on with life. + */ thd->proc_info = "Registering slave on master"; if (register_slave_on_master(mysql) || update_slave_list(mysql)) goto err; @@ -1664,122 +1664,124 @@ connected: while (!slave_killed(thd,mi)) { - thd->proc_info = "Requesting binlog dump"; - if (request_dump(mysql, mi)) - { - sql_print_error("Failed on request_dump()"); - if(slave_killed(thd,mi)) - { - sql_print_error("Slave I/O thread killed while requesting master \ + thd->proc_info = "Requesting binlog dump"; + if (request_dump(mysql, mi)) + { + sql_print_error("Failed on request_dump()"); + if(slave_killed(thd,mi)) + { + sql_print_error("Slave I/O thread killed while requesting master \ dump"); - goto err; - } + goto err; + } - thd->proc_info = "Waiiting to reconnect after a failed dump request"; - mc_end_server(mysql); - // first time retry immediately, assuming that we can recover - // right away - if first time fails, sleep between re-tries - // hopefuly the admin can fix the problem sometime - if (retried_once) - safe_sleep(thd, mi, mi->connect_retry); - else - retried_once = 1; + thd->proc_info = "Waiiting to reconnect after a failed dump request"; + mc_end_server(mysql); + /* + First time retry immediately, assuming that we can recover + right away - if first time fails, sleep between re-tries + hopefuly the admin can fix the problem sometime + */ + if (retried_once) + safe_sleep(thd, mi, mi->connect_retry); + else + retried_once = 1; - if (slave_killed(thd,mi)) - { - sql_print_error("Slave I/O thread killed while retrying master \ + if (slave_killed(thd,mi)) + { + sql_print_error("Slave I/O thread killed while retrying master \ dump"); - goto err; - } + goto err; + } - thd->proc_info = "Reconnecting after a failed dump request"; - sql_print_error("Slave I/O thread: failed dump request, \ + thd->proc_info = "Reconnecting after a failed dump request"; + sql_print_error("Slave I/O thread: failed dump request, \ reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME, - llstr(mi->master_log_pos,llbuff)); - if (safe_reconnect(thd, mysql, mi) || slave_killed(thd,mi)) - { - sql_print_error("Slave I/O thread killed during or \ + llstr(mi->master_log_pos,llbuff)); + if (safe_reconnect(thd, mysql, mi) || slave_killed(thd,mi)) + { + sql_print_error("Slave I/O thread killed during or \ after reconnect"); - goto err; - } + goto err; + } - goto connected; - } + goto connected; + } - while (!slave_killed(thd,mi)) - { - thd->proc_info = "Reading master update"; - ulong event_len = read_event(mysql, mi); - if (slave_killed(thd,mi)) - { - sql_print_error("Slave I/O thread killed while reading event"); - goto err; - } + while (!slave_killed(thd,mi)) + { + thd->proc_info = "Reading master update"; + ulong event_len = read_event(mysql, mi); + if (slave_killed(thd,mi)) + { + sql_print_error("Slave I/O thread killed while reading event"); + goto err; + } - if (event_len == packet_error) - { - if (mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE) - { - sql_print_error("Log entry on master is longer than \ -max_allowed_packet on slave. Slave thread will be aborted. If the entry is \ -really supposed to be that long, restart the server with a higher value of \ -max_allowed_packet. The current value is %ld", max_allowed_packet); - goto err; - } + if (event_len == packet_error) + { + if (mc_mysql_errno(mysql) == ER_NET_PACKET_TOO_LARGE) + { + sql_print_error("Log entry on master is longer than \ +max_allowed_packet (%ld) on slave. Slave thread will be aborted. If the entry \ +is correct, restart the server with a higher value of max_allowed_packet", + max_allowed_packet); + goto err; + } - thd->proc_info = "Waiting to reconnect after a failed read"; - mc_end_server(mysql); - if (retried_once) // punish repeat offender with sleep - safe_sleep(thd,mi,mi->connect_retry); - else - retried_once = 1; + thd->proc_info = "Waiting to reconnect after a failed read"; + mc_end_server(mysql); + if (retried_once) // punish repeat offender with sleep + safe_sleep(thd,mi,mi->connect_retry); + else + retried_once = 1; - if (slave_killed(thd,mi)) - { - sql_print_error("Slave I/O thread killed while waiting to \ + if (slave_killed(thd,mi)) + { + sql_print_error("Slave I/O thread killed while waiting to \ reconnect after a failed read"); - goto err; - } - thd->proc_info = "Reconnecting after a failed read"; - sql_print_error("Slave I/O thread: Failed reading log event, \ + goto err; + } + thd->proc_info = "Reconnecting after a failed read"; + sql_print_error("Slave I/O thread: Failed reading log event, \ reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME, - llstr(mi->master_log_pos, llbuff)); - if (safe_reconnect(thd, mysql, mi) || slave_killed(thd,mi)) - { - sql_print_error("Slave I/O thread killed during or after a \ + llstr(mi->master_log_pos, llbuff)); + if (safe_reconnect(thd, mysql, mi) || slave_killed(thd,mi)) + { + sql_print_error("Slave I/O thread killed during or after a \ reconnect done to recover from failed read"); - goto err; - } - goto connected; - } // if(event_len == packet_error) + goto err; + } + goto connected; + } // if(event_len == packet_error) - thd->proc_info = "Queueing event from master"; - if (queue_event(mi,(const char*)mysql->net.read_pos + 1, - (uint)event_len)) - { - sql_print_error("Slave I/O thread could not queue event \ + thd->proc_info = "Queueing event from master"; + if (queue_event(mi,(const char*)mysql->net.read_pos + 1, + event_len)) + { + sql_print_error("Slave I/O thread could not queue event \ from master"); - goto err; - } - // TODO: check debugging abort code + goto err; + } + // TODO: check debugging abort code #ifndef DBUG_OFF - if (abort_slave_event_count && !--events_till_abort) - { - sql_print_error("Slave I/O thread: debugging abort"); - goto err; - } + if (abort_slave_event_count && !--events_till_abort) + { + sql_print_error("Slave I/O thread: debugging abort"); + goto err; + } #endif - } // while(!slave_killed(thd,mi)) - read/exec loop + } // while(!slave_killed(thd,mi)) - read/exec loop } // while(!slave_killed(thd,mi)) - slave loop // error = 0; - err: +err: // print the current replication position sql_print_error("Slave I/O thread exiting, read up to log '%s', position %s", IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff)); thd->query = thd->db = 0; // extra safety if(mysql) - mc_mysql_close(mysql); + mc_mysql_close(mysql); thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&mi->run_lock); mi->slave_running = 0; @@ -1803,12 +1805,13 @@ from master"); DBUG_RETURN(0); // Can't return anything here } + /* slave SQL logic thread */ pthread_handler_decl(handle_slave_sql,arg) { #ifndef DBUG_OFF - slave_begin: +slave_begin: #endif THD *thd; /* needs to be first for thread_stack */ MYSQL *mysql = NULL ; @@ -1832,14 +1835,16 @@ pthread_handler_decl(handle_slave_sql,arg) pthread_detach_this_thread(); if (init_slave_thread(thd, SLAVE_THD_SQL)) - { - // TODO: this is currently broken - slave start and change master - // will be stuck if we fail here - pthread_cond_broadcast(&rli->start_cond); - pthread_mutex_unlock(&rli->run_lock); - sql_print_error("Failed during slave thread initialization"); - goto err; - } + { + /* + TODO: this is currently broken - slave start and change master + will be stuck if we fail here + */ + pthread_cond_broadcast(&rli->start_cond); + pthread_mutex_unlock(&rli->run_lock); + sql_print_error("Failed during slave thread initialization"); + goto err; + } thd->thread_stack = (char*)&thd; // remember where our stack is thd->temporary_tables = rli->save_temporary_tables; // restore temp tables threads.append(thd); @@ -1876,7 +1881,7 @@ log '%s' at position %s,relay log: name='%s',pos='%s'", RPL_LOG_NAME, if (!slave_killed(thd,rli)) sql_print_error("\ Error running query, slave SQL thread aborted. Fix the problem, and restart \ -the slave SQL thread with \"mysqladmin start-slave\". We stopped at log \ +the slave SQL thread with \"SLAVE START\". We stopped at log \ '%s' position %s", RPL_LOG_NAME, llstr(rli->master_log_pos, llbuff)); goto err; @@ -1895,8 +1900,11 @@ the slave SQL thread with \"mysqladmin start-slave\". We stopped at log \ DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun rli->slave_running = 0; rli->save_temporary_tables = thd->temporary_tables; - //TODO: see if we can do this conditionally in next_event() instead - // to avoid unneeded position re-init + + /* + TODO: see if we can do this conditionally in next_event() instead + to avoid unneeded position re-init + */ rli->log_pos_current=0; thd->temporary_tables = 0; // remove tempation from destructor to close them DBUG_ASSERT(thd->net.buff != 0); @@ -1918,6 +1926,7 @@ the slave SQL thread with \"mysqladmin start-slave\". We stopped at log \ DBUG_RETURN(0); // Can't return anything here } + // We assume we already locked mi->data_lock static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev) { @@ -1929,39 +1938,41 @@ static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev) mi->master_log_name[rev->ident_len] = 0; mi->master_log_pos = rev->pos; #ifndef DBUG_OFF - /* if we do not do this, we will be getting the first - rotate event forever, so - we need to not disconnect after one - */ - if (disconnect_slave_event_count) - events_till_disconnect++; + /* + If we do not do this, we will be getting the first + rotate event forever, so we need to not disconnect after one. + */ + if (disconnect_slave_event_count) + events_till_disconnect++; #endif - return 0; + return 0; } -// TODO: verify the issue with stop events, see if we need them at all -// in the relay log -// TODO: test this code before release - it has to be tested on a separte -// setup with 3.23 master -static int queue_old_event(MASTER_INFO* mi, const char* buf, - uint event_len) +/* + TODO: verify the issue with stop events, see if we need them at all + in the relay log + TODO: test this code before release - it has to be tested on a separte + setup with 3.23 master +*/ + +static int queue_old_event(MASTER_INFO *mi, const char *buf, + ulong event_len) { - const char* errmsg = 0; + const char *errmsg = 0; bool inc_pos = 1; bool processed_stop_event = 0; - Log_event* ev = Log_event::read_log_event(buf,event_len, &errmsg, - 1/*old format*/); + Log_event *ev = Log_event::read_log_event(buf,event_len, &errmsg, + 1 /*old format*/ ); if (unlikely(!ev)) { sql_print_error("Read invalid event from master: '%s',\ - master could be corrupt but a more likely cause of this is a bug", + master could be corrupt but a more likely cause of this is a bug", errmsg); return 1; } pthread_mutex_lock(&mi->data_lock); ev->log_pos = mi->master_log_pos; - switch (ev->get_type_code()) - { + switch (ev->get_type_code()) { case ROTATE_EVENT: if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev))) { @@ -2003,9 +2014,12 @@ static int queue_old_event(MASTER_INFO* mi, const char* buf, return 0; } -// TODO: verify the issue with stop events, see if we need them at all -// in the relay log -int queue_event(MASTER_INFO* mi,const char* buf,uint event_len) +/* + TODO: verify the issue with stop events, see if we need them at all + in the relay log +*/ + +int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len) { int error=0; bool inc_pos = 1; @@ -2015,10 +2029,11 @@ int queue_event(MASTER_INFO* mi,const char* buf,uint event_len) pthread_mutex_lock(&mi->data_lock); - // TODO: figure out if other events in addition to Rotate - // require special processing - switch (buf[EVENT_TYPE_OFFSET]) - { + /* + TODO: figure out if other events in addition to Rotate + require special processing + */ + switch (buf[EVENT_TYPE_OFFSET]) { case STOP_EVENT: processed_stop_event=1; break; @@ -2048,22 +2063,23 @@ int queue_event(MASTER_INFO* mi,const char* buf,uint event_len) return error; } + void end_relay_log_info(RELAY_LOG_INFO* rli) { if (!rli->inited) return; if (rli->info_fd >= 0) - { - end_io_cache(&rli->info_file); - (void)my_close(rli->info_fd, MYF(MY_WME)); - rli->info_fd = -1; - } + { + end_io_cache(&rli->info_file); + (void)my_close(rli->info_fd, MYF(MY_WME)); + rli->info_fd = -1; + } if (rli->cur_log_fd >= 0) - { - end_io_cache(&rli->cache_buf); - (void)my_close(rli->cur_log_fd, MYF(MY_WME)); - rli->cur_log_fd = -1; - } + { + end_io_cache(&rli->cache_buf); + (void)my_close(rli->cur_log_fd, MYF(MY_WME)); + rli->cur_log_fd = -1; + } rli->inited = 0; rli->log_pos_current=0; rli->relay_log.close(1); @@ -2075,10 +2091,12 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) return connect_to_master(thd, mysql, mi, 0); } + /* Try to connect until successful or slave killed or we have retried master_retry_count times */ + static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi, bool reconnect) { @@ -2091,9 +2109,9 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi, events_till_disconnect = disconnect_slave_event_count; #endif while (!(slave_was_killed = slave_killed(thd,mi)) && - (reconnect ? mc_mysql_reconnect(mysql) : + (reconnect ? mc_mysql_reconnect(mysql) != 0 : !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, - mi->port, 0, 0))) + mi->port, 0, 0))) { /* Don't repeat last error */ if (mc_mysql_errno(mysql) != last_errno) @@ -2105,10 +2123,11 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi, mi->connect_retry); } safe_sleep(thd,mi,mi->connect_retry); - /* by default we try forever. The reason is that failure will trigger - master election, so if the user did not set master_retry_count we - do not want to have electioin triggered on the first failure to - connect + /* + By default we try forever. The reason is that failure will trigger + master election, so if the user did not set master_retry_count we + do not want to have electioin triggered on the first failure to + connect */ if (master_retry_count && err_count++ == master_retry_count) { @@ -2124,14 +2143,14 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi, if (reconnect) sql_print_error("Slave: connected to master '%s@%s:%d',\ replication resumed in log '%s' at position %s", mi->user, - mi->host, mi->port, - IO_RPL_LOG_NAME, - llstr(mi->master_log_pos,llbuff)); + mi->host, mi->port, + IO_RPL_LOG_NAME, + llstr(mi->master_log_pos,llbuff)); else { change_rpl_status(RPL_IDLE_SLAVE,RPL_ACTIVE_SLAVE); mysql_log.write(thd, COM_CONNECT_OUT, "%s@%s:%d", - mi->user, mi->host, mi->port); + mi->user, mi->host, mi->port); } #ifdef SIGNAL_WITH_VIO_CLOSE thd->set_active_vio(mysql->net.vio); @@ -2141,6 +2160,7 @@ replication resumed in log '%s' at position %s", mi->user, return slave_was_killed; } + /* Try to connect until successful or slave killed or we have retried master_retry_count times @@ -2172,7 +2192,7 @@ IO_CACHE* reopen_relay_log(RELAY_LOG_INFO* rli, const char** errmsg) IO_CACHE* cur_log = rli->cur_log=&rli->cache_buf; DBUG_ASSERT(rli->cur_log_fd == -1); if ((rli->cur_log_fd=open_binlog(cur_log,rli->relay_log_name, - errmsg))<0) + errmsg)) <0) return 0; my_b_seek(cur_log,rli->relay_log_pos); return cur_log; @@ -2188,29 +2208,36 @@ Log_event* next_event(RELAY_LOG_INFO* rli) bool was_killed; DBUG_ASSERT(thd != 0); - // For most operations we need to protect rli members with data_lock, - // so we will hold it for the most of the loop below - // However, we will release it whenever it is worth the hassle, - // and in the cases when we go into a pthread_cond_wait() with the - // non-data_lock mutex + /* + For most operations we need to protect rli members with data_lock, + so we will hold it for the most of the loop below + However, we will release it whenever it is worth the hassle, + and in the cases when we go into a pthread_cond_wait() with the + non-data_lock mutex + */ pthread_mutex_lock(&rli->data_lock); - for (;!(was_killed=slave_killed(thd,rli));) - { - // we can have two kinds of log reading: - // hot_log - rli->cur_log points at the IO_CACHE of relay_log, which - // is actively being updated by the I/O thread. We need to be careful - // in this case and make sure that we are not looking at a stale log that - // has already been rotated. If it has been, we reopen the log - // the other case is much simpler - we just have a read only log that - // nobody else will be updating. + for (; !(was_killed=slave_killed(thd,rli)) ;) + { + /* + We can have two kinds of log reading: + hot_log - rli->cur_log points at the IO_CACHE of relay_log, which + is actively being updated by the I/O thread. We need to be careful + in this case and make sure that we are not looking at a stale log that + has already been rotated. If it has been, we reopen the log + the other case is much simpler - we just have a read only log that + nobody else will be updating. + */ bool hot_log; if ((hot_log = (cur_log != &rli->cache_buf))) { DBUG_ASSERT(rli->cur_log_fd == -1); // foreign descriptor pthread_mutex_lock(log_lock); - // reading cur_log->init_count here is safe because the log will only - // be rotated when we hold relay_log.LOCK_log + + /* + Reading cur_log->init_count here is safe because the log will only + be rotated when we hold relay_log.LOCK_log + */ if (cur_log->init_count != rli->cur_log_init_count) { if (!(cur_log=reopen_relay_log(rli,&errmsg))) @@ -2235,29 +2262,37 @@ Log_event* next_event(RELAY_LOG_INFO* rli) DBUG_ASSERT(thd==rli->sql_thd); if (!cur_log->error) /* EOF */ { - // on a hot log, EOF means that there are no more updates to - // process and we must block until I/O thread adds some and - // signals us to continue + /* + On a hot log, EOF means that there are no more updates to + process and we must block until I/O thread adds some and + signals us to continue + */ if (hot_log) { DBUG_ASSERT(cur_log->init_count == rli->cur_log_init_count); - //we can, and should release data_lock while we are waiting for - // update. If we do not, show slave status will block + /* + We can, and should release data_lock while we are waiting for + update. If we do not, show slave status will block + */ pthread_mutex_unlock(&rli->data_lock); - // IMPORTANT: note that wait_for_update will unlock LOCK_log, but - // expects the caller to lock it + /* + IMPORTANT: note that wait_for_update will unlock LOCK_log, but + expects the caller to lock it + */ rli->relay_log.wait_for_update(rli->sql_thd); // re-acquire data lock since we released it earlier pthread_mutex_lock(&rli->data_lock); continue; } - // if the log was not hot, we need to move to the next log in - // sequence. The next log could be hot or cold, we deal with both - // cases separately after doing some common initialization else { + /* + If the log was not hot, we need to move to the next log in + sequence. The next log could be hot or cold, we deal with both + cases separately after doing some common initialization + */ end_io_cache(cur_log); DBUG_ASSERT(rli->cur_log_fd >= 0); my_close(rli->cur_log_fd, MYF(MY_WME)); @@ -2282,21 +2317,25 @@ Log_event* next_event(RELAY_LOG_INFO* rli) rli->cur_log_init_count = cur_log->init_count; DBUG_ASSERT(rli->cur_log_fd == -1); - // read pointer has to be at the start since we are the only - // reader + /* + Read pointer has to be at the start since we are the only + reader + */ if (check_binlog_magic(cur_log,&errmsg)) goto err; continue; } - // if we get here, the log was not hot, so we will have to - // open it ourselves + /* + if we get here, the log was not hot, so we will have to + open it ourselves + */ #ifdef EXTRA_DEBUG sql_print_error("next log '%s' is not active", rli->linfo.log_file_name); #endif // open_binlog() will check the magic header if ((rli->cur_log_fd=open_binlog(cur_log,rli->linfo.log_file_name, - &errmsg))<0) + &errmsg)) <0) goto err; } } diff --git a/sql/slave.h b/sql/slave.h index 9632b108ab5..db12ab91618 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -33,8 +33,11 @@ extern my_string opt_relay_logname, opt_relaylog_index_name; extern bool opt_skip_slave_start; struct st_master_info; -// TODO: this needs to be redone, but for now it does not matter since -// we do not have multi-master yet. +/* + TODO: this needs to be redone, but for now it does not matter since + we do not have multi-master yet. +*/ + #define LOCK_ACTIVE_MI { pthread_mutex_lock(&LOCK_active_mi); \ ++active_mi_in_use; \ pthread_mutex_unlock(&LOCK_active_mi);} @@ -62,50 +65,64 @@ struct st_master_info; To clean up, call end_relay_log_info() */ + typedef struct st_relay_log_info { - // info_fd - file descriptor of the info file. set only during - // initialization or clean up - safe to read anytime - // cur_log_fd - file descriptor of the current read relay log, protected by - // data_lock + /*** The following variables can only be read when protect by data lock ****/ + /* + info_fd - file descriptor of the info file. set only during + initialization or clean up - safe to read anytime + cur_log_fd - file descriptor of the current read relay log + */ File info_fd,cur_log_fd; - - // IO_CACHE of the info file - set only during init or end, safe to read - // anytime - IO_CACHE info_file; - - // name of current read relay log - protected by data_lock + // name of current read relay log char relay_log_name[FN_REFLEN]; - - // master log name corresponding to current read position - protected by - // data lock + // master log name corresponding to current read position char master_log_name[FN_REFLEN]; + // original log position of last processed event + volatile my_off_t master_log_pos; + + /* + current offset in the relay log. + pending - in some cases we do not increment offset immediately after + processing an event, because the following event needs to be processed + atomically together with this one ( so far, there is only one type of + such event - Intvar_event that sets auto_increment value). However, once + both events have been processed, we need to increment by the cumulative + offset. pending stored the extra offset to be added to the position. + */ + ulonglong relay_log_pos, pending; - // original log position of last processed event - protected by data_lock - volatile uint32 master_log_pos; + // protected with internal locks + // must get data_lock when resetting the logs + MYSQL_LOG relay_log; + LOG_INFO linfo; + IO_CACHE cache_buf,*cur_log; + + /*** The following variables are safe to read any time ***/ + + // IO_CACHE of the info file - set only during init or end + IO_CACHE info_file; - // when we restart slave thread we need to have access to the previously - // created temporary tables. Modified only on init/end and by the SQL - // thread, read only by SQL thread, need no mutex + /* + When we restart slave thread we need to have access to the previously + created temporary tables. Modified only on init/end and by the SQL + thread, read only by SQL thread. + */ TABLE* save_temporary_tables; - // relay_log_pos - current offset in the relay log - protected by data_lock - // pending - in some cases we do not increment offset immediately after - // processing an event, because the following event needs to be processed - // atomically together with this one ( so far, there is only one type of - // such event - Intvar_event that sets auto_increment value). However, once - // both events have been processed, we need to increment by the cumulative - // offset. pending stored the extra offset to be added to the position. - ulonglong relay_log_pos,pending; - - // standard lock acquistion order to avoid deadlocks: - // run_lock, data_lock, relay_log.LOCK_log,relay_log.LOCK_index + /* + standard lock acquistion order to avoid deadlocks: + run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index + */ pthread_mutex_t data_lock,run_lock; - // start_cond is broadcast when SQL thread is started - // stop_cond - when stopped - // data_cond - when data protected by data_lock changes - pthread_cond_t start_cond,stop_cond,data_cond; + /* + start_cond is broadcast when SQL thread is started + stop_cond - when stopped + data_cond - when data protected by data_lock changes + */ + pthread_cond_t start_cond, stop_cond, data_cond; // if not set, the value of other members of the structure are undefined bool inited; @@ -113,21 +130,19 @@ typedef struct st_relay_log_info // parent master info structure struct st_master_info *mi; - // protected with internal locks - // must get data_lock when resetting the logs - MYSQL_LOG relay_log; - LOG_INFO linfo; - IO_CACHE cache_buf,*cur_log; - - /* needed to deal properly with cur_log getting closed and re-opened with - a different log under our feet + /* + Needed to deal properly with cur_log getting closed and re-opened with + a different log under our feet */ int cur_log_init_count; volatile bool abort_slave, slave_running; -// needed for problems when slave stops and -// we want to restart it skipping one or more events in the master log that -// have caused errors, and have been manually applied by DBA already + + /* + Needed for problems when slave stops and we want to restart it + skipping one or more events in the master log that have caused + errors, and have been manually applied by DBA already. + */ volatile uint32 slave_skip_counter; #ifndef DBUG_OFF int events_till_abort; @@ -168,13 +183,15 @@ typedef struct st_relay_log_info relay_log_pos += val+pending; pending = 0; if (log_pos) - master_log_pos = log_pos+val; + master_log_pos = log_pos+ val; pthread_cond_broadcast(&data_cond); if (!skip_lock) pthread_mutex_unlock(&data_lock); } - // thread safe read of position - not needed if we are in the slave thread, - // but required otherwise + /* + thread safe read of position - not needed if we are in the slave thread, + but required otherwise + */ inline void read_pos(ulonglong& var) { pthread_mutex_lock(&data_lock); @@ -185,12 +202,17 @@ typedef struct st_relay_log_info int wait_for_pos(THD* thd, String* log_name, ulonglong log_pos); } RELAY_LOG_INFO; -// repopen_relay_log() is called when we notice that the current "hot" log -// got rotated under our feet +/* + repopen_relay_log() is called when we notice that the current "hot" log + got rotated under our feet +*/ + IO_CACHE* reopen_relay_log(RELAY_LOG_INFO* rli, const char** errmsg); Log_event* next_event(RELAY_LOG_INFO* rli); -/* st_master_info contains information about how to connect to a master, + +/* + st_master_info contains information about how to connect to a master, current master log name, and current log offset, as well as misc control variables @@ -214,14 +236,14 @@ Log_event* next_event(RELAY_LOG_INFO* rli); flush_master_info() is required. To clean up, call end_master_info() - */ + typedef struct st_master_info { char master_log_name[FN_REFLEN]; - ulonglong master_log_pos; + my_off_t master_log_pos; File fd; IO_CACHE file; @@ -229,24 +251,22 @@ typedef struct st_master_info char host[HOSTNAME_LENGTH+1]; char user[USERNAME_LENGTH+1]; char password[HASH_PASSWORD_LENGTH+1]; - uint port; - uint connect_retry; pthread_mutex_t data_lock,run_lock; pthread_cond_t data_cond,start_cond,stop_cond; - bool inited; - bool old_format; /* master binlog is in 3.23 format */ + THD *io_thd; RELAY_LOG_INFO rli; + uint port; + uint connect_retry; #ifndef DBUG_OFF int events_till_abort; #endif + bool inited; + bool old_format; // master binlog is in 3.23 format volatile bool abort_slave, slave_running; - bool ignore_stop_event; - THD* io_thd; - st_master_info():fd(-1),inited(0), - old_format(0),io_thd(0) + st_master_info():fd(-1), io_thd(0), inited(0), old_format(0) { host[0] = 0; user[0] = 0; password[0] = 0; pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST); @@ -267,7 +287,7 @@ typedef struct st_master_info } MASTER_INFO; -int queue_event(MASTER_INFO* mi,const char* buf,uint event_len); +int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len); typedef struct st_table_rule_ent { @@ -288,10 +308,12 @@ typedef struct st_table_rule_ent /* masks for start/stop operations on io and sql slave threads */ #define SLAVE_IO 1 #define SLAVE_SQL 2 -#define SLAVE_FORCE_ALL 4 /* if this is set, if first gives an - error, second will be tried. Otherwise, - if first fails, we fail - */ + +/* + If the following is set, if first gives an error, second will be + tried. Otherwise, if first fails, we fail. +*/ +#define SLAVE_FORCE_ALL 4 int init_slave(); void init_slave_skip_errors(char* arg); @@ -307,10 +329,11 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_mutex, int start_slave_threads(bool need_slave_mutex, bool wait_for_start, MASTER_INFO* mi, const char* master_info_fname, const char* slave_info_fname, int thread_mask); -/* cond_lock is usually same as start_lock. It is needed for the case when - start_lock is 0 which happens if start_slave_thread() is called already - inside the start_lock section, but at the same time we want a - pthread_cond_wait() on start_cond,start_lock +/* + cond_lock is usually same as start_lock. It is needed for the case when + start_lock is 0 which happens if start_slave_thread() is called already + inside the start_lock section, but at the same time we want a + pthread_cond_wait() on start_cond,start_lock */ int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock, pthread_mutex_t *cond_lock, @@ -318,24 +341,26 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t* start_lock, volatile bool* slave_running, MASTER_INFO* mi); +// If fd is -1, dump to NET int mysql_table_dump(THD* thd, const char* db, const char* tbl_name, int fd = -1); -// if fd is -1, dump to NET -int fetch_master_table(THD* thd, const char* db_name, const char* table_name, - MASTER_INFO* mi, MYSQL* mysql); // retrieve non-exitent table from master +int fetch_master_table(THD* thd, const char* db_name, const char* table_name, + MASTER_INFO* mi, MYSQL* mysql); int show_master_info(THD* thd, MASTER_INFO* mi); int show_binlog_info(THD* thd); +// See if the query uses any tables that should not be replicated int tables_ok(THD* thd, TABLE_LIST* tables); -// see if the query uses any tables that should not be replicated +/* + Check to see if the database is ok to operate on with respect to the + do and ignore lists - used in replication +*/ int db_ok(const char* db, I_List<i_string> &do_list, I_List<i_string> &ignore_list ); -// check to see if the database is ok to operate on with respect to the -// do and ignore lists - used in replication int add_table_rule(HASH* h, const char* table_spec); int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec); @@ -380,13 +405,11 @@ extern int disconnect_slave_event_count, abort_slave_event_count ; // the master variables are defaults read from my.cnf or command line extern uint master_port, master_connect_retry, report_port; extern my_string master_user, master_password, master_host, - master_info_file, relay_log_info_file, report_user, report_host, - report_password; + master_info_file, relay_log_info_file, report_user, report_host, + report_password; extern I_List<i_string> replicate_do_db, replicate_ignore_db; extern I_List<i_string_pair> replicate_rewrite_db; extern I_List<THD> threads; #endif - - diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 091db4e4b39..7cfe801e6f0 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -110,7 +110,7 @@ static void update_hostname(acl_host_and_ip *host, const char *hostname); static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, const char *ip); -int acl_init(bool dont_read_acl_tables) +int acl_init(bool dont_read_acl_tables) { THD *thd; TABLE_LIST tables[3]; @@ -243,13 +243,16 @@ int acl_init(bool dont_read_acl_tables) user.hostname_length=user.host.hostname ? (uint) strlen(user.host.hostname) : 0; if (table->fields >=23) { + /* Table has new MySQL usage limits */ char *ptr = get_field(&mem, table, 21); user.questions=atoi(ptr); ptr = get_field(&mem, table, 22); user.updates=atoi(ptr); if (user.questions) - mqh_used=true; + mqh_used=1; } + else + user.questions=user.updates=0; #ifndef TO_BE_REMOVED if (table->fields <= 13) { // Without grant @@ -430,15 +433,20 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) } -/* Get master privilges for user (priviliges for all tables). Required to connect */ +/* + Get master privilges for user (priviliges for all tables). + Required before connecting to MySQL +*/ + uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *message,char **priv_user, - bool old_ver, uint *max) + bool old_ver, uint *max_questions) { uint user_access=NO_ACCESS; *priv_user=(char*) user; char *ptr=0; + *max_questions=0; if (!initialized) return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */ VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -546,7 +554,7 @@ uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, #else /* HAVE_OPENSSL */ user_access=acl_user->access; #endif /* HAVE_OPENSSL */ - *max=acl_user->questions; + *max_questions=acl_user->questions; if (!acl_user->user) *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ break; @@ -1221,12 +1229,10 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, } } #endif /* HAVE_OPENSSL */ - if (table->fields>=23 && thd->lex.mqh) + if (table->fields >= 23 && thd->lex.mqh) { - char buff[33]; - int len =int2str((long)thd->lex.mqh,buff,10) - buff; - table->field[21]->store(buff,len); - mqh_used=true; + table->field[21]->store((longlong) thd->lex.mqh); + mqh_used=1; } if (old_row_exists) { @@ -2181,7 +2187,7 @@ int grant_init (void) delete thd; DBUG_RETURN(0); // Empty table is ok! } - grant_option = TRUE; + grant_option= TRUE; t_table->file->index_end(); MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a8be2d8b8f5..a5116fa0e20 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -612,8 +612,6 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db, } - - /* move table first in unused links */ static void relink_unused(TABLE *table) @@ -2144,7 +2142,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, THD *in_use; table->version=0L; /* Free when thread is ready */ if (!(in_use=table->in_use)) + { + DBUG_PRINT("info",("Table was not in use")); relink_unused(table); + } else if (in_use != thd) { in_use->some_tables_deleted=1; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 73b15ff3cf1..5b2c9673fdc 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -3088,6 +3088,7 @@ my_bool Query_cache::check_integrity(bool not_locked) result = 1; break; case Query_cache_block::QUERY: + { if (in_list(queries_blocks, block, "query")) result = 1; for (TABLE_COUNTER_TYPE j=0; j < block->n_tables; j++) @@ -3102,6 +3103,7 @@ my_bool Query_cache::check_integrity(bool not_locked) result = 1; } break; + } case Query_cache_block::RES_INCOMPLETE: // This type of block can be not lincked yet (in multithread environment) break; diff --git a/sql/sql_class.h b/sql/sql_class.h index 1d8fa1554d3..4e12cefa271 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -370,7 +370,7 @@ public: */ ulong slave_proxy_id; NET* slave_net; // network connection from slave -> m. - uint32 log_pos; + my_off_t log_pos; THD(); ~THD(); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 2a7824eae68..a155abc522b 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -305,6 +305,8 @@ multi_delete::~multi_delete() bool multi_delete::send_data(List<Item> &values) { int secure_counter= -1; + DBUG_ENTER("multi_delete::send_data"); + for (table_being_deleted=delete_tables ; table_being_deleted ; table_being_deleted=table_being_deleted->next, secure_counter++) @@ -319,13 +321,14 @@ bool multi_delete::send_data(List<Item> &values) if (secure_counter < 0) { + /* If this is the table we are scanning */ table->status|= STATUS_DELETED; if (!(error=table->file->delete_row(table->record[0]))) deleted++; else { table->file->print_error(error,MYF(0)); - return 1; + DBUG_RETURN(1); } } else @@ -334,21 +337,23 @@ bool multi_delete::send_data(List<Item> &values) if (error) { error=-1; - return 1; + DBUG_RETURN(1); } } } - return 0; + DBUG_RETURN(0); } void multi_delete::send_error(uint errcode,const char *err) { + DBUG_ENTER("multi_delete::send_error"); + /* First send error what ever it is ... */ ::send_error(&thd->net,errcode,err); /* If nothing deleted return */ if (!deleted) - return; + DBUG_VOID_RETURN; /* Below can happen when thread is killed early ... */ if (!table_being_deleted) @@ -364,7 +369,10 @@ void multi_delete::send_error(uint errcode,const char *err) table_being_deleted == delete_tables) || !not_trans_safe) ha_rollback_stmt(thd); else if (do_delete) - VOID(do_deletes(true)); + { + VOID(do_deletes(1)); + } + DBUG_VOID_RETURN; } @@ -375,7 +383,7 @@ void multi_delete::send_error(uint errcode,const char *err) 1 error */ -int multi_delete::do_deletes (bool from_send_error) +int multi_delete::do_deletes(bool from_send_error) { int error = 0, counter = 0; @@ -432,7 +440,7 @@ bool multi_delete::send_eof() thd->proc_info="deleting from reference tables"; /* Does deletes for the last n - 1 tables, returns 0 if ok */ - int error = do_deletes(false); // returns 0 if success + int error = do_deletes(0); // returns 0 if success /* reset used flags */ thd->proc_info="end"; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 0c6b5599519..8f9d3474ce2 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -90,6 +90,7 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables, bool dont_send_ok) static enum enum_ha_read_modes rkey_to_rnext[]= { RNEXT, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV }; + int mysql_ha_read(THD *thd, TABLE_LIST *tables, enum enum_ha_read_modes mode, char *keyname, List<Item> *key_expr, enum ha_rkey_function ha_rkey_mode, Item *cond, @@ -121,6 +122,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, List<Item> list; list.push_front(new Item_field(NULL,NULL,"*")); List_iterator<Item> it(list); + uint num_rows; it++; insert_fields(thd,tables,tables->db,tables->name,&it); @@ -136,65 +138,64 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, if (!lock) goto err0; // mysql_lock_tables() printed error message already - for (uint num_rows=0; num_rows < select_limit; ) + for (num_rows=0; num_rows < select_limit; ) { - switch(mode) + switch(mode) { + case RFIRST: + err=keyname ? + table->file->index_first(table->record[0]) : + table->file->rnd_init(1) || + table->file->rnd_next(table->record[0]); + mode=RNEXT; + break; + case RLAST: + DBUG_ASSERT(keyname != 0); + err=table->file->index_last(table->record[0]); + mode=RPREV; + break; + case RNEXT: + err=keyname ? + table->file->index_next(table->record[0]) : + table->file->rnd_next(table->record[0]); + break; + case RPREV: + DBUG_ASSERT(keyname != 0); + err=table->file->index_prev(table->record[0]); + break; + case RKEY: { - case RFIRST: - err=keyname ? - table->file->index_first(table->record[0]) : - table->file->rnd_init(1) || - table->file->rnd_next(table->record[0]); - mode=RNEXT; - break; - case RLAST: - DBUG_ASSERT(keyname != 0); - err=table->file->index_last(table->record[0]); - mode=RPREV; - break; - case RNEXT: - err=keyname ? - table->file->index_next(table->record[0]) : - table->file->rnd_next(table->record[0]); - break; - case RPREV: - DBUG_ASSERT(keyname != 0); - err=table->file->index_prev(table->record[0]); - break; - case RKEY: - { - DBUG_ASSERT(keyname != 0); - KEY *keyinfo=table->key_info+keyno; - KEY_PART_INFO *key_part=keyinfo->key_part; - uint key_len; - byte *key; - if (key_expr->elements > keyinfo->key_parts) - { - my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS), - MYF(0),keyinfo->key_parts); - goto err; - } - List_iterator_fast<Item> it_ke(*key_expr); - Item *item; - for (key_len=0 ; (item=it_ke++) ; key_part++) - { - item->save_in_field(key_part->field); - key_len+=key_part->store_length; - } - if (!(key= (byte*) sql_calloc(ALIGN_SIZE(key_len)))) - { - send_error(&thd->net,ER_OUTOFMEMORY); - goto err; - } - key_copy(key, table, keyno, key_len); - err=table->file->index_read(table->record[0], - key,key_len,ha_rkey_mode); - mode=rkey_to_rnext[(int)ha_rkey_mode]; - break; - } - default: - send_error(&thd->net,ER_ILLEGAL_HA); - goto err; + DBUG_ASSERT(keyname != 0); + KEY *keyinfo=table->key_info+keyno; + KEY_PART_INFO *key_part=keyinfo->key_part; + uint key_len; + byte *key; + if (key_expr->elements > keyinfo->key_parts) + { + my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS), + MYF(0),keyinfo->key_parts); + goto err; + } + List_iterator_fast<Item> it_ke(*key_expr); + Item *item; + for (key_len=0 ; (item=it_ke++) ; key_part++) + { + item->save_in_field(key_part->field); + key_len+=key_part->store_length; + } + if (!(key= (byte*) sql_calloc(ALIGN_SIZE(key_len)))) + { + send_error(&thd->net,ER_OUTOFMEMORY); + goto err; + } + key_copy(key, table, keyno, key_len); + err=table->file->index_read(table->record[0], + key,key_len,ha_rkey_mode); + mode=rkey_to_rnext[(int)ha_rkey_mode]; + break; + } + default: + send_error(&thd->net,ER_ILLEGAL_HA); + goto err; } if (err) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3bcade84cd0..4db3b7f7211 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -55,7 +55,9 @@ extern "C" pthread_mutex_t THR_LOCK_keycache; extern "C" int gethostname(char *name, int namelen); #endif -static int check_for_max_user_connections(const char *user, const char *host, uint max); +static int check_for_max_user_connections(const char *user, const char *host, uint max_questions); +static bool check_mqh(THD *thd, const char *user, const char *host, + uint max_questions); static void decrease_user_connections(const char *user, const char *host); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); @@ -121,101 +123,22 @@ extern pthread_mutex_t LOCK_user_conn; struct user_conn { char *user; - uint len, connections, questions, max; + uint len, connections, questions, max_questions; time_t intime; }; -static byte* get_key_conn(user_conn *buff, uint *length, - my_bool not_used __attribute__((unused))) -{ - *length=buff->len; - return (byte*) buff->user; -} - -#define DEF_USER_COUNT 50 - -static void free_user(struct user_conn *uc) -{ - my_free((char*) uc,MYF(0)); -} - -/* -** Check if maximum queries per hour limit has been reached -** returns 0 if OK. -*/ - -static bool check_mqh(THD *thd, const char *user, const char *host,uint max) -{ - uint temp_len; - char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; - struct user_conn *uc; - if (!user) - user=""; - if (!host) - host=""; - temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host, - NullS) - temp_user); -//This would be MUCH faster if there was already temp_user made in THD !!! May I ?? - (void) pthread_mutex_lock(&LOCK_user_conn); - uc = (struct user_conn *) hash_search(&hash_user_connections, - (byte*) temp_user, temp_len); - if (uc) /* user found ; check for no. of queries */ - { - bool my_start = thd->start_time != 0; - time_t check_time = (my_start) ? thd->start_time : time(NULL); - if (check_time - uc->intime >= 3600) - { - uc->questions=(uint)my_start; - uc->intime=check_time; - } - else if (uc->max && ++(uc->questions) > uc->max) - { - (void) pthread_mutex_unlock(&LOCK_user_conn); - send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); // change this to appropriate message - return 1; - } - } - else - { - struct user_conn *uc= ((struct user_conn*) - my_malloc(sizeof(struct user_conn) + temp_len+1, - MYF(MY_WME))); - if (!uc) - { - send_error(¤t_thd->net, 0, NullS); // Out of memory - (void) pthread_mutex_unlock(&LOCK_user_conn); - return 1; - } - uc->user=(char*) (uc+1); - memcpy(uc->user,temp_user,temp_len+1); - uc->len = temp_len; - uc->connections = 1; - uc->questions=0; - uc->max=max; - uc->intime=current_thd->thr_create_time; - if (hash_insert(&hash_user_connections, (byte*) uc)) - { - my_free((char*) uc,0); - send_error(¤t_thd->net, 0, NullS); // Out of memory - (void) pthread_mutex_unlock(&LOCK_user_conn); - return 1; - } - } - (void) pthread_mutex_unlock(&LOCK_user_conn); - return 0; -} /* -** Check if user is ok -** Updates: -** thd->user, thd->master_access, thd->priv_user, thd->db, thd->db_access + Check if user is ok + Updates: + thd->user, thd->master_access, thd->priv_user, thd->db, thd->db_access */ static bool check_user(THD *thd,enum_server_command command, const char *user, const char *passwd, const char *db, bool check_count) { NET *net= &thd->net; - uint max=0; + uint max_questions=0; thd->db=0; thd->db_length=0; @@ -228,7 +151,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, passwd, thd->scramble, &thd->priv_user, protocol_version == 9 || !(thd->client_capabilities & - CLIENT_LONG_PASSWORD),&max); + CLIENT_LONG_PASSWORD),&max_questions); DBUG_PRINT("info", ("Capabilities: %d packet_length: %d Host: '%s' User: '%s' Using password: %s Access: %u db: '%s'", thd->client_capabilities, thd->max_packet_length, @@ -259,8 +182,6 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, return(1); } } - if (mqh_used && max && check_mqh(thd,user,thd->host,max)) - return -1; mysql_log.write(thd,command, (thd->priv_user == thd->user ? (char*) "%s@%s on %s" : @@ -269,8 +190,11 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, thd->host_or_ip, db ? db : (char*) ""); thd->db_access=0; + /* Don't allow user to connect if he has done too many queries */ + if (max_questions && check_mqh(thd,user,thd->host_or_ip,max_questions)) + return -1; if (max_user_connections && - check_for_max_user_connections(user, thd->host, max)) + check_for_max_user_connections(user, thd->host, max_questions)) return -1; if (db && db[0]) { @@ -285,30 +209,40 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, } /* -** check for maximum allowable user connections -** if mysql server is started with corresponding -** variable that is greater then 0 + Check for maximum allowable user connections, if the mysqld server is + started with corresponding variable that is greater then 0. */ +static byte* get_key_conn(user_conn *buff, uint *length, + my_bool not_used __attribute__((unused))) +{ + *length=buff->len; + return (byte*) buff->user; +} + +static void free_user(struct user_conn *uc) +{ + my_free((char*) uc,MYF(0)); +} + void init_max_user_conn(void) { - (void) hash_init(&hash_user_connections,DEF_USER_COUNT,0,0, + (void) hash_init(&hash_user_connections,max_connections,0,0, (hash_get_key) get_key_conn, (void (*)(void*)) free_user, 0); } -static int check_for_max_user_connections(const char *user, const char *host, uint max) +static int check_for_max_user_connections(const char *user, const char *host, + uint max_questions) { int error=1; uint temp_len; char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; struct user_conn *uc; - if (!user) - user=""; - if (!host) - host=""; DBUG_ENTER("check_for_max_user_connections"); + DBUG_ASSERT(user != 0); + DBUG_ASSERT(host != 0); DBUG_PRINT("enter",("user: '%s' host: '%s'", user, host)); temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user), user, "@", host, @@ -341,7 +275,7 @@ static int check_for_max_user_connections(const char *user, const char *host, ui uc->len = temp_len; uc->connections = 1; uc->questions=0; - uc->max=max; + uc->max_questions=max_questions; uc->intime=current_thd->thr_create_time; if (hash_insert(&hash_user_connections, (byte*) uc)) { @@ -397,9 +331,82 @@ void free_max_user_conn(void) hash_free(&hash_user_connections); } + /* -** check connnetion and get priviliges -** returns 0 on ok, -1 < if error is given > 0 on error. + Check if maximum queries per hour limit has been reached + returns 0 if OK. +*/ + +static bool check_mqh(THD *thd, const char *user, const char *host, + uint max_questions) +{ + uint temp_len; + char temp_user[USERNAME_LENGTH+HOSTNAME_LENGTH+2]; + struct user_conn *uc; + bool error=0; + + DBUG_ASSERT(user != 0); + DBUG_ASSERT(host != 0); + + /* TODO: Add username + host to THD for faster execution */ + temp_len= (uint) (strxnmov(temp_user, sizeof(temp_user)-1, user, "@", host, + NullS) - temp_user); + (void) pthread_mutex_lock(&LOCK_user_conn); + uc = (struct user_conn *) hash_search(&hash_user_connections, + (byte*) temp_user, temp_len); + if (uc) + { + /* user found ; check for no. of queries */ + bool my_start = thd->start_time != 0; + time_t check_time = (my_start) ? thd->start_time : time(NULL); + if (check_time - uc->intime >= 3600) + { + uc->questions=(uint) my_start; + uc->intime=check_time; + } + else if (uc->max_questions && ++(uc->questions) > uc->max_questions) + { + net_printf(&thd->net, ER_USER_LIMIT_REACHED, temp_user, "max_questions", + (long) uc->questions); + error=1; + goto end; + } + } + else + { + struct user_conn *uc= ((struct user_conn*) + my_malloc(sizeof(struct user_conn) + temp_len+1, + MYF(MY_WME))); + if (!uc) + { + send_error(¤t_thd->net, 0, NullS); // Out of memory + error=1; + goto end; + } + uc->user=(char*) (uc+1); + memcpy(uc->user,temp_user,temp_len+1); + uc->len = temp_len; + uc->connections = 1; + uc->questions=0; + uc->max_questions=max_questions; + uc->intime=current_thd->thr_create_time; + if (hash_insert(&hash_user_connections, (byte*) uc)) + { + my_free((char*) uc,0); + send_error(¤t_thd->net, 0, NullS); // Out of memory + error=1; + } + } + +end: + (void) pthread_mutex_unlock(&LOCK_user_conn); + return error; +} + + +/* + Check connnetion and get priviliges + Returns 0 on ok, -1 < if error is given > 0 on error. */ @@ -408,9 +415,7 @@ check_connections(THD *thd) { uint connect_errors=0; NET *net= &thd->net; - /* - ** store the connection details - */ + /* Store the connection details */ DBUG_PRINT("info", (("check_connections called by thread %d"), thd->thread_id)); DBUG_PRINT("info",("New connection received on %s", diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index e4a277d1434..2c4c6216ab7 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -129,7 +129,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) if (!access(name,F_OK)) { my_error(ER_TABLE_EXISTS_ERROR,MYF(0),name); - return ren_table; // This can't be skipped + DBUG_RETURN(ren_table); // This can't be skipped } sprintf(name,"%s/%s/%s%s",mysql_data_home, ren_table->db,ren_table->name, @@ -138,7 +138,7 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) { my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno); if (!skip_error) - return ren_table; + DBUG_RETURN(ren_table); } else if (mysql_rename_table(table_type, ren_table->db, ren_table->name, diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 146490c7b87..0b408920703 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -763,7 +763,6 @@ int change_master(THD* thd, MASTER_INFO* mi) 1 /* wait for start*/, mi,master_info_file,relay_log_info_file, restart_thread_mask); -err: unlock_slave_threads(mi); thd->proc_info = 0; if (error) @@ -1006,9 +1005,9 @@ int log_loaded_block(IO_CACHE* file) /* file->request_pos contains position where we started last read */ char* buffer = (char*) file->request_pos; - if (!(block_len = file->read_end - buffer)) + if (!(block_len = (char*) file->read_end - (char*) buffer)) return 0; - lf_info = (LOAD_FILE_INFO*)file->arg; + lf_info = (LOAD_FILE_INFO*) file->arg; if (lf_info->last_pos_in_file != HA_POS_ERROR && lf_info->last_pos_in_file >= file->pos_in_file) return 0; @@ -1030,5 +1029,3 @@ int log_loaded_block(IO_CACHE* file) } return 0; } - - diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 94018e0046a..89082b40d87 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -185,7 +185,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ulong select_options,select_result *result) { TABLE *tmp_table; - int error, tmp_error, tmp; + int error, tmp_error; bool need_tmp,hidden_group_fields; bool simple_order,simple_group,no_order, skip_sort_order; Item::cond_result cond_value; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 8629930cf5c..131266a11d6 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -708,7 +708,7 @@ mysqld_show_keys(THD *thd, TABLE_LIST *table_list) /* Null flag */ uint flags= key_part->field ? key_part->field->flags : 0; - char *pos=(byte*) ((flags & NOT_NULL_FLAG) ? "" : "YES"); + char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES"); net_store_data(packet,convert,(const char*) pos); net_store_data(packet,convert,table->file->index_type(i)); /* Comment */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 5776cba7e96..6c868b542d1 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -613,10 +613,12 @@ bool multi_update::send_data(List<Item> &values) } else { -// Here I insert into each temporary table - values_by_table.push_front(new Item_string(table->file->ref,table->file->ref_length)); + // Here we insert into each temporary table + values_by_table.push_front(new Item_string((char*) table->file->ref, + table->file->ref_length)); fill_record(tmp_tables[secure_counter]->field,values_by_table); - error= write_record(tmp_tables[secure_counter],&(infos[secure_counter])); + error= write_record(tmp_tables[secure_counter], + &(infos[secure_counter])); if (error) { error=-1; @@ -661,7 +663,8 @@ int multi_update::do_updates (bool from_send_error) { int error = 0, counter = 0; - if (num_updated == 1) return 0; + if (num_updated == 1) + return 0; if (from_send_error) { /* Found out table number for 'table_being_updated' */ @@ -690,7 +693,7 @@ int multi_update::do_updates (bool from_send_error) } List<Item> list; Field **ptr=tmp_table->field,*field; -// This is supposed to be something like insert_fields + // This is supposed to be something like insert_fields thd->used_tables|=tmp_table->map; while ((field = *ptr++)) { @@ -709,12 +712,14 @@ int multi_update::do_updates (bool from_send_error) (!thd->killed || from_send_error || not_trans_safe)) { found++; - error= table->file->rnd_pos(table->record[0], (*(tmp_table->field))->ptr); + error= table->file->rnd_pos(table->record[0], + (byte*) (*(tmp_table->field))->ptr); if (error) return error; table->status|= STATUS_UPDATED; store_record(table,1); - error= fill_record(*fields_by_tables[counter + 1],list) /*|| compare_record(table, query_id)*/ || + error= fill_record(*fields_by_tables[counter + 1],list) || + /* compare_record(table, query_id) || */ table->file->update_row(table->record[1],table->record[0]); if (error) { @@ -731,40 +736,47 @@ int multi_update::do_updates (bool from_send_error) } +/* out: 1 if error, 0 if success */ + bool multi_update::send_eof() { - thd->proc_info="updating the reference tables"; /* out: 1 if error, 0 if success */ + thd->proc_info="updating the reference tables"; /* Does updates for the last n - 1 tables, returns 0 if ok */ int error = do_updates(false); /* do_updates returns 0 if success */ /* reset used flags */ -// update_tables->table->no_keyread=0; - if (error == -1) error = 0; +#ifndef NOT_USED + update_tables->table->no_keyread=0; +#endif + if (error == -1) + error = 0; thd->proc_info="end"; if (error) send_error(error,"An error occured in multi-table update"); - /* Write the SQL statement to the binlog if we updated - rows and we succeeded, or also in an error case when there - was a non-transaction-safe table involved, since - modifications in it cannot be rolled back. */ + /* + Write the SQL statement to the binlog if we updated + rows and we succeeded, or also in an error case when there + was a non-transaction-safe table involved, since + modifications in it cannot be rolled back. + */ if (updated || not_trans_safe) { mysql_update_log.write(thd,thd->query,thd->query_length); Query_log_event qinfo(thd, thd->query); - /* mysql_bin_log is not open if binlogging or replication - is not used */ + /* + mysql_bin_log is not open if binlogging or replication + is not used + */ if (mysql_bin_log.is_open() && mysql_bin_log.write(&qinfo) && !not_trans_safe) - error=1; /* Log write failed: roll back - the SQL statement */ + error=1; /* Log write failed: roll back the SQL statement */ /* Commit or rollback the current SQL statement */ - VOID(ha_autocommit_or_rollback(thd,error > 0)); } else @@ -777,8 +789,8 @@ bool multi_update::send_eof() if (updated) query_cache.invalidate(update_tables); ::send_ok(&thd->net, - (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, - thd->insert_id_used ? thd->insert_id() : 0L,buff); + (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated, + thd->insert_id_used ? thd->insert_id() : 0L,buff); } thd->count_cuted_fields=0; return 0; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 32a87f194ac..91cf0ae5fc9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -577,7 +577,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); opt_outer table_list table_name opt_option opt_place opt_low_priority opt_attribute opt_attribute_list attribute column_list column_list_id opt_column_list grant_privileges opt_table user_list grant_option - grant_privilege grant_privilege_list mqh_option + grant_privilege grant_privilege_list flush_options flush_option insert_lock_option replace_lock_option equal optional_braces opt_key_definition key_usage_list2 opt_mi_check_type opt_to mi_check_types normal_join @@ -3395,7 +3395,7 @@ grant: lex->mqh=0; } grant_privileges ON opt_table TO_SYM user_list - require_clause grant_option mqh_option + require_clause grant_options grant_privileges: grant_privilege_list {} @@ -3582,17 +3582,19 @@ require_clause: /* empty */ Lex->ssl_type=SSL_TYPE_X509; } -grant_option: +grant_options: /* empty */ {} - | WITH GRANT OPTION { Lex->grant |= GRANT_ACL;} + | WITH grant_option_list -mqh_option: - /* empty */ {} - | AND WITH MAX_QUERIES_PER_HOUR EQ NUM - { - Lex->mqh=atoi($5.str); - if (Lex->mqh > 65535) - YYABORT; +grant_option_list: + grant_option_list grant_option {} + | grant_option {} + +grant_option: + GRANT OPTION { Lex->grant |= GRANT_ACL;} + | MAX_QUERIES_PER_HOUR EQ NUM + { + Lex->mqh=atoi($3.str); } begin: |