Commit 5dd0a711 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 d46597eb
......@@ -949,11 +949,11 @@ dict_load_table(
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
all indexes were loaded. */
if (err != DB_SUCCESS && !srv_force_recovery) {
dict_mem_table_free(table);
table = NULL;
} else if (err == DB_SUCCESS) {
if (err == DB_SUCCESS) {
err = dict_load_foreigns(table->name, TRUE);
} else if (!srv_force_recovery) {
dict_table_remove_from_cache(table);
table = NULL;
}
# if 0
if (err != DB_SUCCESS && table != NULL) {
......
......@@ -15,6 +15,8 @@ Created 3/26/1996 Heikki Tuuri
#include "mtr0mtr.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
in crash recovery. */
......@@ -249,8 +251,18 @@ trx_release_savepoint_for_mysql(
const char* savepoint_name); /* in: savepoint name */
/***********************************************************************
Frees savepoint structs. */
Frees a single savepoint struct. */
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
trx_roll_savepoints_free(
/*=====================*/
......
......@@ -171,8 +171,26 @@ trx_rollback_last_sql_stat_for_mysql(
}
/***********************************************************************
Frees savepoint structs. */
Frees a single savepoint struct. */
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
trx_roll_savepoints_free(
/*=====================*/
......@@ -192,9 +210,7 @@ trx_roll_savepoints_free(
while (savep != NULL) {
next_savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep);
mem_free(savep->name);
mem_free(savep);
trx_roll_savepoint_free(trx, savep);
savep = next_savep;
}
......@@ -329,8 +345,8 @@ trx_savepoint_for_mysql(
}
/***********************************************************************
Releases a named savepoint. Savepoints which
were set after this savepoint are deleted. */
Releases only the named savepoint. Savepoints which were set after this
savepoint are left as is. */
UNIV_INTERN
ulint
trx_release_savepoint_for_mysql(
......@@ -346,31 +362,16 @@ trx_release_savepoint_for_mysql(
savep = UT_LIST_GET_FIRST(trx->trx_savepoints);
/* Search for the savepoint by name and free if found. */
while (savep != NULL) {
if (0 == ut_strcmp(savep->name, savepoint_name)) {
/* Found */
break;
trx_roll_savepoint_free(trx, savep);
return(DB_SUCCESS);
}
savep = UT_LIST_GET_NEXT(trx_savepoints, savep);
}
if (savep == NULL) {
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);
return(DB_NO_SAVEPOINT);
}
/***********************************************************************
......
......@@ -917,8 +917,8 @@ trx_commit_off_kernel(
mutex_enter(&kernel_mutex);
}
/* Free savepoints */
trx_roll_savepoints_free(trx, NULL);
/* Free all savepoints */
trx_roll_free_all_savepoints(trx);
trx->conc_state = TRX_NOT_STARTED;
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