diff options
author | unknown <anozdrin/alik@quad.opbmk> | 2008-03-18 13:51:17 +0300 |
---|---|---|
committer | unknown <anozdrin/alik@quad.opbmk> | 2008-03-18 13:51:17 +0300 |
commit | a65e60b7427d3831a60964f161f4561197043fd5 (patch) | |
tree | e96aaaaa6d8f3413c11e63aee2802003dfc5b2bc /sql | |
parent | f36c8297af12a04344157235a748e7608682d002 (diff) | |
parent | 8e4a7deadcbae86a929b089e6f6d818d6e36c481 (diff) | |
download | mariadb-git-a65e60b7427d3831a60964f161f4561197043fd5.tar.gz |
Merge quad.opbmk:/mnt/raid/alik/MySQL/devel/5.1
into quad.opbmk:/mnt/raid/alik/MySQL/devel/5.1-rt-merged
libmysql/libmysql.c:
Auto merged
sql-common/client.c:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/mysqld.cc:
Auto merged
tests/mysql_client_test.c:
Auto merged
Diffstat (limited to 'sql')
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/mysqld.cc | 48 | ||||
-rw-r--r-- | sql/sql_cache.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.cc | 22 | ||||
-rw-r--r-- | sql/sql_connect.cc | 13 | ||||
-rw-r--r-- | sql/sql_delete.cc | 14 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 4 |
7 files changed, 82 insertions, 25 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9bdf6e2a1d5..f035318c880 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -975,8 +975,6 @@ void time_out_user_resource_limits(THD *thd, USER_CONN *uc); void decrease_user_connections(USER_CONN *uc); void thd_init_client_charset(THD *thd, uint cs_number); bool setup_connection_thread_globals(THD *thd); -bool login_connection(THD *thd); -void end_connection(THD *thd); bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent); bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create); @@ -1897,6 +1895,7 @@ extern bool opt_disable_networking, opt_skip_show_db; extern my_bool opt_character_set_client_handshake; extern bool volatile abort_loop, shutdown_in_progress; extern uint volatile thread_count, thread_running, global_read_lock; +extern uint connection_count; extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; extern my_bool opt_slave_compressed_protocol, use_temp_pool; @@ -1935,7 +1934,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db, LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock, LOCK_global_system_variables, LOCK_user_conn, LOCK_prepared_stmt_count, - LOCK_bytes_sent, LOCK_bytes_received; + LOCK_bytes_sent, LOCK_bytes_received, LOCK_connection_count; #ifdef HAVE_OPENSSL extern pthread_mutex_t LOCK_des_key_file; #endif diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d329c6798a7..16c65f48708 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -585,7 +585,8 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_global_system_variables, - LOCK_user_conn, LOCK_slave_list, LOCK_active_mi; + LOCK_user_conn, LOCK_slave_list, LOCK_active_mi, + LOCK_connection_count; /** The below lock protects access to two global server variables: max_prepared_stmt_count and prepared_stmt_count. These variables @@ -721,6 +722,11 @@ char *des_key_file; struct st_VioSSLFd *ssl_acceptor_fd; #endif /* HAVE_OPENSSL */ +/** + Number of currently active user connections. The variable is protected by + LOCK_connection_count. +*/ +uint connection_count= 0; /* Function declarations */ @@ -1342,6 +1348,7 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_bytes_sent); (void) pthread_mutex_destroy(&LOCK_bytes_received); (void) pthread_mutex_destroy(&LOCK_user_conn); + (void) pthread_mutex_destroy(&LOCK_connection_count); Events::destroy_mutexes(); #ifdef HAVE_OPENSSL (void) pthread_mutex_destroy(&LOCK_des_key_file); @@ -1784,6 +1791,11 @@ void unlink_thd(THD *thd) DBUG_ENTER("unlink_thd"); DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd)); thd->cleanup(); + + pthread_mutex_lock(&LOCK_connection_count); + --connection_count; + pthread_mutex_unlock(&LOCK_connection_count); + (void) pthread_mutex_lock(&LOCK_thread_count); thread_count--; delete thd; @@ -3452,6 +3464,7 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST); + (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST); #ifdef HAVE_OPENSSL (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST); #ifndef HAVE_YASSL @@ -4699,6 +4712,11 @@ void create_thread_to_handle_connection(THD *thd) thread_count--; thd->killed= THD::KILL_CONNECTION; // Safety (void) pthread_mutex_unlock(&LOCK_thread_count); + + pthread_mutex_lock(&LOCK_connection_count); + --connection_count; + pthread_mutex_unlock(&LOCK_connection_count); + statistic_increment(aborted_connects,&LOCK_status); /* Can't use my_error() since store_globals has not been called. */ my_snprintf(error_message_buff, sizeof(error_message_buff), @@ -4738,15 +4756,34 @@ static void create_new_thread(THD *thd) if (protocol_version > 9) net->return_errno=1; - /* don't allow too many connections */ - if (thread_count - delayed_insert_threads >= max_connections+1 || abort_loop) + /* + Don't allow too many connections. We roughly check here that we allow + only (max_connections + 1) connections. + */ + + pthread_mutex_lock(&LOCK_connection_count); + + if (connection_count >= max_connections + 1 || abort_loop) { + pthread_mutex_unlock(&LOCK_connection_count); + DBUG_PRINT("error",("Too many connections")); close_connection(thd, ER_CON_COUNT_ERROR, 1); delete thd; DBUG_VOID_RETURN; } + + ++connection_count; + + if (connection_count > max_used_connections) + max_used_connections= connection_count; + + pthread_mutex_unlock(&LOCK_connection_count); + + /* Start a new thread to handle connection. */ + pthread_mutex_lock(&LOCK_thread_count); + /* The initialization of thread_id is done in create_embedded_thd() for the embedded library. @@ -4754,13 +4791,10 @@ static void create_new_thread(THD *thd) */ thd->thread_id= thd->variables.pseudo_thread_id= thread_id++; - /* Start a new thread to handle connection */ thread_count++; - if (thread_count - delayed_insert_threads > max_used_connections) - max_used_connections= thread_count - delayed_insert_threads; - thread_scheduler.add_connection(thd); + DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index ae6765c7934..388700f0efa 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1998,6 +1998,7 @@ void Query_cache::make_disabled() query_cache_size= 0; queries_blocks= 0; free_memory= 0; + free_memory_blocks= 0; bins= 0; steps= 0; cache= 0; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 376102c8bf9..594577dd89c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -395,8 +395,11 @@ Diagnostics_area::set_ok_status(THD *thd, ha_rows affected_rows_arg, { DBUG_ASSERT(! is_set()); #ifdef DBUG_OFF - /* In production, refuse to overwrite an error with an OK packet. */ - if (is_error()) + /* + In production, refuse to overwrite an error or a custom response + with an OK packet. + */ + if (is_error() || is_disabled()) return; #endif /** Only allowed to report success if has not yet reported an error */ @@ -424,8 +427,11 @@ Diagnostics_area::set_eof_status(THD *thd) DBUG_ASSERT(! is_set()); #ifdef DBUG_OFF - /* In production, refuse to overwrite an error with an EOF packet. */ - if (is_error()) + /* + In production, refuse to overwrite an error or a custom response + with an EOF packet. + */ + if (is_error() || is_disabled()) return; #endif @@ -454,6 +460,14 @@ Diagnostics_area::set_error_status(THD *thd, uint sql_errno_arg, an error can happen during the flush. */ DBUG_ASSERT(! is_set() || can_overwrite_status); +#ifdef DBUG_OFF + /* + In production, refuse to overwrite a custom response with an + ERROR packet. + */ + if (is_disabled()) + return; +#endif m_sql_errno= sql_errno_arg; strmake(m_message, message_arg, sizeof(m_message) - 1); diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index b22a33e3e92..6f8cd6494cd 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -402,10 +402,11 @@ check_user(THD *thd, enum enum_server_command command, if (check_count) { - VOID(pthread_mutex_lock(&LOCK_thread_count)); - bool count_ok= thread_count <= max_connections + delayed_insert_threads - || (thd->main_security_ctx.master_access & SUPER_ACL); - VOID(pthread_mutex_unlock(&LOCK_thread_count)); + pthread_mutex_lock(&LOCK_connection_count); + bool count_ok= connection_count <= max_connections || + (thd->main_security_ctx.master_access & SUPER_ACL); + VOID(pthread_mutex_unlock(&LOCK_connection_count)); + if (!count_ok) { // too many connections my_error(ER_CON_COUNT_ERROR, MYF(0)); @@ -930,7 +931,7 @@ bool setup_connection_thread_globals(THD *thd) */ -bool login_connection(THD *thd) +static bool login_connection(THD *thd) { NET *net= &thd->net; int error; @@ -968,7 +969,7 @@ bool login_connection(THD *thd) This mainly updates status variables */ -void end_connection(THD *thd) +static void end_connection(THD *thd) { NET *net= &thd->net; plugin_thdvar_cleanup(thd); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 990f7713561..b9a7cd12662 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -45,6 +45,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, bool transactional_table, safe_update, const_cond; bool const_cond_result; ha_rows deleted= 0; + bool triggers_applicable; uint usable_index= MAX_KEY; SELECT_LEX *select_lex= &thd->lex->select_lex; THD::killed_state killed_status= THD::NOT_KILLED; @@ -102,6 +103,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, /* Error evaluating val_int(). */ DBUG_RETURN(TRUE); } + /* Test if the user wants to delete all rows and deletion doesn't have any side-effects (because of triggers), so we can use optimized @@ -249,7 +251,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, init_ftfuncs(thd, select_lex, 1); thd_proc_info(thd, "updating"); - if (table->triggers && + + /* NOTE: TRUNCATE must not invoke triggers. */ + + triggers_applicable= table->triggers && + thd->lex->sql_command != SQLCOM_TRUNCATE; + + if (triggers_applicable && table->triggers->has_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER)) { @@ -274,7 +282,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (!(select && select->skip_record())&& ! thd->is_error() ) { - if (table->triggers && + if (triggers_applicable && table->triggers->process_triggers(thd, TRG_EVENT_DELETE, TRG_ACTION_BEFORE, FALSE)) { @@ -285,7 +293,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (!(error= table->file->ha_delete_row(table->record[0]))) { deleted++; - if (table->triggers && + if (triggers_applicable && table->triggers->process_triggers(thd, TRG_EVENT_DELETE, TRG_ACTION_AFTER, FALSE)) { diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index a027ffe9daa..c922b21af90 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2555,6 +2555,8 @@ void mysql_stmt_close(THD *thd, char *packet) Prepared_statement *stmt; DBUG_ENTER("mysql_stmt_close"); + thd->main_da.disable_status(); + if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close"))) DBUG_VOID_RETURN; @@ -2566,8 +2568,6 @@ void mysql_stmt_close(THD *thd, char *packet) (void) stmt->deallocate(); general_log_print(thd, thd->command, NullS); - thd->main_da.disable_status(); - DBUG_VOID_RETURN; } |