diff options
author | unknown <jimw@mysql.com> | 2005-02-08 18:43:27 -0800 |
---|---|---|
committer | unknown <jimw@mysql.com> | 2005-02-08 18:43:27 -0800 |
commit | 71acf51498d61ec509e532f5c76efaae841b96f0 (patch) | |
tree | d073cfb4f813e84b054cfda9c90029ec0ea09034 /sql/sql_parse.cc | |
parent | 22f839cdd23475075e0f1e9eeeb3c7201f9a4262 (diff) | |
download | mariadb-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.cc | 56 |
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); } |