mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
WL#1339 "Add per account max_user_connections limit (maximum number
of concurrent connections for the same account)" Added support of account specific max_user_connections limit. Made all user limits to be counted per account instead of the old behavior, which was per user/host accounting. Added option which enables the old behavior. Added testing of these to the test suite. (After review version). client/mysqltest.c: Extended mysqltest to be able to handle connect() statements for which error is expected. - Added replace_dynstr_append() utility function. - added connect_n_handle_errors() function which connects with server without retries and handles errors as if "connect" was usual statement. - do_connect(): added ability to handle connects which are expected to return an error. - run_query_normal(): Moved all expected-error-handling code to separate normal_handle_error()/normal_handle_no_error() functions to be able to reuse them in connect_n_handle_errors(). mysql-test/r/grant.result: Fixed test results since one more column to mysql.user was added. mysql-test/r/system_mysql_db.result: Fixed test results since one more column to mysql.user was added. scripts/mysql_create_system_tables.sh: Added max_user_connections column to mysql.user table for storing new maximal concurrent connections per account limit. scripts/mysql_fix_privilege_tables.sql: Added max_user_connections column to mysql.user table for storing new maximal concurrent connections per account limit. sql/lex.h: Added MAX_USER_CONNECTIONS symbol used for specifying maximum number of concurrent connections per account. sql/mysql_priv.h: Added declaration of opt_old_style_user_limits variable which is defined in sql/mysqld.cc used in sql/sql_parse.cc. sql/mysqld.cc: Added "old-style-user-limits" option which forces user limits to behave in old way i.e. to be counted per user/host pair instead of per account. Added comment describing mqh_used variable. sql/set_var.cc: Added sys_var_max_user_conn class which implements support for the new behavior of max_user_connections variable. Now the global instance of this variable holds default maximum number of concurrent connections per account (as it was before) and the session instance gives read-only access to account-specific version of this limit. sql/set_var.h: Added sys_var_max_user_conn class which implements support for the new behavior of max_user_connections variable. Now the global instance of this variable holds default maximum number of concurrent connections per account (as it was before) and the session instance gives read-only access to account-specific version of this limit. sql/sql_acl.cc: Added support for account-specific MAX_USER_CONNECTIONS limit. Tweaked USER_RESOURCES and their handling for better clarity. sql/sql_parse.cc: Added support for account-specific MAX_USER_CONNECTIONS (maximum number of concurrent connections per account) limit. Changed default behavior of all user limits to be per account instead of per user+host. '--old-style-user-limits' option was added to enable the old behavior. Made maximum number of connections per hour to be independant on the value of global max_user_connections variable. sql/sql_yacc.yy: Added support of new MAX_USER_CONNECTIONS limit to grammar. Renamed USER_RESOURCES::connections member to conn_per_hour and bits member to specified_limits. Also enum is used instead of naked numbers when we are working with specified_limits. sql/structs.h: USER_RESOURCES struct: - Added user_conn member to store the maximum number of concurrent connections for an account. Renamed connections member to conn_per_hour for less ambiguity. - Renamed member 'bits' to 'specified_limits' for the sake of clarity. The member was used as a flag indicating which limits were mentioned in GRANT clause. - Added comments. USER_CONN struct: - Removed unused user_len member. - Added comments.
This commit is contained in:
@ -332,10 +332,19 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
||||
ptr = get_field(&mem, table->field[next_field++]);
|
||||
user.user_resource.updates=ptr ? atoi(ptr) : 0;
|
||||
ptr = get_field(&mem, table->field[next_field++]);
|
||||
user.user_resource.connections=ptr ? atoi(ptr) : 0;
|
||||
user.user_resource.conn_per_hour= ptr ? atoi(ptr) : 0;
|
||||
if (user.user_resource.questions || user.user_resource.updates ||
|
||||
user.user_resource.connections)
|
||||
user.user_resource.conn_per_hour)
|
||||
mqh_used=1;
|
||||
|
||||
if (table->fields >= 34)
|
||||
{
|
||||
/* Starting from 5.0.3 we have max_user_connections field */
|
||||
ptr= get_field(&mem, table->field[next_field++]);
|
||||
user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
|
||||
}
|
||||
else
|
||||
user.user_resource.user_conn= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -922,12 +931,14 @@ static void acl_update_user(const char *user, const char *host,
|
||||
!my_strcasecmp(system_charset_info, host, acl_user->host.hostname))
|
||||
{
|
||||
acl_user->access=privileges;
|
||||
if (mqh->bits & 1)
|
||||
if (mqh->specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
|
||||
acl_user->user_resource.questions=mqh->questions;
|
||||
if (mqh->bits & 2)
|
||||
if (mqh->specified_limits & USER_RESOURCES::UPDATES_PER_HOUR)
|
||||
acl_user->user_resource.updates=mqh->updates;
|
||||
if (mqh->bits & 4)
|
||||
acl_user->user_resource.connections=mqh->connections;
|
||||
if (mqh->specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR)
|
||||
acl_user->user_resource.conn_per_hour= mqh->conn_per_hour;
|
||||
if (mqh->specified_limits & USER_RESOURCES::USER_CONNECTIONS)
|
||||
acl_user->user_resource.user_conn= mqh->user_conn;
|
||||
if (ssl_type != SSL_TYPE_NOT_SPECIFIED)
|
||||
{
|
||||
acl_user->ssl_type= ssl_type;
|
||||
@ -1605,7 +1616,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
if (combo.password.str) // If password given
|
||||
table->field[2]->store(password, password_len, system_charset_info);
|
||||
else if (!rights && !revoke_grant &&
|
||||
lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && !lex->mqh.bits)
|
||||
lex->ssl_type == SSL_TYPE_NOT_SPECIFIED &&
|
||||
!lex->mqh.specified_limits)
|
||||
{
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
@ -1667,13 +1679,16 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
}
|
||||
|
||||
USER_RESOURCES mqh= lex->mqh;
|
||||
if (mqh.bits & 1)
|
||||
if (mqh.specified_limits & USER_RESOURCES::QUERIES_PER_HOUR)
|
||||
table->field[28]->store((longlong) mqh.questions);
|
||||
if (mqh.bits & 2)
|
||||
if (mqh.specified_limits & USER_RESOURCES::UPDATES_PER_HOUR)
|
||||
table->field[29]->store((longlong) mqh.updates);
|
||||
if (mqh.bits & 4)
|
||||
table->field[30]->store((longlong) mqh.connections);
|
||||
mqh_used = mqh_used || mqh.questions || mqh.updates || mqh.connections;
|
||||
if (mqh.specified_limits & USER_RESOURCES::CONNECTIONS_PER_HOUR)
|
||||
table->field[30]->store((longlong) mqh.conn_per_hour);
|
||||
if (table->fields >= 34 &&
|
||||
(mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
|
||||
table->field[33]->store((longlong) mqh.user_conn);
|
||||
mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
|
||||
}
|
||||
if (old_row_exists)
|
||||
{
|
||||
@ -3345,8 +3360,10 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
}
|
||||
}
|
||||
if ((want_access & GRANT_ACL) ||
|
||||
(acl_user->user_resource.questions | acl_user->user_resource.updates |
|
||||
acl_user->user_resource.connections))
|
||||
(acl_user->user_resource.questions ||
|
||||
acl_user->user_resource.updates ||
|
||||
acl_user->user_resource.conn_per_hour ||
|
||||
acl_user->user_resource.user_conn))
|
||||
{
|
||||
global.append(" WITH",5);
|
||||
if (want_access & GRANT_ACL)
|
||||
@ -3355,8 +3372,10 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
"MAX_QUERIES_PER_HOUR");
|
||||
add_user_option(&global, acl_user->user_resource.updates,
|
||||
"MAX_UPDATES_PER_HOUR");
|
||||
add_user_option(&global, acl_user->user_resource.connections,
|
||||
add_user_option(&global, acl_user->user_resource.conn_per_hour,
|
||||
"MAX_CONNECTIONS_PER_HOUR");
|
||||
add_user_option(&global, acl_user->user_resource.user_conn,
|
||||
"MAX_USER_CONNECTIONS");
|
||||
}
|
||||
protocol->prepare_for_resend();
|
||||
protocol->store(global.ptr(),global.length(),global.charset());
|
||||
|
Reference in New Issue
Block a user