diff --git a/mysql-test/suite/tokudb.bugs/r/db817.result b/mysql-test/suite/tokudb.bugs/r/db817.result new file mode 100644 index 00000000000..d69f0dabcb3 --- /dev/null +++ b/mysql-test/suite/tokudb.bugs/r/db817.result @@ -0,0 +1,33 @@ +drop table if exists ti; +create table ti (id int primary key) engine=innodb; +begin; +insert into ti values (0); +savepoint b; +insert into ti values (1); +savepoint a2; +insert into ti values (2); +savepoint b; +insert into ti values (3); +rollback to a2; +commit; +select * from ti; +id +0 +1 +drop table if exists tt; +create table tt (id int primary key) engine=tokudb; +begin; +insert into tt values (0); +savepoint b; +insert into tt values (1); +savepoint a2; +insert into tt values (2); +savepoint b; +insert into tt values (3); +rollback to a2; +commit; +select * from tt; +id +0 +1 +drop table ti,tt; diff --git a/mysql-test/suite/tokudb.bugs/t/db817.test b/mysql-test/suite/tokudb.bugs/t/db817.test new file mode 100644 index 00000000000..53c9edc3893 --- /dev/null +++ b/mysql-test/suite/tokudb.bugs/t/db817.test @@ -0,0 +1,38 @@ +# verify that duplicate savepoint names in innodb and tokudb work the same +source include/have_innodb.inc; +source include/have_tokudb.inc; +disable_warnings; +drop table if exists ti; +enable_warnings; +create table ti (id int primary key) engine=innodb; +begin; +insert into ti values (0); +savepoint b; +insert into ti values (1); +savepoint a2; +insert into ti values (2); +savepoint b; +insert into ti values (3); +rollback to a2; +commit; +select * from ti; + +disable_warnings; +drop table if exists tt; +enable_warnings; +create table tt (id int primary key) engine=tokudb; +begin; +insert into tt values (0); +savepoint b; +insert into tt values (1); +savepoint a2; +insert into tt values (2); +savepoint b; +insert into tt values (3); +rollback to a2; +commit; +select * from tt; + +drop table ti,tt; + + diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index c7b3302c248..b348b3bd599 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -3926,13 +3926,13 @@ int ha_tokudb::write_row(uchar * record) { goto cleanup; } } - txn = create_sub_trans ? sub_trans : transaction; - + if (tokudb_debug & TOKUDB_DEBUG_TXN) { + TOKUDB_HANDLER_TRACE("txn %p", txn); + } if (tokudb_debug & TOKUDB_DEBUG_CHECK_KEY) { test_row_packing(record,&prim_key,&row); } - if (loader) { error = loader->put(loader, &prim_key, &row); if (error) { @@ -4206,7 +4206,7 @@ int ha_tokudb::delete_row(const uchar * record) { bool has_null; THD* thd = ha_thd(); uint curr_num_DBs; - tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton);; + tokudb_trx_data* trx = (tokudb_trx_data *) thd_get_ha_data(thd, tokudb_hton); ha_statistic_increment(&SSV::ha_delete_count); @@ -4231,10 +4231,14 @@ int ha_tokudb::delete_row(const uchar * record) { goto cleanup; } + if (tokudb_debug & TOKUDB_DEBUG_TXN) { + TOKUDB_HANDLER_TRACE("all %p stmt %p sub_sp_level %p transaction %p", trx->all, trx->stmt, trx->sub_sp_level, transaction); + } + error = db_env->del_multiple( db_env, share->key_file[primary_key], - transaction, + transaction, &prim_key, &row, curr_num_DBs, diff --git a/storage/tokudb/hatoku_hton.cc b/storage/tokudb/hatoku_hton.cc index 23b3fd028ed..c3dcd7be221 100644 --- a/storage/tokudb/hatoku_hton.cc +++ b/storage/tokudb/hatoku_hton.cc @@ -946,7 +946,7 @@ cleanup: #endif static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint) { - TOKUDB_DBUG_ENTER(""); + TOKUDB_DBUG_ENTER("%p", savepoint); int error; SP_INFO save_info = (SP_INFO)savepoint; tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton); @@ -967,6 +967,9 @@ static int tokudb_savepoint(handlerton * hton, THD * thd, void *savepoint) { trx->sp_level = save_info->txn; save_info->in_sub_stmt = false; } + if (tokudb_debug & TOKUDB_DEBUG_TXN) { + TOKUDB_TRACE("begin txn %p", save_info->txn); + } save_info->trx = trx; error = 0; cleanup: @@ -974,7 +977,7 @@ cleanup: } static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *savepoint) { - TOKUDB_DBUG_ENTER(""); + TOKUDB_DBUG_ENTER("%p", savepoint); int error; SP_INFO save_info = (SP_INFO)savepoint; DB_TXN* parent = NULL; @@ -982,6 +985,9 @@ static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *save tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton); parent = txn_to_rollback->parent; + if (tokudb_debug & TOKUDB_DEBUG_TXN) { + TOKUDB_TRACE("rollback txn %p", txn_to_rollback); + } if (!(error = txn_to_rollback->abort(txn_to_rollback))) { if (save_info->in_sub_stmt) { trx->sub_sp_level = parent; @@ -995,24 +1001,27 @@ static int tokudb_rollback_to_savepoint(handlerton * hton, THD * thd, void *save } static int tokudb_release_savepoint(handlerton * hton, THD * thd, void *savepoint) { - TOKUDB_DBUG_ENTER(""); - int error; - + TOKUDB_DBUG_ENTER("%p", savepoint); + int error = 0; SP_INFO save_info = (SP_INFO)savepoint; DB_TXN* parent = NULL; DB_TXN* txn_to_commit = save_info->txn; tokudb_trx_data *trx = (tokudb_trx_data *) thd_get_ha_data(thd, hton); parent = txn_to_commit->parent; - if (!(error = txn_to_commit->commit(txn_to_commit, 0))) { + if (tokudb_debug & TOKUDB_DEBUG_TXN) { + TOKUDB_TRACE("commit txn %p", txn_to_commit); + } + DB_TXN *child = txn_to_commit->get_child(txn_to_commit); + if (child == NULL && !(error = txn_to_commit->commit(txn_to_commit, 0))) { if (save_info->in_sub_stmt) { trx->sub_sp_level = parent; } else { trx->sp_level = parent; } - save_info->txn = NULL; } + save_info->txn = NULL; TOKUDB_DBUG_RETURN(error); }