Commit 2341d537 authored by marko's avatar marko

branches/zip: Merge revisions 3601:3930 from branches/5.1:

  ------------------------------------------------------------------------
  r3911 | sunny | 2009-01-13 14:15:24 +0200 (Tue, 13 Jan 2009) | 13 lines

  branches/5.1: Fix Bug#38187 Error 153 when creating savepoints
  InnoDB previously treated savepoints as a stack e.g.,
    SAVEPOINT a;
    SAVEPOINT b;
    SAVEPOINT c;
    SAVEPOINT b; <- This would delete b and c.

  This fix changes the behavior to:
    SAVEPOINT a;
    SAVEPOINT b;
    SAVEPOINT c;
    SAVEPOINT b; <- Does not delete savepoint c
  ------------------------------------------------------------------------
  r3930 | marko | 2009-01-14 15:51:30 +0200 (Wed, 14 Jan 2009) | 4 lines

  branches/5.1: dict_load_table(): If dict_load_indexes() fails,
  invoke dict_table_remove_from_cache() instead of dict_mem_table_free(),
  so that the data dictionary will not point to freed data.
  (Bug #42075, Issue #153, rb://76 approved by Heikki Tuuri)
  ------------------------------------------------------------------------
parent 2f7bcc7d
...@@ -949,11 +949,11 @@ err_exit: ...@@ -949,11 +949,11 @@ err_exit:
of the error condition, since the user may want to dump data from the of the error condition, since the user may want to dump data from the
clustered index. However we load the foreign key information only if clustered index. However we load the foreign key information only if
all indexes were loaded. */ all indexes were loaded. */
if (err != DB_SUCCESS && !srv_force_recovery) { if (err == DB_SUCCESS) {
dict_mem_table_free(table);
table = NULL;
} else if (err == DB_SUCCESS) {
err = dict_load_foreigns(table->name, TRUE); err = dict_load_foreigns(table->name, TRUE);
} else if (!srv_force_recovery) {
dict_table_remove_from_cache(table);
table = NULL;
} }
# if 0 # if 0
if (err != DB_SUCCESS && table != NULL) { if (err != DB_SUCCESS && table != NULL) {
......
...@@ -15,6 +15,8 @@ Created 3/26/1996 Heikki Tuuri ...@@ -15,6 +15,8 @@ Created 3/26/1996 Heikki Tuuri
#include "mtr0mtr.h" #include "mtr0mtr.h"
#include "trx0sys.h" #include "trx0sys.h"
#define trx_roll_free_all_savepoints(s) trx_roll_savepoints_free((s), NULL)
/*********************************************************************** /***********************************************************************
Determines if this transaction is rolling back an incomplete transaction Determines if this transaction is rolling back an incomplete transaction
in crash recovery. */ in crash recovery. */
...@@ -249,8 +251,18 @@ trx_release_savepoint_for_mysql( ...@@ -249,8 +251,18 @@ trx_release_savepoint_for_mysql(
const char* savepoint_name); /* in: savepoint name */ const char* savepoint_name); /* in: savepoint name */
/*********************************************************************** /***********************************************************************
Frees savepoint structs. */ Frees a single savepoint struct. */
UNIV_INTERN UNIV_INTERN
void
trx_roll_savepoint_free(
/*=====================*/
trx_t* trx, /* in: transaction handle */
trx_named_savept_t* savep); /* in: savepoint to free */
/***********************************************************************
Frees savepoint structs starting from savep, if savep == NULL then
free all savepoints. */
void void
trx_roll_savepoints_free( trx_roll_savepoints_free(
/*=====================*/ /*=====================*/
......
...@@ -171,8 +171,26 @@ trx_rollback_last_sql_stat_for_mysql( ...@@ -171,8 +171,26 @@ trx_rollback_last_sql_stat_for_mysql(
} }
/*********************************************************************** /***********************************************************************
Frees savepoint structs. */ Frees a single savepoint struct. */
UNIV_INTERN UNIV_INTERN
void
trx_roll_savepoint_free(
/*=====================*/
trx_t* trx, /* in: transaction handle */
trx_named_savept_t* savep) /* in: savepoint to free */
{
ut_a(savep != NULL);
ut_a(UT_LIST_GET_LEN(trx->trx_savepoints) > 0);
UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
mem_free(savep->name);
mem_free(savep);
}
/***********************************************************************
Frees savepoint structs starting from savep, if savep == NULL then
free all savepoints. */
void void
trx_roll_savepoints_free( trx_roll_savepoints_free(
/*=====================*/ /*=====================*/
...@@ -192,9 +210,7 @@ trx_roll_savepoints_free( ...@@ -192,9 +210,7 @@ trx_roll_savepoints_free(
while (savep != NULL) { while (savep != NULL) {
next_savep = UT_LIST_GET_NEXT(trx_savepoints, savep); next_savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep); trx_roll_savepoint_free(trx, savep);
mem_free(savep->name);
mem_free(savep);
savep = next_savep; savep = next_savep;
} }
...@@ -329,8 +345,8 @@ trx_savepoint_for_mysql( ...@@ -329,8 +345,8 @@ trx_savepoint_for_mysql(
} }
/*********************************************************************** /***********************************************************************
Releases a named savepoint. Savepoints which Releases only the named savepoint. Savepoints which were set after this
were set after this savepoint are deleted. */ savepoint are left as is. */
UNIV_INTERN UNIV_INTERN
ulint ulint
trx_release_savepoint_for_mysql( trx_release_savepoint_for_mysql(
...@@ -346,31 +362,16 @@ trx_release_savepoint_for_mysql( ...@@ -346,31 +362,16 @@ trx_release_savepoint_for_mysql(
savep = UT_LIST_GET_FIRST(trx->trx_savepoints); savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
/* Search for the savepoint by name and free if found. */
while (savep != NULL) { while (savep != NULL) {
if (0 == ut_strcmp(savep->name, savepoint_name)) { if (0 == ut_strcmp(savep->name, savepoint_name)) {
/* Found */ trx_roll_savepoint_free(trx, savep);
break; return(DB_SUCCESS);
} }
savep = UT_LIST_GET_NEXT(trx_savepoints, savep); savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
} }
if (savep == NULL) { return(DB_NO_SAVEPOINT);
return(DB_NO_SAVEPOINT);
}
/* We can now free all savepoints strictly later than this one */
trx_roll_savepoints_free(trx, savep);
/* Now we can free this savepoint too */
UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
mem_free(savep->name);
mem_free(savep);
return(DB_SUCCESS);
} }
/*********************************************************************** /***********************************************************************
......
...@@ -917,8 +917,8 @@ trx_commit_off_kernel( ...@@ -917,8 +917,8 @@ trx_commit_off_kernel(
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
} }
/* Free savepoints */ /* Free all savepoints */
trx_roll_savepoints_free(trx, NULL); trx_roll_free_all_savepoints(trx);
trx->conc_state = TRX_NOT_STARTED; trx->conc_state = TRX_NOT_STARTED;
trx->rseg = NULL; trx->rseg = NULL;
......
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