summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <anozdrin/alik@quad.opbmk>2008-03-18 13:51:17 +0300
committerunknown <anozdrin/alik@quad.opbmk>2008-03-18 13:51:17 +0300
commita65e60b7427d3831a60964f161f4561197043fd5 (patch)
treee96aaaaa6d8f3413c11e63aee2802003dfc5b2bc /sql
parentf36c8297af12a04344157235a748e7608682d002 (diff)
parent8e4a7deadcbae86a929b089e6f6d818d6e36c481 (diff)
downloadmariadb-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.h5
-rw-r--r--sql/mysqld.cc48
-rw-r--r--sql/sql_cache.cc1
-rw-r--r--sql/sql_class.cc22
-rw-r--r--sql/sql_connect.cc13
-rw-r--r--sql/sql_delete.cc14
-rw-r--r--sql/sql_prepare.cc4
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;
}