raven-rhel6/mysqlclient/max_connection2_mysql_clock_5_5_12.patch
2024-02-21 20:14:44 +06:00

263 lines
8.2 KiB
Diff

diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index ff81198..449a8d7 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -429,7 +429,7 @@ uint opt_large_page_size= 0;
uint opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
-my_bool opt_userstat= 0, opt_thread_statistics= 0;
+my_bool opt_userstat= 1, opt_thread_statistics= 0;
/*
True if there is at least one per-hour limit for some user, so we should
check them before each query (and possibly reset counters when hour is
@@ -7469,6 +7469,7 @@ static void set_server_version(void)
#endif
if (opt_log || opt_slow_log || opt_bin_log)
strmov(end, "-log"); // This may slow down system
+ end= strmov(end, "-cll");
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 1875813..63240d5 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -906,7 +906,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
{
/* Starting from 5.0.3 we have max_user_connections field */
ptr= get_field(thd->mem_root, table->field[next_field++]);
- user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
+ user.user_resource.user_conn= ptr ? atoll(ptr) : 0;
}
if (table->s->fields >= 41)
@@ -9311,10 +9311,7 @@ acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len)
}
/* Don't allow the user to connect if he has done too many queries */
- if ((acl_user->user_resource.questions || acl_user->user_resource.updates ||
- acl_user->user_resource.conn_per_hour ||
- acl_user->user_resource.user_conn ||
- global_system_variables.max_user_connections) &&
+ if (
get_or_create_user_conn(thd,
(opt_old_style_user_limits ? sctx->user : sctx->priv_user),
(opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host),
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 6ee2821..ba8b9ac 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3718,6 +3718,7 @@ inline bool add_group_to_list(THD *thd, Item *item, bool asc)
#endif /* MYSQL_SERVER */
+
/**
The meat of thd_proc_info(THD*, char*), a macro that packs the last
three calling-info parameters.
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 3499e0f..7eb4898 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -630,6 +630,10 @@ static void update_global_thread_stats_with_thread(THD* thd,
thread_stats->empty_queries+= thd->diff_empty_queries;
}
+int is_root_access(char *user_name){
+ return !strcmp(user_name,"root")||!strcmp(user_name,"mysql");
+}
+
// Updates the global stats of a user or client
void update_global_user_stats(THD* thd, bool create_user, time_t now)
{
@@ -734,6 +738,15 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
DBUG_ENTER("check_for_max_user_connections");
mysql_mutex_lock(&LOCK_user_conn);
+
+
+ if (((uc->user_resources.user_conn==(uint)~0) || (global_system_variables.max_user_connections == (uint)~0)) && !is_root_access(uc->user))
+ {
+ my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
+ error=1;
+ goto end;
+ }
+
if (global_system_variables.max_user_connections &&
!uc->user_resources.user_conn &&
global_system_variables.max_user_connections < (uint) uc->connections)
diff --git a/sql/sql_list.cc b/sql/sql_list.cc
index 31f0ba2..20707de 100644
--- a/sql/sql_list.cc
+++ b/sql/sql_list.cc
@@ -39,6 +39,14 @@ void free_list(I_List <i_string> *list)
}
+void free_list(I_List <i_thd> *list)
+{
+ i_thd *tmp;
+ while ((tmp= list->get()))
+ delete tmp;
+}
+
+
base_list::base_list(const base_list &rhs, MEM_ROOT *mem_root)
{
if (rhs.elements)
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 5cd2423..a10f4b4 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -562,6 +562,15 @@ public:
i_string(const char* s) : ptr(s) {}
};
+/* DB_GOVERNOR ADDITIONS */
+class i_thd: public ilink
+{
+ public:
+ THD* ptr;
+ i_thd():ptr(0) { }
+ i_thd(THD* s) : ptr(s) {}
+};
+
/* needed for linked list of two strings for replicate-rewrite-db */
class i_string_pair: public ilink
{
@@ -711,5 +720,6 @@ list_copy_and_replace_each_value(List<T> &list, MEM_ROOT *mem_root)
void free_list(I_List <i_string_pair> *list);
void free_list(I_List <i_string> *list);
+void free_list(I_List <i_thd> *list);
#endif // INCLUDES_MYSQL_SQL_LIST_H
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 9ee6c42..ea6c42e 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -114,6 +114,7 @@
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
static void sql_kill(THD *thd, ulong id, bool only_kill_query);
+static void sql_kill_user(THD *thd, char *user, bool only_kill_query);
// Uses the THD to update the global stats by user name and client IP
void update_global_user_stats(THD* thd, bool create_user, time_t now);
@@ -3593,7 +3594,13 @@ end_with_restore_list:
MYF(0));
goto error;
}
- sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
+
+ if(it->type()==Item::STRING_ITEM){
+ sql_kill_user(thd, it->val_str(0)->c_ptr(), lex->type & ONLY_KILL_QUERY);
+ } else {
+ sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
+ }
+
break;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -6477,6 +6484,15 @@ void sql_kill(THD *thd, ulong id, bool only_kill_query)
my_error(error, MYF(0), id);
}
+static void sql_kill_user(THD *thd, char *user, bool only_kill_query)
+{
+ uint error;
+ if (!(error= kill_user_thread(thd, user, only_kill_query)))
+ if (! thd->killed) my_ok(thd);
+ else
+ my_error(error, MYF(0), user);
+}
+
/** If pointer is not a null pointer, append filename to it. */
@@ -7382,3 +7398,58 @@ merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl)
}
return cs;
}
+
+uint kill_user_thread(THD *thd, char *user, bool only_kill_query)
+{
+ THD *tmp;
+ uint error=0;
+ DBUG_ENTER("kill_user_thread");
+ DBUG_PRINT("enter", ("id=%s only_kill=%d", !user?"nop":user, only_kill_query));
+ i_thd *thd_tmp;
+ I_List<i_thd> threads_tmp;
+ threads_tmp.empty();
+ mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
+ I_List_iterator<THD> it(threads);
+ while ((tmp=it++))
+ {
+ if (tmp->command == COM_DAEMON)
+ continue;
+ if((tmp)&&(user)&&(tmp->user_connect)&&(tmp->user_connect->user)){
+ if (!strncmp(tmp->user_connect->user,user,16))
+ {
+ mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ thd_tmp = new i_thd(tmp);
+ if (thd_tmp) threads_tmp.append(thd_tmp);
+ else mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ }
+ }
+ }
+ mysql_mutex_unlock(&LOCK_thread_count);
+
+ if(!threads_tmp.is_empty())
+ {
+ I_List_iterator<i_thd> it_tmp(threads_tmp);
+ while ((thd_tmp=it_tmp++)){
+ tmp=thd_tmp->ptr;
+
+ if ((tmp)&&(thd->security_ctx->master_access & SUPER_ACL) ||
+ thd->security_ctx->user_matches(tmp->security_ctx))
+ {
+ tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
+ error=0;
+ }
+ else
+ error=ER_KILL_DENIED_ERROR;
+ mysql_mutex_unlock(&tmp->LOCK_thd_data);
+ }
+ free_list(&threads_tmp);
+ threads_tmp.empty();
+ }
+ DBUG_PRINT("exit", ("%d", error));
+ DBUG_RETURN(error);
+}
+
+
+
+
+
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
index 9eea074..7262d4c 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -50,6 +50,7 @@ bool parse_sql(THD *thd,
Parser_state *parser_state,
Object_creation_ctx *creation_ctx);
+uint kill_user_thread(THD *thd, char *user, bool only_kill_query);
uint kill_one_thread(THD *thd, ulong id, bool only_kill_query);
void free_items(Item *item);
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 5ff927d..692ceff 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1603,7 +1603,7 @@ static Sys_var_mybool Sys_userstat(
"userstat",
"Control USER_STATISTICS, CLIENT_STATISTICS, THREAD_STATISTICS, "
"INDEX_STATISTICS and TABLE_STATISTICS running",
- GLOBAL_VAR(opt_userstat), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
+ GLOBAL_VAR(opt_userstat), CMD_LINE(OPT_ARG), DEFAULT(TRUE));
static Sys_var_mybool Sys_thread_statistics(
"thread_statistics",