Commit 48fd7552 authored by Michael Widenius's avatar Michael Widenius

Automatic merge with 5.2

parents 69aea4bb b32cd30c
...@@ -943,6 +943,7 @@ inline bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list) ...@@ -943,6 +943,7 @@ inline bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list)
inline bool check_some_routine_access(THD *thd, const char *db, inline bool check_some_routine_access(THD *thd, const char *db,
const char *name, bool is_proc) const char *name, bool is_proc)
{ return false; } { return false; }
#define decrease_user_connections(X) do { } while(0) /* nothing */
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/ #endif /*NO_EMBEDDED_ACCESS_CHECKS*/
bool multi_update_precheck(THD *thd, TABLE_LIST *tables); bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
...@@ -1176,7 +1177,9 @@ bool init_new_connection_handler_thread(); ...@@ -1176,7 +1177,9 @@ bool init_new_connection_handler_thread();
void reset_mqh(LEX_USER *lu, bool get_them); void reset_mqh(LEX_USER *lu, bool get_them);
bool check_mqh(THD *thd, uint check_command); bool check_mqh(THD *thd, uint check_command);
void time_out_user_resource_limits(THD *thd, USER_CONN *uc); void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
void decrease_user_connections(USER_CONN *uc); void decrease_user_connections(USER_CONN *uc);
#endif
bool thd_init_client_charset(THD *thd, uint cs_number); bool thd_init_client_charset(THD *thd, uint cs_number);
inline bool is_supported_parser_charset(CHARSET_INFO *cs) inline bool is_supported_parser_charset(CHARSET_INFO *cs)
{ {
......
...@@ -6978,7 +6978,6 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name, ...@@ -6978,7 +6978,6 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name,
#undef HAVE_OPENSSL #undef HAVE_OPENSSL
#ifdef NO_EMBEDDED_ACCESS_CHECKS #ifdef NO_EMBEDDED_ACCESS_CHECKS
#define initialized 0 #define initialized 0
#define decrease_user_connections(X) /* nothing */
#define check_for_max_user_connections(X,Y) 0 #define check_for_max_user_connections(X,Y) 0
#define get_or_create_user_conn(A,B,C,D) 0 #define get_or_create_user_conn(A,B,C,D) 0
#endif #endif
...@@ -8167,6 +8166,8 @@ bool acl_authenticate(THD *thd, uint connect_errors, ...@@ -8167,6 +8166,8 @@ bool acl_authenticate(THD *thd, uint connect_errors,
max_user_connections) && max_user_connections) &&
check_for_max_user_connections(thd, thd->user_connect)) check_for_max_user_connections(thd, thd->user_connect))
{ {
/* Ensure we don't decrement thd->user_connections->connections twice */
thd->user_connect= 0;
status_var_increment(denied_connections); status_var_increment(denied_connections);
DBUG_RETURN(1); // The error is set in check_for_max_user_connections() DBUG_RETURN(1); // The error is set in check_for_max_user_connections()
} }
...@@ -8207,12 +8208,7 @@ bool acl_authenticate(THD *thd, uint connect_errors, ...@@ -8207,12 +8208,7 @@ bool acl_authenticate(THD *thd, uint connect_errors,
if (mysql_change_db(thd, &mpvio.db, FALSE)) if (mysql_change_db(thd, &mpvio.db, FALSE))
{ {
/* mysql_change_db() has pushed the error message. */ /* mysql_change_db() has pushed the error message. */
if (thd->user_connect) status_var_increment(thd->status_var.access_denied_errors);
{
status_var_increment(thd->status_var.access_denied_errors);
decrease_user_connections(thd->user_connect);
thd->user_connect= 0;
}
DBUG_RETURN(1); DBUG_RETURN(1);
} }
} }
......
...@@ -1095,6 +1095,11 @@ void THD::cleanup(void) ...@@ -1095,6 +1095,11 @@ void THD::cleanup(void)
lock=locked_tables; locked_tables=0; lock=locked_tables; locked_tables=0;
close_thread_tables(this); close_thread_tables(this);
} }
if (user_connect)
{
decrease_user_connections(user_connect);
user_connect= 0; // Safety
}
wt_thd_destroy(&transaction.wt); wt_thd_destroy(&transaction.wt);
#if defined(ENABLED_DEBUG_SYNC) #if defined(ENABLED_DEBUG_SYNC)
......
...@@ -49,6 +49,7 @@ int get_or_create_user_conn(THD *thd, const char *user, ...@@ -49,6 +49,7 @@ int get_or_create_user_conn(THD *thd, const char *user,
DBUG_ASSERT(user != 0); DBUG_ASSERT(user != 0);
DBUG_ASSERT(host != 0); DBUG_ASSERT(host != 0);
DBUG_ASSERT(thd->user_connect == 0);
user_len= strlen(user); user_len= strlen(user);
temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1; temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
...@@ -108,7 +109,7 @@ int get_or_create_user_conn(THD *thd, const char *user, ...@@ -108,7 +109,7 @@ int get_or_create_user_conn(THD *thd, const char *user,
int check_for_max_user_connections(THD *thd, USER_CONN *uc) int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{ {
int error=0; int error= 1;
DBUG_ENTER("check_for_max_user_connections"); DBUG_ENTER("check_for_max_user_connections");
(void) pthread_mutex_lock(&LOCK_user_conn); (void) pthread_mutex_lock(&LOCK_user_conn);
...@@ -116,7 +117,6 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) ...@@ -116,7 +117,6 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
max_user_connections < (uint) uc->connections) max_user_connections < (uint) uc->connections)
{ {
my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user); my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
error=1;
goto end; goto end;
} }
time_out_user_resource_limits(thd, uc); time_out_user_resource_limits(thd, uc);
...@@ -126,7 +126,6 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) ...@@ -126,7 +126,6 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
"max_user_connections", "max_user_connections",
(long) uc->user_resources.user_conn); (long) uc->user_resources.user_conn);
error= 1;
goto end; goto end;
} }
if (uc->user_resources.conn_per_hour && if (uc->user_resources.conn_per_hour &&
...@@ -135,10 +134,10 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc) ...@@ -135,10 +134,10 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
"max_connections_per_hour", "max_connections_per_hour",
(long) uc->user_resources.conn_per_hour); (long) uc->user_resources.conn_per_hour);
error=1;
goto end; goto end;
} }
uc->conn_per_hour++; uc->conn_per_hour++;
error= 0;
end: end:
if (error) if (error)
...@@ -1028,8 +1027,17 @@ void end_connection(THD *thd) ...@@ -1028,8 +1027,17 @@ void end_connection(THD *thd)
{ {
NET *net= &thd->net; NET *net= &thd->net;
plugin_thdvar_cleanup(thd); plugin_thdvar_cleanup(thd);
if (thd->user_connect) if (thd->user_connect)
{
/*
We decrease this variable early to make it easy to log again quickly.
This code is not critical as we will in any case do this test
again in thd->cleanup()
*/
decrease_user_connections(thd->user_connect); decrease_user_connections(thd->user_connect);
thd->user_connect= 0;
}
if (thd->killed || (net->error && net->vio != 0)) if (thd->killed || (net->error && net->vio != 0))
{ {
......
...@@ -1132,12 +1132,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1132,12 +1132,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* Ensure we don't free security_ctx->user in case we have to revert */ /* Ensure we don't free security_ctx->user in case we have to revert */
thd->security_ctx->user= 0; thd->security_ctx->user= 0;
thd->user_connect= 0;
if (acl_authenticate(thd, 0, packet_length)) if (acl_authenticate(thd, 0, packet_length))
{ {
/* Free user if allocated by acl_authenticate */ /* Free user if allocated by acl_authenticate */
x_free(thd->security_ctx->user); x_free(thd->security_ctx->user);
*thd->security_ctx= save_security_ctx; *thd->security_ctx= save_security_ctx;
if (thd->user_connect)
decrease_user_connections(thd->user_connect);
thd->user_connect= save_user_connect; thd->user_connect= save_user_connect;
thd->reset_db(save_db, save_db_length); thd->reset_db(save_db, save_db_length);
thd->variables.character_set_client= save_character_set_client; thd->variables.character_set_client= save_character_set_client;
......
...@@ -320,25 +320,32 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn, ...@@ -320,25 +320,32 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
skip_DDLs= skip_DDLs_arg; skip_DDLs= skip_DDLs_arg;
skipped_undo_phase= 0; skipped_undo_phase= 0;
trnman_init(max_trid_in_control_file);
if (from_lsn == LSN_IMPOSSIBLE) if (from_lsn == LSN_IMPOSSIBLE)
{ {
if (last_checkpoint_lsn == LSN_IMPOSSIBLE) if (last_checkpoint_lsn == LSN_IMPOSSIBLE)
{ {
from_lsn= translog_first_lsn_in_log(); from_lsn= translog_first_lsn_in_log();
if (unlikely(from_lsn == LSN_ERROR)) if (unlikely(from_lsn == LSN_ERROR))
{
trnman_destroy();
goto err; goto err;
}
} }
else else
{ {
from_lsn= parse_checkpoint_record(last_checkpoint_lsn); from_lsn= parse_checkpoint_record(last_checkpoint_lsn);
if (from_lsn == LSN_ERROR) if (from_lsn == LSN_ERROR)
{
trnman_destroy();
goto err; goto err;
}
} }
} }
now= microsecond_interval_timer(); now= microsecond_interval_timer();
in_redo_phase= TRUE; in_redo_phase= TRUE;
trnman_init(max_trid_in_control_file);
if (run_redo_phase(from_lsn, end_lsn, apply)) if (run_redo_phase(from_lsn, end_lsn, apply))
{ {
ma_message_no_user(0, "Redo phase failed"); ma_message_no_user(0, "Redo phase failed");
......
...@@ -123,6 +123,9 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type, ...@@ -123,6 +123,9 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type,
if (protocol->write()) if (protocol->write())
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n", sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf); msgbuf);
else if (thd->variables.log_warnings > 2)
sql_print_error("%s", msgbuf);
#ifdef THREAD #ifdef THREAD
if (param->need_print_msg_lock) if (param->need_print_msg_lock)
pthread_mutex_unlock(&param->print_msg_mutex); pthread_mutex_unlock(&param->print_msg_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment