ha_innodb.h, ha_innodb.cc, handler.h, handler.cc, sql_class.cc:
Fix a hang on the adaptive hash S-latch if an application program uses mysql_use_result() and performs queries on two connections at the same time sql/sql_class.cc: Fix a hang on the adaptive hash S-latch if an application program uses mysql_use_result() and performs queries on two connections at the same time sql/handler.cc: Fix a hang on the adaptive hash S-latch if an application program uses mysql_use_result() and performs queries on two connections at the same time sql/handler.h: Fix a hang on the adaptive hash S-latch if an application program uses mysql_use_result() and performs queries on two connections at the same time sql/ha_innodb.cc: Fix a hang on the adaptive hash S-latch if an application program uses mysql_use_result() and performs queries on two connections at the same time sql/ha_innodb.h: Fix a hang on the adaptive hash S-latch if an application program uses mysql_use_result() and performs queries on two connections at the same time
This commit is contained in:
parent
9ca8f13734
commit
e70b22e55c
@ -150,6 +150,19 @@ innobase_release_stat_resources(
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Call this function when mysqld passes control to the client. That is to
|
||||
avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
|
||||
documentation, see handler.cc. */
|
||||
|
||||
void
|
||||
innobase_release_temporary_latches(
|
||||
/*===============================*/
|
||||
void* innobase_tid)
|
||||
{
|
||||
innobase_release_stat_resources((trx_t*)innobase_tid);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
|
||||
time calls srv_active_wake_master_thread. This function should be used
|
||||
|
@ -208,3 +208,4 @@ int innodb_show_status(THD* thd);
|
||||
|
||||
my_bool innobase_query_caching_of_table_permitted(THD* thd, char* full_name,
|
||||
uint full_name_len);
|
||||
void innobase_release_temporary_latches(void* innobase_tid);
|
||||
|
@ -238,8 +238,10 @@ int ha_autocommit_or_rollback(THD *thd, int error)
|
||||
handler must be the same as in the binlog.
|
||||
|
||||
arguments:
|
||||
thd: the thread handle of the current connection
|
||||
log_file_name: latest binlog file name
|
||||
end_offset: the offset in the binlog file up to which we wrote
|
||||
return value: 0 if success, 1 if error
|
||||
*/
|
||||
|
||||
int ha_report_binlog_offset_and_commit(THD *thd,
|
||||
@ -266,6 +268,34 @@ int ha_report_binlog_offset_and_commit(THD *thd,
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
This function should be called when MySQL sends rows of a SELECT result set
|
||||
or the EOF mark to the client. It releases a possible adaptive hash index
|
||||
S-latch held by thd in InnoDB and also releases a possible InnoDB query
|
||||
FIFO ticket to enter InnoDB. To save CPU time, InnoDB allows a thd to
|
||||
keep them over several calls of the InnoDB handler interface when a join
|
||||
is executed. But when we let the control to pass to the client they have
|
||||
to be released because if the application program uses mysql_use_result(),
|
||||
it may deadlock on the S-latch if the application on another connection
|
||||
performs another SQL query. In MySQL-4.1 this is even more important because
|
||||
there a connection can have several SELECT queries open at the same time.
|
||||
|
||||
arguments:
|
||||
thd: the thread handle of the current connection
|
||||
return value: always 0
|
||||
*/
|
||||
|
||||
int ha_release_temporary_latches(THD *thd)
|
||||
{
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
THD_TRANS *trans;
|
||||
trans = &thd->transaction.all;
|
||||
if (trans->innobase_tid)
|
||||
innobase_release_temporary_latches(trans->innobase_tid);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ha_commit_trans(THD *thd, THD_TRANS* trans)
|
||||
{
|
||||
int error=0;
|
||||
|
@ -371,6 +371,7 @@ void ha_resize_key_cache(void);
|
||||
int ha_start_stmt(THD *thd);
|
||||
int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
|
||||
my_off_t end_offset);
|
||||
int ha_release_temporary_latches(THD *thd);
|
||||
int ha_commit_trans(THD *thd, THD_TRANS *trans);
|
||||
int ha_rollback_trans(THD *thd, THD_TRANS *trans);
|
||||
int ha_autocommit_or_rollback(THD *thd, int error);
|
||||
|
@ -463,6 +463,14 @@ bool select_send::send_data(List<Item> &items)
|
||||
String *packet= &thd->packet;
|
||||
DBUG_ENTER("send_data");
|
||||
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
/* We may be passing the control from mysqld to the client: release the
|
||||
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
|
||||
by thd */
|
||||
if (thd->transaction.all.innobase_tid)
|
||||
ha_release_temporary_latches(thd);
|
||||
#endif
|
||||
|
||||
if (thd->offset_limit)
|
||||
{ // using limit offset,count
|
||||
thd->offset_limit--;
|
||||
@ -486,6 +494,14 @@ bool select_send::send_data(List<Item> &items)
|
||||
|
||||
bool select_send::send_eof()
|
||||
{
|
||||
#ifdef HAVE_INNOBASE_DB
|
||||
/* We may be passing the control from mysqld to the client: release the
|
||||
InnoDB adaptive hash S-latch to avoid thread deadlocks if it was reserved
|
||||
by thd */
|
||||
if (thd->transaction.all.innobase_tid)
|
||||
ha_release_temporary_latches(thd);
|
||||
#endif
|
||||
|
||||
/* Unlock tables before sending packet to gain some speed */
|
||||
if (thd->lock)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user