Commit 1354f104 authored by serg@serg.mylan's avatar serg@serg.mylan

Merge bk-internal:/home/bk/mysql-5.0

into serg.mylan:/usr/home/serg/Abk/mysql-5.0
parents 2f47e3e1 19279b1b
...@@ -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,9 +4390,7 @@ mysql_execute_command(THD *thd) ...@@ -4388,9 +4390,7 @@ 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)
...@@ -4398,9 +4398,7 @@ mysql_execute_command(THD *thd) ...@@ -4398,9 +4398,7 @@ mysql_execute_command(THD *thd)
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
{ {
...@@ -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);
...@@ -114,7 +113,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, ...@@ -114,7 +113,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
tables List of tables to delete tables List of tables to delete
if_exists If 1, don't give error if one table doesn't exists if_exists If 1, don't give error if one table doesn't exists
dont_log_query Don't write query to log files. This will also not dont_log_query Don't write query to log files. This will also not
generate warnings if the handler files doesn't exists generate warnings if the handler files doesn't exists
NOTES NOTES
Works like documented in mysql_rm_table(), but don't check Works like documented in mysql_rm_table(), but don't check
......
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