summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_func.h38
-rw-r--r--sql/lock.cc9
-rw-r--r--sql/log.cc49
-rw-r--r--sql/log_event.cc64
-rw-r--r--sql/log_event.h8
-rw-r--r--sql/mini_client.cc14
-rw-r--r--sql/mysqld.cc3
-rw-r--r--sql/repl_failsafe.cc5
-rw-r--r--sql/share/czech/errmsg.txt1
-rw-r--r--sql/share/danish/errmsg.txt1
-rw-r--r--sql/share/dutch/errmsg.txt1
-rw-r--r--sql/share/english/errmsg.txt1
-rw-r--r--sql/share/estonian/errmsg.txt1
-rw-r--r--sql/share/french/errmsg.txt1
-rw-r--r--sql/share/german/errmsg.txt1
-rw-r--r--sql/share/greek/errmsg.txt1
-rw-r--r--sql/share/hungarian/errmsg.txt1
-rw-r--r--sql/share/italian/errmsg.txt1
-rw-r--r--sql/share/japanese/errmsg.txt1
-rw-r--r--sql/share/korean/errmsg.txt1
-rw-r--r--sql/share/norwegian-ny/errmsg.txt1
-rw-r--r--sql/share/norwegian/errmsg.txt1
-rw-r--r--sql/share/polish/errmsg.txt1
-rw-r--r--sql/share/portuguese/errmsg.txt1
-rw-r--r--sql/share/romanian/errmsg.txt1
-rw-r--r--sql/share/russian/errmsg.txt1
-rw-r--r--sql/share/slovak/errmsg.txt1
-rw-r--r--sql/share/spanish/errmsg.txt1
-rw-r--r--sql/share/swedish/errmsg.txt1
-rw-r--r--sql/share/ukrainian/errmsg.txt1
-rw-r--r--sql/slave.cc479
-rw-r--r--sql/slave.h185
-rw-r--r--sql/sql_acl.cc30
-rw-r--r--sql/sql_base.cc5
-rw-r--r--sql/sql_cache.cc2
-rw-r--r--sql/sql_class.h2
-rw-r--r--sql/sql_delete.cc22
-rw-r--r--sql/sql_handler.cc115
-rw-r--r--sql/sql_parse.cc215
-rw-r--r--sql/sql_rename.cc4
-rw-r--r--sql/sql_repl.cc7
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc2
-rw-r--r--sql/sql_update.cc54
-rw-r--r--sql/sql_yacc.yy24
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(&current_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(&current_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(&current_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(&current_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: