Commit 1f919052 authored by unknown's avatar unknown

merged


sql/ha_innodb.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
parents 01774e96 608b63c7
...@@ -390,8 +390,9 @@ struct trx_struct{ ...@@ -390,8 +390,9 @@ struct trx_struct{
dulint table_id; /* table id if the preceding field is dulint table_id; /* table id if the preceding field is
TRUE */ TRUE */
/*------------------------------*/ /*------------------------------*/
int active_trans; /* whether a transaction in MySQL int active_trans; /* 1 - if a transaction in MySQL
is active */ is active. 2 - if prepare_commit_mutex
was taken */
void* mysql_thd; /* MySQL thread handle corresponding void* mysql_thd; /* MySQL thread handle corresponding
to this trx, or NULL */ to this trx, or NULL */
char** mysql_query_str;/* pointer to the field in mysqld_thd char** mysql_query_str;/* pointer to the field in mysqld_thd
......
...@@ -8,7 +8,7 @@ n ...@@ -8,7 +8,7 @@ n
3 3
flush tables with read lock; flush tables with read lock;
drop table t2; drop table t2;
ERROR HY000: Table 't2' was locked with a READ lock and can't be updated ERROR HY000: Can't execute the query because you have a conflicting read lock
drop table t2; drop table t2;
unlock tables; unlock tables;
create database mysqltest; create database mysqltest;
......
...@@ -37,7 +37,7 @@ connection con1; ...@@ -37,7 +37,7 @@ connection con1;
select * from t1; select * from t1;
connection con2; connection con2;
flush tables with read lock; flush tables with read lock;
--error 1099; --error 1223
drop table t2; drop table t2;
connection con1; connection con1;
send drop table t2; send drop table t2;
......
...@@ -45,7 +45,8 @@ have disables the InnoDB inlining in this file. */ ...@@ -45,7 +45,8 @@ have disables the InnoDB inlining in this file. */
#include "ha_innodb.h" #include "ha_innodb.h"
pthread_mutex_t innobase_mutex; pthread_mutex_t innobase_share_mutex, // to protect innobase_open_files
prepare_commit_mutex; // to force correct commit order in binlog
bool innodb_inited= 0; bool innodb_inited= 0;
/* Store MySQL definition of 'byte': in Linux it is char while InnoDB /* Store MySQL definition of 'byte': in Linux it is char while InnoDB
...@@ -1268,7 +1269,8 @@ innobase_init(void) ...@@ -1268,7 +1269,8 @@ innobase_init(void)
(void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0, (void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
(hash_get_key) innobase_get_key, 0, 0); (hash_get_key) innobase_get_key, 0, 0);
pthread_mutex_init(&innobase_mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
innodb_inited= 1; innodb_inited= 1;
/* If this is a replication slave and we needed to do a crash recovery, /* If this is a replication slave and we needed to do a crash recovery,
...@@ -1322,7 +1324,8 @@ innobase_end(void) ...@@ -1322,7 +1324,8 @@ innobase_end(void)
hash_free(&innobase_open_tables); hash_free(&innobase_open_tables);
my_free(internal_innobase_data_file_path, my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR)); MYF(MY_ALLOW_ZERO_PTR));
pthread_mutex_destroy(&innobase_mutex); pthread_mutex_destroy(&innobase_share_mutex);
pthread_mutex_destroy(&prepare_commit_mutex);
} }
DBUG_RETURN(err); DBUG_RETURN(err);
...@@ -1480,9 +1483,20 @@ innobase_commit( ...@@ -1480,9 +1483,20 @@ innobase_commit(
/* We were instructed to commit the whole transaction, or /* We were instructed to commit the whole transaction, or
this is an SQL statement end and autocommit is on */ this is an SQL statement end and autocommit is on */
/* We need current binlog position for HotBackup to work.
Note, the position is current because of prepare_commit_mutex */
trx->mysql_log_file_name = mysql_bin_log.get_log_fname();
trx->mysql_log_offset =
(ib_longlong)mysql_bin_log.get_log_file()->pos_in_file;
innobase_commit_low(trx); innobase_commit_low(trx);
if (trx->active_trans == 2) {
pthread_mutex_unlock(&prepare_commit_mutex);
}
trx->active_trans = 0; trx->active_trans = 0;
} else { } else {
/* We just mark the SQL statement ended and do not do a /* We just mark the SQL statement ended and do not do a
transaction commit */ transaction commit */
...@@ -5953,7 +5967,7 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length, ...@@ -5953,7 +5967,7 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
static INNOBASE_SHARE *get_share(const char *table_name) static INNOBASE_SHARE *get_share(const char *table_name)
{ {
INNOBASE_SHARE *share; INNOBASE_SHARE *share;
pthread_mutex_lock(&innobase_mutex); pthread_mutex_lock(&innobase_share_mutex);
uint length=(uint) strlen(table_name); uint length=(uint) strlen(table_name);
if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables, if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
(mysql_byte*) table_name, (mysql_byte*) table_name,
...@@ -5967,7 +5981,7 @@ static INNOBASE_SHARE *get_share(const char *table_name) ...@@ -5967,7 +5981,7 @@ static INNOBASE_SHARE *get_share(const char *table_name)
strmov(share->table_name,table_name); strmov(share->table_name,table_name);
if (my_hash_insert(&innobase_open_tables, (mysql_byte*) share)) if (my_hash_insert(&innobase_open_tables, (mysql_byte*) share))
{ {
pthread_mutex_unlock(&innobase_mutex); pthread_mutex_unlock(&innobase_share_mutex);
my_free((gptr) share,0); my_free((gptr) share,0);
return 0; return 0;
} }
...@@ -5976,13 +5990,13 @@ static INNOBASE_SHARE *get_share(const char *table_name) ...@@ -5976,13 +5990,13 @@ static INNOBASE_SHARE *get_share(const char *table_name)
} }
} }
share->use_count++; share->use_count++;
pthread_mutex_unlock(&innobase_mutex); pthread_mutex_unlock(&innobase_share_mutex);
return share; return share;
} }
static void free_share(INNOBASE_SHARE *share) static void free_share(INNOBASE_SHARE *share)
{ {
pthread_mutex_lock(&innobase_mutex); pthread_mutex_lock(&innobase_share_mutex);
if (!--share->use_count) if (!--share->use_count)
{ {
hash_delete(&innobase_open_tables, (mysql_byte*) share); hash_delete(&innobase_open_tables, (mysql_byte*) share);
...@@ -5990,7 +6004,7 @@ static void free_share(INNOBASE_SHARE *share) ...@@ -5990,7 +6004,7 @@ static void free_share(INNOBASE_SHARE *share)
pthread_mutex_destroy(&share->mutex); pthread_mutex_destroy(&share->mutex);
my_free((gptr) share, MYF(0)); my_free((gptr) share, MYF(0));
} }
pthread_mutex_unlock(&innobase_mutex); pthread_mutex_unlock(&innobase_share_mutex);
} }
/********************************************************************* /*********************************************************************
...@@ -6454,15 +6468,19 @@ innobase_xa_prepare( ...@@ -6454,15 +6468,19 @@ innobase_xa_prepare(
FALSE - the current SQL statement ended */ FALSE - the current SQL statement ended */
{ {
int error = 0; int error = 0;
trx_t* trx; trx_t* trx = check_trx_exists(thd);
if (thd->lex->sql_command != SQLCOM_XA_PREPARE) {
pthread_mutex_lock(&prepare_commit_mutex);
trx->active_trans = 2;
}
if (!thd->variables.innodb_support_xa) { if (!thd->variables.innodb_support_xa) {
return(0); return(0);
} }
trx = check_trx_exists(thd);
trx->xid=thd->transaction.xid; trx->xid=thd->transaction.xid;
/* Release a possible FIFO ticket and search latch. Since we will /* Release a possible FIFO ticket and search latch. Since we will
......
...@@ -526,7 +526,6 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg) ...@@ -526,7 +526,6 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg)
/* /*
RETURN RETURN
-1 - cannot prepare
0 - ok 0 - ok
1 - error, transaction was rolled back 1 - error, transaction was rolled back
*/ */
...@@ -539,8 +538,6 @@ int ha_prepare(THD *thd) ...@@ -539,8 +538,6 @@ int ha_prepare(THD *thd)
#ifdef USING_TRANSACTIONS #ifdef USING_TRANSACTIONS
if (trans->nht) if (trans->nht)
{ {
if (trans->no_2pc)
DBUG_RETURN(-1);
for (; *ht; ht++) for (; *ht; ht++)
{ {
int err; int err;
...@@ -762,6 +759,14 @@ static char* xid_to_str(char *buf, XID *xid) ...@@ -762,6 +759,14 @@ static char* xid_to_str(char *buf, XID *xid)
for (i=0; i < xid->gtrid_length+xid->bqual_length; i++) for (i=0; i < xid->gtrid_length+xid->bqual_length; i++)
{ {
uchar c=(uchar)xid->data[i]; uchar c=(uchar)xid->data[i];
bool is_next_dig;
if (i < XIDDATASIZE)
{
char ch=xid->data[i+1];
is_next_dig=(c >= '0' && c <='9');
}
else
is_next_dig=FALSE;
if (i == xid->gtrid_length) if (i == xid->gtrid_length)
{ {
*s++='\''; *s++='\'';
...@@ -774,9 +779,11 @@ static char* xid_to_str(char *buf, XID *xid) ...@@ -774,9 +779,11 @@ static char* xid_to_str(char *buf, XID *xid)
if (c < 32 || c > 126) if (c < 32 || c > 126)
{ {
*s++='\\'; *s++='\\';
*s++='x'; if (c > 077 || is_next_dig)
*s++=_dig_vec_lower[c >> 4]; *s++=_dig_vec_lower[c >> 6];
*s++=_dig_vec_lower[c & 15]; if (c > 007 || is_next_dig)
*s++=_dig_vec_lower[(c >> 3) & 7];
*s++=_dig_vec_lower[c & 7];
} }
else else
{ {
...@@ -862,6 +869,10 @@ int ha_recover(HASH *commit_list) ...@@ -862,6 +869,10 @@ int ha_recover(HASH *commit_list)
my_xid x=list[i].get_my_xid(); my_xid x=list[i].get_my_xid();
if (!x) // not "mine" - that is generated by external TM if (!x) // not "mine" - that is generated by external TM
{ {
#ifndef DBUG_OFF
char buf[XIDDATASIZE*4+6]; // see xid_to_str
sql_print_information("ignore xid %s", xid_to_str(buf, list+i));
#endif
found_foreign_xids++; found_foreign_xids++;
continue; continue;
} }
...@@ -962,9 +973,9 @@ bool mysql_xa_recover(THD *thd) ...@@ -962,9 +973,9 @@ bool mysql_xa_recover(THD *thd)
if (xid->get_my_xid()) if (xid->get_my_xid())
continue; // skip "our" xids continue; // skip "our" xids
protocol->prepare_for_resend(); protocol->prepare_for_resend();
protocol->store_long((longlong)xid->formatID); protocol->store_longlong((longlong)xid->formatID, FALSE);
protocol->store_long((longlong)xid->gtrid_length); protocol->store_longlong((longlong)xid->gtrid_length, FALSE);
protocol->store_long((longlong)xid->bqual_length); protocol->store_longlong((longlong)xid->bqual_length, FALSE);
protocol->store(xid->data, xid->gtrid_length+xid->bqual_length, protocol->store(xid->data, xid->gtrid_length+xid->bqual_length,
&my_charset_bin); &my_charset_bin);
if (protocol->write()) if (protocol->write())
......
...@@ -800,8 +800,8 @@ bool lock_global_read_lock(THD *thd) ...@@ -800,8 +800,8 @@ bool lock_global_read_lock(THD *thd)
if (!thd->global_read_lock) if (!thd->global_read_lock)
{ {
(void) pthread_mutex_lock(&LOCK_open); (void) pthread_mutex_lock(&LOCK_global_read_lock);
const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open, const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
"Waiting to get readlock"); "Waiting to get readlock");
DBUG_PRINT("info", DBUG_PRINT("info",
("waiting_for: %d protect_against: %d", ("waiting_for: %d protect_against: %d",
...@@ -809,7 +809,7 @@ bool lock_global_read_lock(THD *thd) ...@@ -809,7 +809,7 @@ bool lock_global_read_lock(THD *thd)
waiting_for_read_lock++; waiting_for_read_lock++;
while (protect_against_global_read_lock && !thd->killed) while (protect_against_global_read_lock && !thd->killed)
pthread_cond_wait(&COND_refresh, &LOCK_open); pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
waiting_for_read_lock--; waiting_for_read_lock--;
if (thd->killed) if (thd->killed)
{ {
...@@ -834,11 +834,11 @@ bool lock_global_read_lock(THD *thd) ...@@ -834,11 +834,11 @@ bool lock_global_read_lock(THD *thd)
void unlock_global_read_lock(THD *thd) void unlock_global_read_lock(THD *thd)
{ {
uint tmp; uint tmp;
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_global_read_lock);
tmp= --global_read_lock; tmp= --global_read_lock;
if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT) if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT)
--global_read_lock_blocks_commit; --global_read_lock_blocks_commit;
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_global_read_lock);
/* Send the signal outside the mutex to avoid a context switch */ /* Send the signal outside the mutex to avoid a context switch */
if (!tmp) if (!tmp)
pthread_cond_broadcast(&COND_refresh); pthread_cond_broadcast(&COND_refresh);
...@@ -857,7 +857,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, ...@@ -857,7 +857,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
DBUG_ENTER("wait_if_global_read_lock"); DBUG_ENTER("wait_if_global_read_lock");
LINT_INIT(old_message); LINT_INIT(old_message);
(void) pthread_mutex_lock(&LOCK_open); (void) pthread_mutex_lock(&LOCK_global_read_lock);
if ((need_exit_cond= must_wait)) if ((need_exit_cond= must_wait))
{ {
if (thd->global_read_lock) // This thread had the read locks if (thd->global_read_lock) // This thread had the read locks
...@@ -865,7 +865,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, ...@@ -865,7 +865,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
if (is_not_commit) if (is_not_commit)
my_message(ER_CANT_UPDATE_WITH_READLOCK, my_message(ER_CANT_UPDATE_WITH_READLOCK,
ER(ER_CANT_UPDATE_WITH_READLOCK), MYF(0)); ER(ER_CANT_UPDATE_WITH_READLOCK), MYF(0));
(void) pthread_mutex_unlock(&LOCK_open); (void) pthread_mutex_unlock(&LOCK_global_read_lock);
/* /*
We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does. We allow FLUSHer to COMMIT; we assume FLUSHer knows what it does.
This allowance is needed to not break existing versions of innobackup This allowance is needed to not break existing versions of innobackup
...@@ -873,11 +873,11 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, ...@@ -873,11 +873,11 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
*/ */
DBUG_RETURN(is_not_commit); DBUG_RETURN(is_not_commit);
} }
old_message=thd->enter_cond(&COND_refresh, &LOCK_open, old_message=thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
"Waiting for release of readlock"); "Waiting for release of readlock");
while (must_wait && ! thd->killed && while (must_wait && ! thd->killed &&
(!abort_on_refresh || thd->version == refresh_version)) (!abort_on_refresh || thd->version == refresh_version))
(void) pthread_cond_wait(&COND_refresh,&LOCK_open); (void) pthread_cond_wait(&COND_refresh,&LOCK_global_read_lock);
if (thd->killed) if (thd->killed)
result=1; result=1;
} }
...@@ -890,7 +890,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, ...@@ -890,7 +890,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
if (unlikely(need_exit_cond)) if (unlikely(need_exit_cond))
thd->exit_cond(old_message); thd->exit_cond(old_message);
else else
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_global_read_lock);
DBUG_RETURN(result); DBUG_RETURN(result);
} }
...@@ -901,10 +901,10 @@ void start_waiting_global_read_lock(THD *thd) ...@@ -901,10 +901,10 @@ void start_waiting_global_read_lock(THD *thd)
DBUG_ENTER("start_waiting_global_read_lock"); DBUG_ENTER("start_waiting_global_read_lock");
if (unlikely(thd->global_read_lock)) if (unlikely(thd->global_read_lock))
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
(void) pthread_mutex_lock(&LOCK_open); (void) pthread_mutex_lock(&LOCK_global_read_lock);
tmp= (!--protect_against_global_read_lock && tmp= (!--protect_against_global_read_lock &&
(waiting_for_read_lock || global_read_lock_blocks_commit)); (waiting_for_read_lock || global_read_lock_blocks_commit));
(void) pthread_mutex_unlock(&LOCK_open); (void) pthread_mutex_unlock(&LOCK_global_read_lock);
if (tmp) if (tmp)
pthread_cond_broadcast(&COND_refresh); pthread_cond_broadcast(&COND_refresh);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -922,16 +922,16 @@ bool make_global_read_lock_block_commit(THD *thd) ...@@ -922,16 +922,16 @@ bool make_global_read_lock_block_commit(THD *thd)
*/ */
if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK) if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK)
DBUG_RETURN(1); DBUG_RETURN(1);
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_global_read_lock);
/* increment this BEFORE waiting on cond (otherwise race cond) */ /* increment this BEFORE waiting on cond (otherwise race cond) */
global_read_lock_blocks_commit++; global_read_lock_blocks_commit++;
/* For testing we set up some blocking, to see if we can be killed */ /* For testing we set up some blocking, to see if we can be killed */
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop", DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
protect_against_global_read_lock++;); protect_against_global_read_lock++;);
old_message= thd->enter_cond(&COND_refresh, &LOCK_open, old_message= thd->enter_cond(&COND_refresh, &LOCK_global_read_lock,
"Waiting for all running commits to finish"); "Waiting for all running commits to finish");
while (protect_against_global_read_lock && !thd->killed) while (protect_against_global_read_lock && !thd->killed)
pthread_cond_wait(&COND_refresh, &LOCK_open); pthread_cond_wait(&COND_refresh, &LOCK_global_read_lock);
DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop", DBUG_EXECUTE_IF("make_global_read_lock_block_commit_loop",
protect_against_global_read_lock--;); protect_against_global_read_lock--;);
if (error= thd->killed) if (error= thd->killed)
......
...@@ -1101,7 +1101,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, ...@@ -1101,7 +1101,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status, LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator, LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock,
LOCK_global_system_variables, LOCK_user_conn; LOCK_global_system_variables, LOCK_user_conn;
extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
......
...@@ -426,7 +426,7 @@ SHOW_COMP_OPTION have_crypt, have_compress; ...@@ -426,7 +426,7 @@ SHOW_COMP_OPTION have_crypt, have_compress;
pthread_key(MEM_ROOT**,THR_MALLOC); pthread_key(MEM_ROOT**,THR_MALLOC);
pthread_key(THD*, THR_THD); pthread_key(THD*, THR_THD);
pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count, pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
LOCK_mapped_file, LOCK_status, LOCK_mapped_file, LOCK_status, LOCK_global_read_lock,
LOCK_error_log, LOCK_uuid_generator, LOCK_error_log, LOCK_uuid_generator,
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received, LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
...@@ -1102,6 +1102,7 @@ static void clean_up_mutexes() ...@@ -1102,6 +1102,7 @@ static void clean_up_mutexes()
(void) rwlock_destroy(&LOCK_sys_init_connect); (void) rwlock_destroy(&LOCK_sys_init_connect);
(void) rwlock_destroy(&LOCK_sys_init_slave); (void) rwlock_destroy(&LOCK_sys_init_slave);
(void) pthread_mutex_destroy(&LOCK_global_system_variables); (void) pthread_mutex_destroy(&LOCK_global_system_variables);
(void) pthread_mutex_destroy(&LOCK_global_read_lock);
(void) pthread_cond_destroy(&COND_thread_count); (void) pthread_cond_destroy(&COND_thread_count);
(void) pthread_cond_destroy(&COND_refresh); (void) pthread_cond_destroy(&COND_refresh);
(void) pthread_cond_destroy(&COND_thread_cache); (void) pthread_cond_destroy(&COND_thread_cache);
...@@ -2594,6 +2595,7 @@ static int init_thread_environment() ...@@ -2594,6 +2595,7 @@ static int init_thread_environment()
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
(void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
(void) my_rwlock_init(&LOCK_sys_init_connect, NULL); (void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
(void) my_rwlock_init(&LOCK_sys_init_slave, NULL); (void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
......
...@@ -4380,6 +4380,8 @@ mysql_execute_command(THD *thd) ...@@ -4380,6 +4380,8 @@ mysql_execute_command(THD *thd)
{ {
if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 1))) if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 1)))
my_error(ER_XAER_NOTA, MYF(0)); my_error(ER_XAER_NOTA, MYF(0));
else
send_ok(thd);
break; break;
} }
if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE) if (thd->transaction.xa_state == XA_IDLE && thd->lex->xa_opt == XA_ONE_PHASE)
...@@ -4388,20 +4390,16 @@ mysql_execute_command(THD *thd) ...@@ -4388,20 +4390,16 @@ mysql_execute_command(THD *thd)
if ((r= ha_commit(thd))) if ((r= ha_commit(thd)))
my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0)); my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
else else
{
send_ok(thd); send_ok(thd);
} }
}
else else
if (thd->transaction.xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE) if (thd->transaction.xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
{ {
if (ha_commit_one_phase(thd, 1)) if (ha_commit_one_phase(thd, 1))
my_error(ER_XAER_RMERR, MYF(0)); my_error(ER_XAER_RMERR, MYF(0));
else else
{
send_ok(thd); send_ok(thd);
} }
}
else else
{ {
my_error(ER_XAER_RMFAIL, MYF(0), my_error(ER_XAER_RMFAIL, MYF(0),
...@@ -4417,6 +4415,8 @@ mysql_execute_command(THD *thd) ...@@ -4417,6 +4415,8 @@ mysql_execute_command(THD *thd)
{ {
if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 0))) if (!(res= !ha_commit_or_rollback_by_xid(&thd->lex->ident, 0)))
my_error(ER_XAER_NOTA, MYF(0)); my_error(ER_XAER_NOTA, MYF(0));
else
send_ok(thd);
break; break;
} }
if (thd->transaction.xa_state != XA_IDLE && if (thd->transaction.xa_state != XA_IDLE &&
......
...@@ -65,7 +65,7 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, ...@@ -65,7 +65,7 @@ static int copy_data_between_tables(TABLE *from,TABLE *to,
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
my_bool drop_temporary) my_bool drop_temporary)
{ {
bool error= FALSE; bool error= FALSE, need_start_waiters= FALSE;
DBUG_ENTER("mysql_rm_table"); DBUG_ENTER("mysql_rm_table");
/* mark for close and remove all cached entries */ /* mark for close and remove all cached entries */
...@@ -74,23 +74,19 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, ...@@ -74,23 +74,19 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
thd->mysys_var->current_cond= &COND_refresh; thd->mysys_var->current_cond= &COND_refresh;
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
if (!drop_temporary && global_read_lock) if (!drop_temporary)
{ {
if (thd->global_read_lock) if ((error= wait_if_global_read_lock(thd, 0, 1)))
{ {
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->table_name); my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->table_name);
error= TRUE;
goto err; goto err;
} }
while (global_read_lock && ! thd->killed) else
{ need_start_waiters= TRUE;
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
}
} }
error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0); error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
err: err:
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
pthread_mutex_lock(&thd->mysys_var->mutex); pthread_mutex_lock(&thd->mysys_var->mutex);
...@@ -98,6 +94,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, ...@@ -98,6 +94,9 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
thd->mysys_var->current_cond= 0; thd->mysys_var->current_cond= 0;
pthread_mutex_unlock(&thd->mysys_var->mutex); pthread_mutex_unlock(&thd->mysys_var->mutex);
if (need_start_waiters)
start_waiting_global_read_lock(thd);
if (error) if (error)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
send_ok(thd); send_ok(thd);
......
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