Loading innobase/include/trx0trx.h +3 −2 Original line number Diff line number Diff line Loading @@ -390,8 +390,9 @@ struct trx_struct{ dulint table_id; /* table id if the preceding field is TRUE */ /*------------------------------*/ int active_trans; /* whether a transaction in MySQL is active */ int active_trans; /* 1 - if a transaction in MySQL is active. 2 - if prepare_commit_mutex was taken */ void* mysql_thd; /* MySQL thread handle corresponding to this trx, or NULL */ char** mysql_query_str;/* pointer to the field in mysqld_thd Loading mysql-test/r/flush.result +1 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ n 3 flush tables with read lock; 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; unlock tables; create database mysqltest; Loading mysql-test/t/flush.test +1 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ connection con1; select * from t1; connection con2; flush tables with read lock; --error 1099; --error 1223 drop table t2; connection con1; send drop table t2; Loading sql/ha_innodb.cc +29 −11 Original line number Diff line number Diff line Loading @@ -45,7 +45,8 @@ have disables the InnoDB inlining in this file. */ #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; /* Store MySQL definition of 'byte': in Linux it is char while InnoDB Loading Loading @@ -1268,7 +1269,8 @@ innobase_init(void) (void) hash_init(&innobase_open_tables,system_charset_info, 32, 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; /* If this is a replication slave and we needed to do a crash recovery, Loading Loading @@ -1322,7 +1324,8 @@ innobase_end(void) hash_free(&innobase_open_tables); my_free(internal_innobase_data_file_path, 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); Loading Loading @@ -1480,9 +1483,20 @@ innobase_commit( /* We were instructed to commit the whole transaction, or 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); if (trx->active_trans == 2) { pthread_mutex_unlock(&prepare_commit_mutex); } trx->active_trans = 0; } else { /* We just mark the SQL statement ended and do not do a transaction commit */ Loading Loading @@ -5953,7 +5967,7 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length, static INNOBASE_SHARE *get_share(const char *table_name) { INNOBASE_SHARE *share; pthread_mutex_lock(&innobase_mutex); pthread_mutex_lock(&innobase_share_mutex); uint length=(uint) strlen(table_name); if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables, (mysql_byte*) table_name, Loading @@ -5967,7 +5981,7 @@ static INNOBASE_SHARE *get_share(const char *table_name) strmov(share->table_name,table_name); 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); return 0; } Loading @@ -5976,13 +5990,13 @@ static INNOBASE_SHARE *get_share(const char *table_name) } } share->use_count++; pthread_mutex_unlock(&innobase_mutex); pthread_mutex_unlock(&innobase_share_mutex); return share; } static void free_share(INNOBASE_SHARE *share) { pthread_mutex_lock(&innobase_mutex); pthread_mutex_lock(&innobase_share_mutex); if (!--share->use_count) { hash_delete(&innobase_open_tables, (mysql_byte*) share); Loading @@ -5990,7 +6004,7 @@ static void free_share(INNOBASE_SHARE *share) pthread_mutex_destroy(&share->mutex); my_free((gptr) share, MYF(0)); } pthread_mutex_unlock(&innobase_mutex); pthread_mutex_unlock(&innobase_share_mutex); } /********************************************************************* Loading Loading @@ -6454,15 +6468,19 @@ innobase_xa_prepare( FALSE - the current SQL statement ended */ { 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) { return(0); } trx = check_trx_exists(thd); trx->xid=thd->transaction.xid; /* Release a possible FIFO ticket and search latch. Since we will Loading sql/handler.cc +20 −9 Original line number Diff line number Diff line Loading @@ -526,7 +526,6 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg) /* RETURN -1 - cannot prepare 0 - ok 1 - error, transaction was rolled back */ Loading @@ -539,8 +538,6 @@ int ha_prepare(THD *thd) #ifdef USING_TRANSACTIONS if (trans->nht) { if (trans->no_2pc) DBUG_RETURN(-1); for (; *ht; ht++) { int err; Loading Loading @@ -762,6 +759,14 @@ static char* xid_to_str(char *buf, XID *xid) for (i=0; i < xid->gtrid_length+xid->bqual_length; 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) { *s++='\''; Loading @@ -774,9 +779,11 @@ static char* xid_to_str(char *buf, XID *xid) if (c < 32 || c > 126) { *s++='\\'; *s++='x'; *s++=_dig_vec_lower[c >> 4]; *s++=_dig_vec_lower[c & 15]; if (c > 077 || is_next_dig) *s++=_dig_vec_lower[c >> 6]; if (c > 007 || is_next_dig) *s++=_dig_vec_lower[(c >> 3) & 7]; *s++=_dig_vec_lower[c & 7]; } else { Loading Loading @@ -862,6 +869,10 @@ int ha_recover(HASH *commit_list) my_xid x=list[i].get_my_xid(); 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++; continue; } Loading Loading @@ -962,9 +973,9 @@ bool mysql_xa_recover(THD *thd) if (xid->get_my_xid()) continue; // skip "our" xids protocol->prepare_for_resend(); protocol->store_long((longlong)xid->formatID); protocol->store_long((longlong)xid->gtrid_length); protocol->store_long((longlong)xid->bqual_length); protocol->store_longlong((longlong)xid->formatID, FALSE); protocol->store_longlong((longlong)xid->gtrid_length, FALSE); protocol->store_longlong((longlong)xid->bqual_length, FALSE); protocol->store(xid->data, xid->gtrid_length+xid->bqual_length, &my_charset_bin); if (protocol->write()) Loading Loading
innobase/include/trx0trx.h +3 −2 Original line number Diff line number Diff line Loading @@ -390,8 +390,9 @@ struct trx_struct{ dulint table_id; /* table id if the preceding field is TRUE */ /*------------------------------*/ int active_trans; /* whether a transaction in MySQL is active */ int active_trans; /* 1 - if a transaction in MySQL is active. 2 - if prepare_commit_mutex was taken */ void* mysql_thd; /* MySQL thread handle corresponding to this trx, or NULL */ char** mysql_query_str;/* pointer to the field in mysqld_thd Loading
mysql-test/r/flush.result +1 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ n 3 flush tables with read lock; 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; unlock tables; create database mysqltest; Loading
mysql-test/t/flush.test +1 −1 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ connection con1; select * from t1; connection con2; flush tables with read lock; --error 1099; --error 1223 drop table t2; connection con1; send drop table t2; Loading
sql/ha_innodb.cc +29 −11 Original line number Diff line number Diff line Loading @@ -45,7 +45,8 @@ have disables the InnoDB inlining in this file. */ #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; /* Store MySQL definition of 'byte': in Linux it is char while InnoDB Loading Loading @@ -1268,7 +1269,8 @@ innobase_init(void) (void) hash_init(&innobase_open_tables,system_charset_info, 32, 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; /* If this is a replication slave and we needed to do a crash recovery, Loading Loading @@ -1322,7 +1324,8 @@ innobase_end(void) hash_free(&innobase_open_tables); my_free(internal_innobase_data_file_path, 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); Loading Loading @@ -1480,9 +1483,20 @@ innobase_commit( /* We were instructed to commit the whole transaction, or 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); if (trx->active_trans == 2) { pthread_mutex_unlock(&prepare_commit_mutex); } trx->active_trans = 0; } else { /* We just mark the SQL statement ended and do not do a transaction commit */ Loading Loading @@ -5953,7 +5967,7 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length, static INNOBASE_SHARE *get_share(const char *table_name) { INNOBASE_SHARE *share; pthread_mutex_lock(&innobase_mutex); pthread_mutex_lock(&innobase_share_mutex); uint length=(uint) strlen(table_name); if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables, (mysql_byte*) table_name, Loading @@ -5967,7 +5981,7 @@ static INNOBASE_SHARE *get_share(const char *table_name) strmov(share->table_name,table_name); 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); return 0; } Loading @@ -5976,13 +5990,13 @@ static INNOBASE_SHARE *get_share(const char *table_name) } } share->use_count++; pthread_mutex_unlock(&innobase_mutex); pthread_mutex_unlock(&innobase_share_mutex); return share; } static void free_share(INNOBASE_SHARE *share) { pthread_mutex_lock(&innobase_mutex); pthread_mutex_lock(&innobase_share_mutex); if (!--share->use_count) { hash_delete(&innobase_open_tables, (mysql_byte*) share); Loading @@ -5990,7 +6004,7 @@ static void free_share(INNOBASE_SHARE *share) pthread_mutex_destroy(&share->mutex); my_free((gptr) share, MYF(0)); } pthread_mutex_unlock(&innobase_mutex); pthread_mutex_unlock(&innobase_share_mutex); } /********************************************************************* Loading Loading @@ -6454,15 +6468,19 @@ innobase_xa_prepare( FALSE - the current SQL statement ended */ { 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) { return(0); } trx = check_trx_exists(thd); trx->xid=thd->transaction.xid; /* Release a possible FIFO ticket and search latch. Since we will Loading
sql/handler.cc +20 −9 Original line number Diff line number Diff line Loading @@ -526,7 +526,6 @@ void trans_register_ha(THD *thd, bool all, handlerton *ht_arg) /* RETURN -1 - cannot prepare 0 - ok 1 - error, transaction was rolled back */ Loading @@ -539,8 +538,6 @@ int ha_prepare(THD *thd) #ifdef USING_TRANSACTIONS if (trans->nht) { if (trans->no_2pc) DBUG_RETURN(-1); for (; *ht; ht++) { int err; Loading Loading @@ -762,6 +759,14 @@ static char* xid_to_str(char *buf, XID *xid) for (i=0; i < xid->gtrid_length+xid->bqual_length; 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) { *s++='\''; Loading @@ -774,9 +779,11 @@ static char* xid_to_str(char *buf, XID *xid) if (c < 32 || c > 126) { *s++='\\'; *s++='x'; *s++=_dig_vec_lower[c >> 4]; *s++=_dig_vec_lower[c & 15]; if (c > 077 || is_next_dig) *s++=_dig_vec_lower[c >> 6]; if (c > 007 || is_next_dig) *s++=_dig_vec_lower[(c >> 3) & 7]; *s++=_dig_vec_lower[c & 7]; } else { Loading Loading @@ -862,6 +869,10 @@ int ha_recover(HASH *commit_list) my_xid x=list[i].get_my_xid(); 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++; continue; } Loading Loading @@ -962,9 +973,9 @@ bool mysql_xa_recover(THD *thd) if (xid->get_my_xid()) continue; // skip "our" xids protocol->prepare_for_resend(); protocol->store_long((longlong)xid->formatID); protocol->store_long((longlong)xid->gtrid_length); protocol->store_long((longlong)xid->bqual_length); protocol->store_longlong((longlong)xid->formatID, FALSE); protocol->store_longlong((longlong)xid->gtrid_length, FALSE); protocol->store_longlong((longlong)xid->bqual_length, FALSE); protocol->store(xid->data, xid->gtrid_length+xid->bqual_length, &my_charset_bin); if (protocol->write()) Loading