Commit 6b3654f9 authored by Michael Widenius's avatar Michael Widenius

Automatic merge

parents 22f91edd 2c40fb56
......@@ -216,7 +216,7 @@ struct st_vio
struct sockaddr_storage remote; /* Remote internet address */
int addrLen; /* Length of remote address */
enum enum_vio_type type; /* Type of connection */
char desc[30]; /* String description */
const char *desc; /* String description */
char *read_buffer; /* buffer for vio_read_buff */
char *read_pos; /* start of unfetched data in the
read buffer */
......
......@@ -64,6 +64,7 @@ wait/synch/mutex/sql/LOCK_server_started
wait/synch/mutex/sql/LOCK_slave_list
wait/synch/mutex/sql/LOCK_stats
wait/synch/mutex/sql/LOCK_status
wait/synch/mutex/sql/LOCK_thread_cache
wait/synch/mutex/sql/LOCK_thread_count
wait/synch/mutex/sql/LOCK_user_conn
wait/synch/mutex/sql/LOCK_user_locks
......
......@@ -70,52 +70,34 @@ Success
TRUNCATE TABLE performance_schema.events_waits_history_long;
TRUNCATE TABLE performance_schema.events_waits_history;
TRUNCATE TABLE performance_schema.events_waits_current;
SELECT * FROM t1 WHERE id = 1;
id b
1 initial value
show variables like "%not_found%";
Variable_name Value
SET @before_count = (SELECT SUM(TIMER_WAIT)
FROM performance_schema.events_waits_history_long
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant'));
SELECT * FROM t1;
id b
1 initial value
2 initial value
3 initial value
4 initial value
5 initial value
6 initial value
7 initial value
8 initial value
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_system_variables_hash'));
show variables like "%not_found%";
Variable_name Value
SET @after_count = (SELECT SUM(TIMER_WAIT)
FROM performance_schema.events_waits_history_long
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant'));
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_system_variables_hash'));
SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_fm1_rw_timed;
test_fm1_rw_timed
Success
UPDATE performance_schema.setup_instruments SET enabled = 'NO'
WHERE NAME = 'wait/synch/rwlock/sql/LOCK_grant';
WHERE NAME = 'wait/synch/rwlock/sql/LOCK_system_variables_hash';
TRUNCATE TABLE performance_schema.events_waits_history_long;
TRUNCATE TABLE performance_schema.events_waits_history;
TRUNCATE TABLE performance_schema.events_waits_current;
SELECT * FROM t1 WHERE id = 1;
id b
1 initial value
show variables like "%not_found%";
Variable_name Value
SET @before_count = (SELECT SUM(TIMER_WAIT)
FROM performance_schema.events_waits_history_long
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant'));
SELECT * FROM t1;
id b
1 initial value
2 initial value
3 initial value
4 initial value
5 initial value
6 initial value
7 initial value
8 initial value
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_system_variables_hash'));
show variables like "%not_found%";
Variable_name Value
SET @after_count = (SELECT SUM(TIMER_WAIT)
FROM performance_schema.events_waits_history_long
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant'));
WHERE (EVENT_NAME = 'LOCK_system_variables_hash'));
SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_rw_timed;
test_fm2_rw_timed
Success
......
......@@ -87,38 +87,38 @@ TRUNCATE TABLE performance_schema.events_waits_history_long;
TRUNCATE TABLE performance_schema.events_waits_history;
TRUNCATE TABLE performance_schema.events_waits_current;
SELECT * FROM t1 WHERE id = 1;
show variables like "%not_found%";
SET @before_count = (SELECT SUM(TIMER_WAIT)
FROM performance_schema.events_waits_history_long
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant'));
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_system_variables_hash'));
SELECT * FROM t1;
show variables like "%not_found%";
SET @after_count = (SELECT SUM(TIMER_WAIT)
FROM performance_schema.events_waits_history_long
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant'));
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_system_variables_hash'));
SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_fm1_rw_timed;
UPDATE performance_schema.setup_instruments SET enabled = 'NO'
WHERE NAME = 'wait/synch/rwlock/sql/LOCK_grant';
WHERE NAME = 'wait/synch/rwlock/sql/LOCK_system_variables_hash';
TRUNCATE TABLE performance_schema.events_waits_history_long;
TRUNCATE TABLE performance_schema.events_waits_history;
TRUNCATE TABLE performance_schema.events_waits_current;
SELECT * FROM t1 WHERE id = 1;
show variables like "%not_found%";
SET @before_count = (SELECT SUM(TIMER_WAIT)
FROM performance_schema.events_waits_history_long
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant'));
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_system_variables_hash'));
SELECT * FROM t1;
show variables like "%not_found%";
SET @after_count = (SELECT SUM(TIMER_WAIT)
FROM performance_schema.events_waits_history_long
WHERE (EVENT_NAME = 'wait/synch/rwlock/sql/LOCK_grant'));
WHERE (EVENT_NAME = 'LOCK_system_variables_hash'));
SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_fm2_rw_timed;
......
......@@ -87,13 +87,17 @@ my_bool my_gethwaddr(uchar *to)
int fd, res= 1;
struct ifreq ifr[32];
struct ifconf ifc;
DBUG_ENTER("my_gethwaddr");
ifc.ifc_req= ifr;
ifc.ifc_len= sizeof(ifr);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
DBUG_PRINT("error", ("socket() call failed with %d", errno));
goto err;
}
if (ioctl(fd, SIOCGIFCONF, (char*)&ifc) >= 0)
{
......@@ -106,8 +110,8 @@ my_bool my_gethwaddr(uchar *to)
ETHER_ADDR_LEN);
#else
/*
A bug in OpenSolaris used to prevent non-root from getting a mac address:
{no url. Oracle killed the old OpenSolaris bug database}
A bug in OpenSolaris used to prevent non-root from getting a mac
address: {no url. Oracle killed the old OpenSolaris bug database}
Thus, we'll use an alternative method and extract the address from the
arp table.
......@@ -124,7 +128,7 @@ my_bool my_gethwaddr(uchar *to)
close(fd);
err:
return res;
DBUG_RETURN(res);
}
#elif defined(_WIN32)
......
......@@ -45,11 +45,20 @@ void my_rnd_init(struct my_rnd_struct *rand_st, ulong seed1, ulong seed2)
RETURN VALUE
generated pseudo random number
NOTE:
This is codes so that it can be called by two threads at the same time
with minimum impact.
(As the number is supposed to be random, it doesn't matter much if
rand->seed1 or rand->seed2 are updated with slightly wrong numbers or
if two threads gets the same number.
*/
double my_rnd(struct my_rnd_struct *rand_st)
{
rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % rand_st->max_value;
return (((double) rand_st->seed1)/rand_st->max_value_dbl);
unsigned long seed1;
seed1= (rand_st->seed1*3+rand_st->seed2) % rand_st->max_value;
rand_st->seed2=(seed1+rand_st->seed2+33) % rand_st->max_value;
rand_st->seed1= seed1;
return (((double) seed1)/rand_st->max_value_dbl);
}
......@@ -132,11 +132,11 @@ post_init_event_thread(THD *thd)
return TRUE;
}
thread_safe_increment32(&thread_count, &thread_count_lock);
mysql_mutex_lock(&LOCK_thread_count);
threads.append(thd);
thread_count++;
inc_thread_running();
mysql_mutex_unlock(&LOCK_thread_count);
inc_thread_running();
return FALSE;
}
......@@ -154,12 +154,8 @@ deinit_event_thread(THD *thd)
{
thd->proc_info= "Clearing";
DBUG_PRINT("exit", ("Event thread finishing"));
mysql_mutex_lock(&LOCK_thread_count);
thread_count--;
dec_thread_running();
delete thd;
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
delete_running_thd(thd);
}
......@@ -436,12 +432,7 @@ Event_scheduler::start()
ret= TRUE;
new_thd->proc_info= "Clearing";
mysql_mutex_lock(&LOCK_thread_count);
thread_count--;
dec_thread_running();
delete new_thd;
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
delete_running_thd(new_thd);
}
end:
UNLOCK_DATA();
......@@ -570,12 +561,7 @@ error:
if (new_thd)
{
new_thd->proc_info= "Clearing";
mysql_mutex_lock(&LOCK_thread_count);
thread_count--;
dec_thread_running();
delete new_thd;
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
delete_running_thd(new_thd);
}
delete event_name;
DBUG_RETURN(TRUE);
......
This diff is collapsed.
......@@ -56,6 +56,7 @@ void kill_mysql(void);
void close_connection(THD *thd, uint sql_errno= 0);
void handle_connection_in_main_thread(THD *thd);
void create_thread_to_handle_connection(THD *thd);
void delete_running_thd(THD *thd);
void unlink_thd(THD *thd);
bool one_thread_per_connection_end(THD *thd, bool put_in_cache);
void flush_thread_cache();
......@@ -89,7 +90,6 @@ extern bool opt_ignore_builtin_innodb;
extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop;
extern bool in_bootstrap;
extern uint volatile thread_count;
extern uint connection_count;
extern my_bool opt_safe_user_create;
extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
......@@ -352,7 +352,8 @@ extern mysql_rwlock_t LOCK_system_variables_hash;
extern mysql_cond_t COND_thread_count;
extern mysql_cond_t COND_manager;
extern int32 thread_running;
extern my_atomic_rwlock_t thread_running_lock;
extern int32 thread_count;
extern my_atomic_rwlock_t thread_running_lock, thread_count_lock;
extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
*opt_ssl_key;
......@@ -449,7 +450,7 @@ inline query_id_t next_query_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);
return (id);
}
inline query_id_t get_query_id()
......@@ -479,42 +480,30 @@ inline void table_case_convert(char * name, uint length)
name, length, name, length);
}
inline ulong sql_rnd_with_mutex()
inline void thread_safe_increment32(int32 *value, my_atomic_rwlock_t *lock)
{
mysql_mutex_lock(&LOCK_thread_count);
ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
mysql_mutex_unlock(&LOCK_thread_count);
return tmp;
my_atomic_rwlock_wrlock(lock);
(void) my_atomic_add32(value, 1);
my_atomic_rwlock_wrunlock(lock);
}
inline int32
inc_thread_running()
inline void thread_safe_decrement32(int32 *value, my_atomic_rwlock_t *lock)
{
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);
my_atomic_rwlock_wrlock(lock);
(void) my_atomic_add32(value, -1);
my_atomic_rwlock_wrunlock(lock);
}
inline int32
dec_thread_running()
inline void
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);
thread_safe_increment32(&thread_running, &thread_running_lock);
}
inline int32
get_thread_running()
inline void
dec_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;
thread_safe_decrement32(&thread_running, &thread_running_lock);
}
void set_server_version(void);
......
......@@ -4530,12 +4530,16 @@ end:
@see check_access
@see check_table_access
@note This functions assumes that either number of tables to be inspected
@note
This functions assumes that either number of tables to be inspected
by it is limited explicitly (i.e. is is not UINT_MAX) or table list
used and thd->lex->query_tables_own_last value correspond to each
other (the latter should be either 0 or point to next_global member
of one of elements of this table list).
We delay locking of LOCK_grant until we really need it as we assume that
most privileges be resolved with user or db level accesses.
@return Access status
@retval FALSE Access granted; But column privileges might need to be
checked.
......@@ -4552,6 +4556,8 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
Security_context *sctx= thd->security_ctx;
uint i;
ulong orig_want_access= want_access;
my_bool locked= 0;
GRANT_TABLE *grant_table;
DBUG_ENTER("check_grant");
DBUG_ASSERT(number > 0);
......@@ -4575,11 +4581,9 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
*/
tl->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
}
number= i;
mysql_rwlock_rdlock(&LOCK_grant);
for (tl= tables;
tl && number-- && tl != first_not_own_table;
tl= tl->next_global)
for (tl= tables; number-- ; tl= tl->next_global)
{
sctx = test(tl->security_ctx) ? tl->security_ctx : thd->security_ctx;
......@@ -4632,13 +4636,18 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
}
continue;
}
GRANT_TABLE *grant_table= table_hash_search(sctx->host, sctx->ip,
tl->get_db_name(),
sctx->priv_user,
tl->get_table_name(),
FALSE);
if (!grant_table)
if (!locked)
{
locked= 1;
mysql_rwlock_rdlock(&LOCK_grant);
}
if (!(grant_table= table_hash_search(sctx->host, sctx->ip,
tl->get_db_name(),
sctx->priv_user,
tl->get_table_name(),
FALSE)))
{
want_access &= ~tl->grant.privilege;
goto err; // No grants
......@@ -4665,11 +4674,13 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables,
goto err; // impossible
}
}
mysql_rwlock_unlock(&LOCK_grant);
if (locked)
mysql_rwlock_unlock(&LOCK_grant);
DBUG_RETURN(FALSE);
err:
mysql_rwlock_unlock(&LOCK_grant);
if (locked)
mysql_rwlock_unlock(&LOCK_grant);
if (!no_errors) // Not a silent skip of table
{
char command[128];
......
......@@ -349,29 +349,6 @@ void thd_set_thread_stack(THD *thd, char *stack_start)
thd->thread_stack= stack_start;
}
/**
Lock connection data for the set of connections this connection
belongs to
@param thd THD object
*/
void thd_lock_thread_count(THD *)
{
mysql_mutex_lock(&LOCK_thread_count);
}
/**
Lock connection data for the set of connections this connection
belongs to
@param thd THD object
*/
void thd_unlock_thread_count(THD *)
{
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
}
/**
Close the socket used by this connection
......@@ -947,7 +924,14 @@ THD::THD()
protocol_binary.init(this);
tablespace_op=FALSE;
tmp= sql_rnd_with_mutex();
/*
Initialize the random generator. We call my_rnd() without a lock as
it's not really critical if two threads modifies the structure at the
same time. We ensure that we have an unique number foreach thread
by adding the address of the stack.
*/
tmp= (ulong) (my_rnd(&sql_rand) * 0xffffffff);
my_rnd_init(&rand, tmp + (ulong) &rand, tmp + (ulong) ::global_query_id);
substitute_null_with_insert_id = FALSE;
thr_lock_info_init(&lock_info); /* safety: will be reset after start */
......@@ -4342,17 +4326,8 @@ void THD::set_query_and_id(char *query_arg, uint32 query_length_arg,
{
mysql_mutex_lock(&LOCK_thd_data);
set_query_inner(query_arg, query_length_arg, cs);
query_id= new_query_id;
mysql_mutex_unlock(&LOCK_thd_data);
}
/** Assign a new value to thd->query_id. */
void THD::set_query_id(query_id_t new_query_id)
{
mysql_mutex_lock(&LOCK_thd_data);
query_id= new_query_id;
mysql_mutex_unlock(&LOCK_thd_data);
}
/** Assign a new value to thd->mysys_var. */
......
......@@ -3076,7 +3076,10 @@ public:
{ set_query(CSET_STRING()); }
void set_query_and_id(char *query_arg, uint32 query_length_arg,
CHARSET_INFO *cs, query_id_t new_query_id);
void set_query_id(query_id_t new_query_id);
void set_query_id(query_id_t new_query_id)
{
query_id= new_query_id;
}
void set_open_tables(TABLE *open_tables_arg)
{
mysql_mutex_lock(&LOCK_thd_data);
......
......@@ -2038,9 +2038,9 @@ public:
thd.unlink(); // Must be unlinked under lock
my_free(thd.query());
thd.security_ctx->user= thd.security_ctx->host=0;
thread_count--;
delayed_insert_threads--;
mysql_mutex_unlock(&LOCK_thread_count);
thread_safe_decrement32(&thread_count, &thread_count_lock);
mysql_cond_broadcast(&COND_thread_count); /* Tell main we are ready */
}
......@@ -2175,9 +2175,9 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
{
if (!(di= new Delayed_insert()))
goto end_create;
mysql_mutex_lock(&LOCK_thread_count);
thread_count++;
mysql_mutex_unlock(&LOCK_thread_count);
thread_safe_increment32(&thread_count, &thread_count_lock);
/*
Annotating delayed inserts is not supported.
*/
......
......@@ -645,9 +645,10 @@ end:
delete thd;
#ifndef EMBEDDED_LIBRARY
mysql_mutex_lock(&LOCK_thread_count);
thread_count--;
thread_safe_decrement32(&thread_count, &thread_count_lock);
in_bootstrap= FALSE;
mysql_mutex_lock(&LOCK_thread_count);
mysql_cond_broadcast(&COND_thread_count);
mysql_mutex_unlock(&LOCK_thread_count);
my_thread_end();
......@@ -930,9 +931,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->query_plan_flags= QPLAN_INIT;
thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
thd->set_time();
thd->set_query_id(get_query_id());
if (!(server_command_flags[command] & CF_SKIP_QUERY_ID))
next_query_id();
thd->set_query_id(next_query_id());
else
{
/*
ping, get statistics or similar stateless command.
No reason to increase query id here.
*/
thd->set_query_id(get_query_id());
}
inc_thread_running();
if (!(server_command_flags[command] & CF_SKIP_QUESTIONS))
......@@ -5021,6 +5029,10 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
if ((db != NULL) && (db != any_db))
{
/*
Check if this is reserved database, like information schema or
performance schema
*/
const ACL_internal_schema_access *access;
access= get_cached_schema_access(grant_internal_info, db);
if (access)
......
......@@ -213,9 +213,7 @@ Vio *vio_new(my_socket sd, enum enum_vio_type type, uint flags)
if ((vio = (Vio*) my_malloc(sizeof(*vio),MYF(MY_WME))))
{
vio_init(vio, type, sd, 0, flags);
sprintf(vio->desc,
(vio->type == VIO_TYPE_SOCKET ? "socket (%d)" : "TCP/IP (%d)"),
vio->sd);
vio->desc= (vio->type == VIO_TYPE_SOCKET ? "socket" : "TCP/IP");
#if !defined(__WIN__)
#if !defined(NO_FCNTL_NONBLOCK)
/*
......@@ -257,7 +255,7 @@ Vio *vio_new_win32pipe(HANDLE hPipe)
if ((vio = (Vio*) my_malloc(sizeof(Vio),MYF(MY_WME))))
{
vio_init(vio, VIO_TYPE_NAMEDPIPE, 0, hPipe, VIO_LOCALHOST);
strmov(vio->desc, "named pipe");
vio->desc= "named pipe";
}
DBUG_RETURN(vio);
}
......@@ -282,7 +280,7 @@ Vio *vio_new_win32shared_memory(HANDLE handle_file_map, HANDLE handle_map,
vio->event_conn_closed= event_conn_closed;
vio->shared_memory_remain= 0;
vio->shared_memory_pos= handle_map;
strmov(vio->desc, "shared memory");
vio->desc= "shared memory";
}
DBUG_RETURN(vio);
}
......
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