summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMarc Alff <marc.alff@sun.com>2009-12-17 02:12:02 -0700
committerMarc Alff <marc.alff@sun.com>2009-12-17 02:12:02 -0700
commit4e8d1c6bf30abfd45a993b058ff2a33d4671b73d (patch)
tree4b84506f98fd3e9ba8a57b531c2609eb5bd11fbe /sql
parent0d99234dba5dc64bc4f369361f8fc0a669b8dff3 (diff)
parenta2a4c70c1bfd077a1281604bdd8368dd32ab6e83 (diff)
downloadmariadb-git-4e8d1c6bf30abfd45a993b058ff2a33d4671b73d.tar.gz
Merge mysql-next-mr (revno 2939) --> mysql-next-mr-marc
Diffstat (limited to 'sql')
-rw-r--r--sql/event_scheduler.cc9
-rw-r--r--sql/log_event.cc13
-rw-r--r--sql/mysql_priv.h56
-rw-r--r--sql/mysqld.cc9
-rw-r--r--sql/net_serv.cc2
-rw-r--r--sql/slave.cc17
-rw-r--r--sql/sp_head.cc6
-rw-r--r--sql/sql_base.cc9
-rw-r--r--sql/sql_class.cc20
-rw-r--r--sql/sql_class.h5
-rw-r--r--sql/sql_cursor.cc2
-rw-r--r--sql/sql_parse.cc54
12 files changed, 143 insertions, 59 deletions
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index d9ca161f260..31bb3d39b85 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -132,9 +132,8 @@ post_init_event_thread(THD *thd)
pthread_mutex_lock(&LOCK_thread_count);
threads.append(thd);
thread_count++;
- thread_running++;
+ inc_thread_running();
pthread_mutex_unlock(&LOCK_thread_count);
-
return FALSE;
}
@@ -156,7 +155,7 @@ deinit_event_thread(THD *thd)
DBUG_PRINT("exit", ("Event thread finishing"));
pthread_mutex_lock(&LOCK_thread_count);
thread_count--;
- thread_running--;
+ dec_thread_running();
delete thd;
pthread_cond_broadcast(&COND_thread_count);
pthread_mutex_unlock(&LOCK_thread_count);
@@ -417,7 +416,7 @@ Event_scheduler::start()
net_end(&new_thd->net);
pthread_mutex_lock(&LOCK_thread_count);
thread_count--;
- thread_running--;
+ dec_thread_running();
delete new_thd;
pthread_cond_broadcast(&COND_thread_count);
pthread_mutex_unlock(&LOCK_thread_count);
@@ -550,7 +549,7 @@ error:
net_end(&new_thd->net);
pthread_mutex_lock(&LOCK_thread_count);
thread_count--;
- thread_running--;
+ dec_thread_running();
delete new_thd;
pthread_cond_broadcast(&COND_thread_count);
pthread_mutex_unlock(&LOCK_thread_count);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index cc2b4667115..10b4ecd3f7b 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -3055,10 +3055,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
rpl_filter->db_ok(thd->db))
{
thd->set_time((time_t)when);
- thd->set_query((char*)query_arg, q_len_arg);
- pthread_mutex_lock(&LOCK_thread_count);
- thd->query_id = next_query_id();
- pthread_mutex_unlock(&LOCK_thread_count);
+ thd->set_query_and_id((char*)query_arg, q_len_arg, next_query_id());
thd->variables.pseudo_thread_id= thread_id; // for temp tables
DBUG_PRINT("query",("%s", thd->query()));
@@ -4580,9 +4577,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
if (rpl_filter->db_ok(thd->db))
{
thd->set_time((time_t)when);
- pthread_mutex_lock(&LOCK_thread_count);
- thd->query_id = next_query_id();
- pthread_mutex_unlock(&LOCK_thread_count);
+ thd->set_query_id(next_query_id());
thd->warning_info->opt_clear_warning_info(thd->query_id);
TABLE_LIST tables;
@@ -8071,9 +8066,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
DBUG_ASSERT(rli->sql_thd == thd);
/* Step the query id to mark what columns that are actually used. */
- pthread_mutex_lock(&LOCK_thread_count);
- thd->query_id= next_query_id();
- pthread_mutex_unlock(&LOCK_thread_count);
+ thd->set_query_id(next_query_id());
if (!(memory= my_multi_malloc(MYF(MY_WME),
&table_list, (uint) sizeof(RPL_TABLE_LIST),
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 46fab53039f..3ddaf114673 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -53,6 +53,7 @@
#include "sql_array.h"
#include "sql_plugin.h"
#include "scheduler.h"
+#include <my_atomic.h>
#include <mysql/psi/mysql_file.h>
#ifndef __WIN__
#include <netdb.h>
@@ -89,11 +90,60 @@ typedef ulong nesting_map; /* Used for flags of nesting constructs */
typedef ulonglong nested_join_map;
/* query_id */
-typedef ulonglong query_id_t;
+typedef int64 query_id_t;
extern query_id_t global_query_id;
+extern int32 thread_running;
+extern my_atomic_rwlock_t global_query_id_lock;
+extern my_atomic_rwlock_t thread_running_lock;
/* increment query_id and return it. */
-inline query_id_t next_query_id() { return global_query_id++; }
+inline query_id_t next_query_id()
+{
+ query_id_t id;
+ my_atomic_rwlock_wrlock(&global_query_id_lock);
+ id= my_atomic_add64(&global_query_id, 1);
+ my_atomic_rwlock_wrunlock(&global_query_id_lock);
+ return (id+1);
+}
+
+inline query_id_t get_query_id()
+{
+ query_id_t id;
+ my_atomic_rwlock_wrlock(&global_query_id_lock);
+ id= my_atomic_load64(&global_query_id);
+ my_atomic_rwlock_wrunlock(&global_query_id_lock);
+ return id;
+}
+
+inline int32
+inc_thread_running()
+{
+ int32 num_thread_running;
+ my_atomic_rwlock_wrlock(&thread_running_lock);
+ num_thread_running= my_atomic_add32(&thread_running, 1);
+ my_atomic_rwlock_wrunlock(&thread_running_lock);
+ return (num_thread_running+1);
+}
+
+inline int32
+dec_thread_running()
+{
+ int32 num_thread_running;
+ my_atomic_rwlock_wrlock(&thread_running_lock);
+ num_thread_running= my_atomic_add32(&thread_running, -1);
+ my_atomic_rwlock_wrunlock(&thread_running_lock);
+ return (num_thread_running-1);
+}
+
+inline int32
+get_thread_running()
+{
+ int32 num_thread_running;
+ my_atomic_rwlock_wrlock(&thread_running_lock);
+ num_thread_running= my_atomic_load32(&thread_running);
+ my_atomic_rwlock_wrunlock(&thread_running_lock);
+ return num_thread_running;
+}
/* useful constants */
extern MYSQL_PLUGIN_IMPORT const key_map key_map_empty;
@@ -1955,7 +2005,7 @@ extern bool opt_ignore_builtin_innodb;
extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop, shutdown_in_progress;
extern bool in_bootstrap;
-extern uint volatile thread_count, thread_running, global_read_lock;
+extern uint volatile thread_count, 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;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 88b7b5931f7..e8d2b10034a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -524,7 +524,8 @@ uint mysqld_port_timeout;
uint delay_key_write_options, protocol_version;
uint lower_case_table_names;
uint tc_heuristic_recover= 0;
-uint volatile thread_count, thread_running;
+uint volatile thread_count;
+int32 thread_running;
ulonglong thd_startup_options;
ulong back_log, connect_timeout, concurrency, server_id;
ulong table_cache_size, table_def_size;
@@ -540,6 +541,8 @@ ulonglong max_binlog_cache_size=0;
ulong query_cache_size=0;
ulong refresh_version; /* Increments on each reload */
query_id_t global_query_id;
+my_atomic_rwlock_t global_query_id_lock;
+my_atomic_rwlock_t thread_running_lock;
ulong aborted_threads, aborted_connects;
ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
@@ -1372,6 +1375,8 @@ void clean_up(bool print_message)
DBUG_PRINT("quit", ("Error messages freed"));
/* Tell main we are ready */
logger.cleanup_end();
+ my_atomic_rwlock_destroy(&global_query_id_lock);
+ my_atomic_rwlock_destroy(&thread_running_lock);
(void) pthread_mutex_lock(&LOCK_thread_count);
DBUG_PRINT("quit", ("got thread count lock"));
ready_to_exit=1;
@@ -7789,6 +7794,8 @@ static int mysql_init_variables(void)
what_to_log= ~ (1L << (uint) COM_TIME);
refresh_version= 1L; /* Increments on each reload */
global_query_id= thread_id= 1L;
+ my_atomic_rwlock_init(&global_query_id_lock);
+ my_atomic_rwlock_init(&thread_running_lock);
strmov(server_version, MYSQL_SERVER_VERSION);
myisam_recover_options_str= sql_mode_str= "OFF";
myisam_stats_method_str= "nulls_unequal";
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 5cf3597c638..d54ff1d2779 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -71,8 +71,10 @@
#if defined(__WIN__) || !defined(MYSQL_SERVER)
/* The following is because alarms doesn't work on windows. */
+#ifndef NO_ALARM
#define NO_ALARM
#endif
+#endif
#ifndef NO_ALARM
#include "my_pthread.h"
diff --git a/sql/slave.cc b/sql/slave.cc
index 6d78d44f6f2..6876734d746 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1206,6 +1206,8 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
mi->clock_diff_with_master=
(long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10));
}
+ else if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ goto slave_killed_err;
else if (is_network_error(mysql_errno(mysql)))
{
mi->report(WARNING_LEVEL, mysql_errno(mysql),
@@ -1258,7 +1260,9 @@ not always make sense; please check the manual before using it).";
}
else if (mysql_errno(mysql))
{
- if (is_network_error(mysql_errno(mysql)))
+ if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ goto slave_killed_err;
+ else if (is_network_error(mysql_errno(mysql)))
{
mi->report(WARNING_LEVEL, mysql_errno(mysql),
"Get master SERVER_ID failed with error: %s", mysql_error(mysql));
@@ -1329,6 +1333,8 @@ be equal for the Statement-format replication to work";
goto err;
}
}
+ else if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ goto slave_killed_err;
else if (is_network_error(mysql_errno(mysql)))
{
mi->report(WARNING_LEVEL, mysql_errno(mysql),
@@ -1390,6 +1396,8 @@ be equal for the Statement-format replication to work";
goto err;
}
}
+ else if (check_io_slave_killed(mi->io_thd, mi, NULL))
+ goto slave_killed_err;
else if (is_network_error(mysql_errno(mysql)))
{
mi->report(WARNING_LEVEL, mysql_errno(mysql),
@@ -1453,6 +1461,11 @@ network_err:
if (master_res)
mysql_free_result(master_res);
DBUG_RETURN(2);
+
+slave_killed_err:
+ if (master_res)
+ mysql_free_result(master_res);
+ DBUG_RETURN(2);
}
static bool wait_for_relay_log_space(Relay_log_info* rli)
@@ -2678,7 +2691,7 @@ connected:
if (ret == 1)
/* Fatal error */
goto err;
-
+
if (ret == 2)
{
if (check_io_slave_killed(mi->io_thd, mi, "Slave I/O thread killed"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 542db282700..3f7d812384c 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1335,7 +1335,7 @@ sp_head::execute(THD *thd)
/* To avoid wiping out thd->change_list on old_change_list destruction */
old_change_list.empty();
thd->lex= old_lex;
- thd->query_id= old_query_id;
+ thd->set_query_id(old_query_id);
DBUG_ASSERT(!thd->derived_tables);
thd->derived_tables= old_derived_tables;
thd->variables.sql_mode= save_sql_mode;
@@ -2745,9 +2745,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
*/
thd->lex= m_lex;
- pthread_mutex_lock(&LOCK_thread_count);
- thd->query_id= next_query_id();
- pthread_mutex_unlock(&LOCK_thread_count);
+ thd->set_query_id(next_query_id());
if (thd->prelocked_mode == NON_PRELOCKED)
{
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 7df66a5af16..ee264ec3de6 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2555,6 +2555,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
char key[MAX_DBKEY_LENGTH];
uint key_length;
char *alias= table_list->alias;
+ my_hash_value_type hash_value;
HASH_SEARCH_STATE state;
DBUG_ENTER("open_table");
@@ -2741,6 +2742,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
on disk.
*/
+ hash_value= my_calc_hash(&open_cache, (uchar*) key, key_length);
mysql_mutex_lock(&LOCK_open);
/*
@@ -2783,8 +2785,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
an implicit "pending locks queue" - see
wait_for_locked_table_names for details.
*/
- for (table= (TABLE*) my_hash_first(&open_cache, (uchar*) key, key_length,
- &state);
+ for (table= (TABLE*) my_hash_first_from_hash_value(&open_cache,
+ hash_value,
+ (uchar*) key,
+ key_length,
+ &state);
table && table->in_use ;
table= (TABLE*) my_hash_next(&open_cache, (uchar*) key, key_length,
&state))
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index cded82c2e87..019c22d9dd2 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -3273,6 +3273,26 @@ void THD::set_query(char *query_arg, uint32 query_length_arg)
pthread_mutex_unlock(&LOCK_thd_data);
}
+/** Assign a new value to thd->query and thd->query_id. */
+
+void THD::set_query_and_id(char *query_arg, uint32 query_length_arg,
+ query_id_t new_query_id)
+{
+ pthread_mutex_lock(&LOCK_thd_data);
+ set_query_inner(query_arg, query_length_arg);
+ query_id= new_query_id;
+ pthread_mutex_unlock(&LOCK_thd_data);
+}
+
+/** Assign a new value to thd->query_id. */
+
+void THD::set_query_id(query_id_t new_query_id)
+{
+ pthread_mutex_lock(&LOCK_thd_data);
+ query_id= new_query_id;
+ pthread_mutex_unlock(&LOCK_thd_data);
+}
+
/**
Mark transaction to rollback and mark error as fatal to a sub-statement.
diff --git a/sql/sql_class.h b/sql/sql_class.h
index b518ac84d8f..4156f2afa8e 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -2319,10 +2319,13 @@ public:
virtual void set_statement(Statement *stmt);
/**
- Assign a new value to thd->query.
+ Assign a new value to thd->query and thd->query_id.
Protected with LOCK_thd_data mutex.
*/
void set_query(char *query_arg, uint32 query_length_arg);
+ void set_query_and_id(char *query_arg, uint32 query_length_arg,
+ query_id_t new_query_id);
+ void set_query_id(query_id_t new_query_id);
private:
/** The current internal error handler for this thread, or NULL. */
Internal_error_handler *m_internal_handler;
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index ffc3fafe55f..533b47e61da 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -438,7 +438,7 @@ Sensitive_cursor::fetch(ulong num_rows)
thd->derived_tables= derived_tables;
thd->open_tables= open_tables;
thd->lock= lock;
- thd->query_id= query_id;
+ thd->set_query_id(query_id);
thd->change_list= change_list;
/* save references to memory allocated during fetch */
thd->set_n_backup_active_arena(this, &backup_arena);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 30af6dc93b4..0774e373908 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -482,7 +482,7 @@ static void handle_bootstrap_impl(THD *thd)
query= (char *) thd->memdup_w_gap(buff, length + 1,
thd->db_length + 1 +
QUERY_CACHE_FLAGS_SIZE);
- thd->set_query(query, length);
+ thd->set_query_and_id(query, length, next_query_id());
DBUG_PRINT("query",("%-.4096s",thd->query()));
#if defined(ENABLED_PROFILING)
thd->profiling.start_new_query();
@@ -493,7 +493,6 @@ static void handle_bootstrap_impl(THD *thd)
We don't need to obtain LOCK_thread_count here because in bootstrap
mode we have only one thread.
*/
- thd->query_id=next_query_id();
thd->set_time();
mysql_parse(thd, thd->query(), length, & found_semicolon);
close_thread_tables(thd); // Free tables
@@ -915,29 +914,29 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->enable_slow_log= TRUE;
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
thd->set_time();
- pthread_mutex_lock(&LOCK_thread_count);
- thd->query_id= global_query_id;
-
- switch( command ) {
- /* Ignore these statements. */
- case COM_STATISTICS:
- case COM_PING:
- break;
- /* Only increase id on these statements but don't count them. */
- case COM_STMT_PREPARE:
- case COM_STMT_CLOSE:
- case COM_STMT_RESET:
- next_query_id();
- break;
- /* Increase id and count all other statements. */
- default:
- statistic_increment(thd->status_var.questions, &LOCK_status);
- next_query_id();
+ {
+ query_id_t query_id;
+ switch( command ) {
+ /* Ignore these statements. */
+ case COM_STATISTICS:
+ case COM_PING:
+ query_id= get_query_id();
+ break;
+ /* Only increase id on these statements but don't count them. */
+ case COM_STMT_PREPARE:
+ case COM_STMT_CLOSE:
+ case COM_STMT_RESET:
+ query_id= next_query_id() - 1;
+ break;
+ /* Increase id and count all other statements. */
+ default:
+ statistic_increment(thd->status_var.questions, &LOCK_status);
+ query_id= next_query_id() - 1;
+ }
+ thd->set_query_id(query_id);
}
-
- thread_running++;
+ inc_thread_running();
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
- pthread_mutex_unlock(&LOCK_thread_count);
/**
Clear the set of flags that are expected to be cleared at the
@@ -1165,16 +1164,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->security_ctx->priv_user,
(char *) thd->security_ctx->host_or_ip);
- thd->set_query(beginning_of_next_stmt, length);
- pthread_mutex_lock(&LOCK_thread_count);
+ thd->set_query_and_id(beginning_of_next_stmt, length, next_query_id());
/*
Count each statement from the client.
*/
statistic_increment(thd->status_var.questions, &LOCK_status);
- thd->query_id= next_query_id();
thd->set_time(); /* Reset the query start time. */
/* TODO: set thd->lex->sql_command to SQLCOM_END here */
- pthread_mutex_unlock(&LOCK_thread_count);
mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
}
@@ -1488,9 +1484,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd_proc_info(thd, "cleaning up");
thd->set_query(NULL, 0);
thd->command=COM_SLEEP;
- pthread_mutex_lock(&LOCK_thread_count); // For process list
- thread_running--;
- pthread_mutex_unlock(&LOCK_thread_count);
+ dec_thread_running();
thd_proc_info(thd, 0);
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));