summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authorunknown <jimw@mysql.com>2005-02-08 18:43:27 -0800
committerunknown <jimw@mysql.com>2005-02-08 18:43:27 -0800
commit71acf51498d61ec509e532f5c76efaae841b96f0 (patch)
treed073cfb4f813e84b054cfda9c90029ec0ea09034 /sql/sql_parse.cc
parent22f839cdd23475075e0f1e9eeeb3c7201f9a4262 (diff)
downloadmariadb-git-71acf51498d61ec509e532f5c76efaae841b96f0.tar.gz
Fix per-hour user connection limits by making sure that the number of
connections is actually reset after an hour, and also fix (unlikely) conditions under which the per-hour query and connection limits could be exceeded. (Bug #8350) sql/sql_parse.cc: Add time_out_user_resource_limits() function to reset the user resource limits before they are checked, and add locking to check_mqh() because not doing so isn't as safe as the old comment explaining its absence said it is.
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc56
1 files changed, 40 insertions, 16 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index cd0abafc0c9..bc7d71d8eaa 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -52,7 +52,8 @@ extern "C" pthread_mutex_t THR_LOCK_keycache;
extern "C" int gethostname(char *name, int namelen);
#endif
-static int check_for_max_user_connections(USER_CONN *uc);
+static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
+static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
@@ -272,7 +273,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
return -1;
if (thd->user_connect && (thd->user_connect->user_resources.connections ||
max_user_connections) &&
- check_for_max_user_connections(thd->user_connect))
+ check_for_max_user_connections(thd, thd->user_connect))
return -1;
if (db && db[0])
{
@@ -312,7 +313,7 @@ void init_max_user_conn(void)
}
-static int check_for_max_user_connections(USER_CONN *uc)
+static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{
int error=0;
DBUG_ENTER("check_for_max_user_connections");
@@ -325,6 +326,7 @@ static int check_for_max_user_connections(USER_CONN *uc)
error=1;
goto end;
}
+ time_out_user_resource_limits(thd, uc);
if (uc->user_resources.connections &&
uc->user_resources.connections <= uc->conn_per_hour)
{
@@ -397,33 +399,54 @@ void init_update_queries(void)
/*
- Check if maximum queries per hour limit has been reached
- returns 0 if OK.
+ Reset per-hour user resource limits when it has been more than
+ an hour since they were last checked
- In theory we would need a mutex in the USER_CONN structure for this to
- be 100 % safe, but as the worst scenario is that we would miss counting
- a couple of queries, this isn't critical.
-*/
+ SYNOPSIS:
+ time_out_user_resource_limits()
+ thd Thread handler
+ uc User connection details
+ NOTE:
+ This assumes that the LOCK_user_conn mutex has been acquired, so it is
+ safe to test and modify members of the USER_CONN structure.
+*/
-static bool check_mqh(THD *thd, uint check_command)
+void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
{
- bool error=0;
time_t check_time = thd->start_time ? thd->start_time : time(NULL);
- USER_CONN *uc=thd->user_connect;
- DBUG_ENTER("check_mqh");
- DBUG_ASSERT(uc != 0);
+ DBUG_ENTER("time_out_user_resource_limits");
/* If more than a hour since last check, reset resource checking */
if (check_time - uc->intime >= 3600)
{
- (void) pthread_mutex_lock(&LOCK_user_conn);
uc->questions=1;
uc->updates=0;
uc->conn_per_hour=0;
uc->intime=check_time;
- (void) pthread_mutex_unlock(&LOCK_user_conn);
}
+
+ DBUG_VOID_RETURN;
+}
+
+
+/*
+ Check if maximum queries per hour limit has been reached
+ returns 0 if OK.
+*/
+
+static bool check_mqh(THD *thd, uint check_command)
+{
+ bool error=0;
+ time_t check_time = thd->start_time ? thd->start_time : time(NULL);
+ USER_CONN *uc=thd->user_connect;
+ DBUG_ENTER("check_mqh");
+ DBUG_ASSERT(uc != 0);
+
+ (void) pthread_mutex_lock(&LOCK_user_conn);
+
+ time_out_user_resource_limits(thd, uc);
+
/* Check that we have not done too many questions / hour */
if (uc->user_resources.questions &&
uc->questions++ >= uc->user_resources.questions)
@@ -446,6 +469,7 @@ static bool check_mqh(THD *thd, uint check_command)
}
}
end:
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_RETURN(error);
}