Commit 8392a814 authored by konstantin@mysql.com's avatar konstantin@mysql.com

A fix and a test case for Bug#12243 "MySQL Server crashes with 2

cursors (+ commit)" and Bug#11832 "Server crash with InnoDB + Cursors"
See comments to the changed files.
parent cacc1a9f
......@@ -136,6 +136,9 @@ struct cursor_view_struct{
/* Memory heap for the cursor view */
read_view_t* read_view;
/* Consistent read view of the cursor*/
ulint n_mysql_tables_in_use;
/* number of Innobase tables used in the
processing of this cursor */
};
#ifndef UNIV_NONINL
......
......@@ -286,6 +286,11 @@ read_cursor_view_create_for_mysql(
curview = (cursor_view_t*) mem_heap_alloc(heap, sizeof(cursor_view_t));
curview->heap = heap;
/* Drop cursor tables from consideration when evaluating the need of
auto-commit */
curview->n_mysql_tables_in_use = cr_trx->n_mysql_tables_in_use;
cr_trx->n_mysql_tables_in_use = 0;
mutex_enter(&kernel_mutex);
curview->read_view = read_view_create_low(
......@@ -360,6 +365,10 @@ read_cursor_view_close_for_mysql(
ut_a(curview->read_view);
ut_a(curview->heap);
/* Add cursor's tables to the global count of active tables that
belong to this transaction */
trx->n_mysql_tables_in_use += curview->n_mysql_tables_in_use;
mutex_enter(&kernel_mutex);
read_view_close(curview->read_view);
......
......@@ -3101,12 +3101,6 @@ row_search_for_mysql(
"InnoDB: how you can resolve the problem.\n",
prebuilt->table->name);
/* Restore a global read view back to a transaction. This
forces MySQL always to set a cursor view before fetch from
a cursor. */
trx->read_view = trx->global_read_view;
return(DB_ERROR);
}
......@@ -4098,12 +4092,6 @@ row_search_for_mysql(
}
func_exit:
/* Restore a global read view back to a transaction. This
forces MySQL always to set a cursor view before fetch from
a cursor. */
trx->read_view = trx->global_read_view;
trx->op_info = "";
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
......
......@@ -2146,6 +2146,15 @@ innobase_close_connection(
ut_a(trx);
if (trx->active_trans == 0
&& trx->conc_state != TRX_NOT_STARTED) {
fprintf(stderr,
"InnoDB: Error: trx->active_trans == 0\n"
"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n");
}
if (trx->conc_state != TRX_NOT_STARTED &&
global_system_variables.log_warnings)
sql_print_warning("MySQL is closing a connection that has an active "
......
......@@ -14179,6 +14179,66 @@ static void test_bug11901()
myquery(rc);
}
/* Bug#12243: multiple cursors, crash in a fetch after commit. */
static void test_bug12243()
{
MYSQL_STMT *stmt1, *stmt2;
int rc;
const char *stmt_text;
ulong type;
myheader("test_bug12243");
if (! have_innodb)
{
if (!opt_silent)
printf("This test requires InnoDB.\n");
return;
}
/* create tables */
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
myquery(rc);
mysql_autocommit(mysql, FALSE);
/* create statement */
stmt1= mysql_stmt_init(mysql);
stmt2= mysql_stmt_init(mysql);
type= (ulong) CURSOR_TYPE_READ_ONLY;
mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
stmt_text= "select a from t1";
rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
check_execute(stmt1, rc);
rc= mysql_stmt_execute(stmt1);
check_execute(stmt1, rc);
rc= mysql_stmt_fetch(stmt1);
check_execute(stmt1, rc);
rc= mysql_stmt_prepare(stmt2, stmt_text, strlen(stmt_text));
check_execute(stmt2, rc);
rc= mysql_stmt_execute(stmt2);
check_execute(stmt2, rc);
rc= mysql_stmt_fetch(stmt2);
check_execute(stmt2, rc);
rc= mysql_stmt_close(stmt1);
check_execute(stmt1, rc);
rc= mysql_commit(mysql);
myquery(rc);
rc= mysql_stmt_fetch(stmt2);
check_execute(stmt2, rc);
mysql_stmt_close(stmt2);
rc= mysql_query(mysql, "drop table t1");
myquery(rc);
mysql_autocommit(mysql, TRUE); /* restore default */
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
......@@ -14427,6 +14487,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug12001", test_bug12001 },
{ "test_bug11909", test_bug11909 },
{ "test_bug11901", test_bug11901 },
{ "test_bug12243", test_bug12243 },
{ 0, 0 }
};
......
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