mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Many files:
Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) sql/ha_innodb.cc: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/row/row0mysql.c: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/fil/fil0fil.c: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/dict/dict0crea.c: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/dict/dict0dict.c: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/dict/dict0load.c: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/dict/dict0mem.c: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/include/mem0mem.ic: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/include/dict0mem.h: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/include/fil0fil.h: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/include/mem0mem.h: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1) innobase/mem/mem0mem.c: Fix bug #5137: if innodb_file_per_table was specified, CREATE TEMPORARY TABLE ... TYPE=InnoDB said that cannot find path specified, and made mysqld to exit(1)
This commit is contained in:
@ -205,6 +205,8 @@ dict_build_table_def_step(
|
||||
dict_table_t* cluster_table;
|
||||
dtuple_t* row;
|
||||
ulint error;
|
||||
const char* path_or_name;
|
||||
ibool is_path;
|
||||
mtr_t mtr;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
@ -245,8 +247,19 @@ dict_build_table_def_step(
|
||||
|
||||
table->space = 0; /* reset to zero for the call below */
|
||||
|
||||
if (table->dir_path_of_temp_table) {
|
||||
/* We place tables created with CREATE TEMPORARY
|
||||
TABLE in the tmp dir of mysqld server */
|
||||
|
||||
path_or_name = table->dir_path_of_temp_table;
|
||||
is_path = TRUE;
|
||||
} else {
|
||||
path_or_name = table->name;
|
||||
is_path = FALSE;
|
||||
}
|
||||
|
||||
error = fil_create_new_single_table_tablespace(
|
||||
&(table->space), table->name,
|
||||
&(table->space), path_or_name, is_path,
|
||||
FIL_IBD_FILE_INITIAL_SIZE);
|
||||
if (error != DB_SUCCESS) {
|
||||
|
||||
|
@ -943,8 +943,16 @@ dict_table_rename_in_cache(
|
||||
.ibd file */
|
||||
|
||||
if (table->space != 0) {
|
||||
success = fil_rename_tablespace(table->name, table->space,
|
||||
new_name);
|
||||
if (table->dir_path_of_temp_table != NULL) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Error: trying to rename a table %s (%s) created with CREATE\n"
|
||||
"InnoDB: TEMPORARY TABLE\n", table->name, table->dir_path_of_temp_table);
|
||||
success = FALSE;
|
||||
} else {
|
||||
success = fil_rename_tablespace(table->name,
|
||||
table->space, new_name);
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
|
||||
return(FALSE);
|
||||
|
@ -262,7 +262,7 @@ loop:
|
||||
exists; print a warning to the .err log if not */
|
||||
|
||||
fil_space_for_table_exists_in_mem(space_id, name,
|
||||
TRUE, TRUE);
|
||||
FALSE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
mem_free(name);
|
||||
@ -761,7 +761,7 @@ dict_load_table(
|
||||
/* Check if the tablespace exists and has the right name */
|
||||
if (space != 0) {
|
||||
if (fil_space_for_table_exists_in_mem(space, name, FALSE,
|
||||
FALSE)) {
|
||||
FALSE, FALSE)) {
|
||||
/* Ok; (if we did a crash recovery then the tablespace
|
||||
can already be in the memory cache) */
|
||||
} else {
|
||||
|
@ -50,6 +50,7 @@ dict_mem_table_create(
|
||||
|
||||
table->type = DICT_TABLE_ORDINARY;
|
||||
table->name = mem_heap_strdup(heap, name);
|
||||
table->dir_path_of_temp_table = NULL;
|
||||
table->space = space;
|
||||
table->ibd_file_missing = FALSE;
|
||||
table->tablespace_discarded = FALSE;
|
||||
|
@ -1740,7 +1740,7 @@ fil_op_log_parse_or_replay(
|
||||
|
||||
ut_a(DB_SUCCESS ==
|
||||
fil_create_new_single_table_tablespace(
|
||||
&space_id, name,
|
||||
&space_id, name, FALSE,
|
||||
FIL_IBD_FILE_INITIAL_SIZE));
|
||||
}
|
||||
}
|
||||
@ -1977,25 +1977,34 @@ fil_rename_tablespace_in_mem(
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Allocates a file name for a single-table tablespace.
|
||||
The string must be freed by caller with mem_free(). */
|
||||
Allocates a file name for a single-table tablespace. The string must be freed
|
||||
by caller with mem_free(). */
|
||||
static
|
||||
char*
|
||||
fil_make_ibd_name(
|
||||
/*==============*/
|
||||
/* out, own: file name */
|
||||
const char* name) /* in: table name */
|
||||
const char* name, /* in: table name or a dir path of a
|
||||
TEMPORARY table */
|
||||
ibool is_temp) /* in: TRUE if it is a dir path */
|
||||
{
|
||||
ulint namelen = strlen(name);
|
||||
ulint dirlen = strlen(fil_path_to_mysql_datadir);
|
||||
char* filename = mem_alloc(namelen + dirlen + sizeof "/.ibd");
|
||||
|
||||
if (is_temp) {
|
||||
memcpy(filename, name, namelen);
|
||||
memcpy(filename + namelen, ".ibd", sizeof ".ibd");
|
||||
} else {
|
||||
memcpy(filename, fil_path_to_mysql_datadir, dirlen);
|
||||
filename[dirlen] = '/';
|
||||
|
||||
memcpy(filename + dirlen + 1, name, namelen);
|
||||
memcpy(filename + dirlen + namelen + 1, ".ibd", sizeof ".ibd");
|
||||
}
|
||||
|
||||
srv_normalize_path_for_win(filename);
|
||||
|
||||
return(filename);
|
||||
}
|
||||
|
||||
@ -2104,7 +2113,7 @@ retry:
|
||||
/* Check that the old name in the space is right */
|
||||
|
||||
if (old_name_was_specified) {
|
||||
old_path = fil_make_ibd_name(old_name);
|
||||
old_path = fil_make_ibd_name(old_name, FALSE);
|
||||
|
||||
ut_a(strcmp(space->name, old_path) == 0);
|
||||
ut_a(strcmp(node->name, old_path) == 0);
|
||||
@ -2113,7 +2122,7 @@ retry:
|
||||
}
|
||||
|
||||
/* Rename the tablespace and the node in the memory cache */
|
||||
path = fil_make_ibd_name(new_name);
|
||||
path = fil_make_ibd_name(new_name, FALSE);
|
||||
success = fil_rename_tablespace_in_mem(space, node, path);
|
||||
|
||||
if (success) {
|
||||
@ -2153,7 +2162,8 @@ retry:
|
||||
Creates a new single-table tablespace to a database directory of MySQL.
|
||||
Database directories are under the 'datadir' of MySQL. The datadir is the
|
||||
directory of a running mysqld program. We can refer to it by simply the
|
||||
path '.'. */
|
||||
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
|
||||
dir of the mysqld server. */
|
||||
|
||||
ulint
|
||||
fil_create_new_single_table_tablespace(
|
||||
@ -2164,7 +2174,10 @@ fil_create_new_single_table_tablespace(
|
||||
otherwise output */
|
||||
const char* tablename, /* in: the table name in the usual
|
||||
databasename/tablename format
|
||||
of InnoDB */
|
||||
of InnoDB, or a dir path to a temp
|
||||
table */
|
||||
ibool is_temp, /* in: TRUE if a table created with
|
||||
CREATE TEMPORARY TABLE */
|
||||
ulint size) /* in: the initial size of the
|
||||
tablespace file in pages,
|
||||
must be >= FIL_IBD_FILE_INITIAL_SIZE */
|
||||
@ -2179,7 +2192,7 @@ fil_create_new_single_table_tablespace(
|
||||
|
||||
ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE);
|
||||
|
||||
path = fil_make_ibd_name(tablename);
|
||||
path = fil_make_ibd_name(tablename, is_temp);
|
||||
|
||||
file = os_file_create(path, OS_FILE_CREATE, OS_FILE_NORMAL,
|
||||
OS_DATA_FILE, &ret);
|
||||
@ -2348,7 +2361,7 @@ fil_reset_too_high_lsns(
|
||||
ulint page_no;
|
||||
ibool success;
|
||||
|
||||
filepath = fil_make_ibd_name(name);
|
||||
filepath = fil_make_ibd_name(name, FALSE);
|
||||
|
||||
file = os_file_create_simple_no_error_handling(filepath, OS_FILE_OPEN,
|
||||
OS_FILE_READ_WRITE, &success);
|
||||
@ -2482,7 +2495,7 @@ fil_open_single_table_tablespace(
|
||||
ulint space_id;
|
||||
ibool ret = TRUE;
|
||||
|
||||
filepath = fil_make_ibd_name(name);
|
||||
filepath = fil_make_ibd_name(name, FALSE);
|
||||
|
||||
file = os_file_create_simple_no_error_handling(filepath, OS_FILE_OPEN,
|
||||
OS_FILE_READ_ONLY, &success);
|
||||
@ -2499,6 +2512,8 @@ fil_open_single_table_tablespace(
|
||||
fputs("!\n"
|
||||
"InnoDB: Have you moved InnoDB .ibd files around without using the\n"
|
||||
"InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?\n"
|
||||
"InnoDB: It is also possible that this is a table created with\n"
|
||||
"InnoDB: CREATE TEMPORARY TABLE, and MySQL removed the .ibd file for this.\n"
|
||||
"InnoDB: Please refer to\n"
|
||||
"InnoDB:"
|
||||
" http://dev.mysql.com/doc/mysql/en/InnoDB_troubleshooting_datadict.html\n"
|
||||
@ -3051,7 +3066,10 @@ fil_space_for_table_exists_in_mem(
|
||||
exists in the memory cache */
|
||||
ulint id, /* in: space id */
|
||||
const char* name, /* in: table name in the standard
|
||||
'databasename/tablename' format */
|
||||
'databasename/tablename' format or
|
||||
the dir path to a temp table */
|
||||
ibool is_temp, /* in: TRUE if created with CREATE
|
||||
TEMPORARY TABLE */
|
||||
ibool mark_space, /* in: in crash recovery, at database
|
||||
startup we mark all spaces which have
|
||||
an associated table in the InnoDB
|
||||
@ -3073,7 +3091,7 @@ fil_space_for_table_exists_in_mem(
|
||||
|
||||
mutex_enter(&(system->mutex));
|
||||
|
||||
path = fil_make_ibd_name(name);
|
||||
path = fil_make_ibd_name(name, is_temp);
|
||||
|
||||
/* Look if there is a space with the same id */
|
||||
|
||||
@ -3114,7 +3132,10 @@ fil_space_for_table_exists_in_mem(
|
||||
fprintf(stderr, "\n"
|
||||
"InnoDB: in InnoDB data dictionary has tablespace id %lu,\n"
|
||||
"InnoDB: but tablespace with that id or name does not exist. Have\n"
|
||||
"InnoDB: you deleted or moved .ibd files?\n",
|
||||
"InnoDB: you deleted or moved .ibd files?\n"
|
||||
"InnoDB: This may also be a table created with CREATE TEMPORARY TABLE\n"
|
||||
"InnoDB: whose .ibd and .frm files MySQL automatically removed, but the\n"
|
||||
"InnoDB: table still exists in the InnoDB internal data dictionary.\n",
|
||||
(ulong) id);
|
||||
} else {
|
||||
ut_print_timestamp(stderr);
|
||||
@ -3189,7 +3210,7 @@ fil_get_space_id_for_table(
|
||||
|
||||
mutex_enter(&(system->mutex));
|
||||
|
||||
path = fil_make_ibd_name(name);
|
||||
path = fil_make_ibd_name(name, FALSE);
|
||||
|
||||
/* Look if there is a space with the same name; the name is the
|
||||
directory path to the file */
|
||||
|
@ -305,6 +305,12 @@ struct dict_table_struct{
|
||||
ulint type; /* DICT_TABLE_ORDINARY, ... */
|
||||
mem_heap_t* heap; /* memory heap */
|
||||
const char* name; /* table name */
|
||||
const char* dir_path_of_temp_table;/* NULL or the directory path
|
||||
where a TEMPORARY table that was explicitly
|
||||
created by a user should be placed if
|
||||
innodb_file_per_table is defined in my.cnf;
|
||||
in Unix this is usually /tmp/..., in Windows
|
||||
\temp\... */
|
||||
ulint space; /* space where the clustered index of the
|
||||
table is placed */
|
||||
ibool ibd_file_missing;/* TRUE if this is in a single-table
|
||||
|
@ -339,11 +339,13 @@ fil_rename_tablespace(
|
||||
const char* new_name); /* in: new table name in the standard
|
||||
databasename/tablename format
|
||||
of InnoDB */
|
||||
|
||||
/***********************************************************************
|
||||
Creates a new single-table tablespace to a database directory of MySQL.
|
||||
Database directories are under the 'datadir' of MySQL. The datadir is the
|
||||
directory of a running mysqld program. We can refer to it by simply the
|
||||
path '.'. */
|
||||
path '.'. Tables created with CREATE TEMPORARY TABLE we place in the temp
|
||||
dir of the mysqld server. */
|
||||
|
||||
ulint
|
||||
fil_create_new_single_table_tablespace(
|
||||
@ -354,7 +356,10 @@ fil_create_new_single_table_tablespace(
|
||||
otherwise output */
|
||||
const char* tablename, /* in: the table name in the usual
|
||||
databasename/tablename format
|
||||
of InnoDB */
|
||||
of InnoDB, or a dir path to a temp
|
||||
table */
|
||||
ibool is_temp, /* in: TRUE if a table created with
|
||||
CREATE TEMPORARY TABLE */
|
||||
ulint size); /* in: the initial size of the
|
||||
tablespace file in pages,
|
||||
must be >= FIL_IBD_FILE_INITIAL_SIZE */
|
||||
@ -446,7 +451,10 @@ fil_space_for_table_exists_in_mem(
|
||||
exists in the memory cache */
|
||||
ulint id, /* in: space id */
|
||||
const char* name, /* in: table name in the standard
|
||||
'databasename/tablename' format */
|
||||
'databasename/tablename' format or
|
||||
the dir path to a temp table */
|
||||
ibool is_temp, /* in: TRUE if created with CREATE
|
||||
TEMPORARY TABLE */
|
||||
ibool mark_space, /* in: in crash recovery, at database
|
||||
startup we mark all spaces which have
|
||||
an associated table in the InnoDB
|
||||
|
@ -295,7 +295,7 @@ mem_strdupq(
|
||||
|
||||
/**************************************************************************
|
||||
Duplicates a NUL-terminated string, allocated from a memory heap. */
|
||||
UNIV_INLINE
|
||||
|
||||
char*
|
||||
mem_heap_strdup(
|
||||
/*============*/
|
||||
|
@ -627,20 +627,6 @@ mem_strdupq(
|
||||
return(dst);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Duplicates a NUL-terminated string, allocated from a memory heap. */
|
||||
UNIV_INLINE
|
||||
char*
|
||||
mem_heap_strdup(
|
||||
/*============*/
|
||||
/* out, own: a copy of the string */
|
||||
mem_heap_t* heap, /* in: memory heap where string is allocated */
|
||||
const char* str) /* in: string to be copied */
|
||||
{
|
||||
ulint len = strlen(str) + 1;
|
||||
return(memcpy(mem_heap_alloc(heap, len), str, len));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Makes a NUL-terminated copy of a nonterminated string,
|
||||
allocated from a memory heap. */
|
||||
|
@ -102,6 +102,20 @@ mem_alloc_func_noninline(
|
||||
return(mem_alloc_func(n, file_name, line));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Duplicates a NUL-terminated string, allocated from a memory heap. */
|
||||
|
||||
char*
|
||||
mem_heap_strdup(
|
||||
/*============*/
|
||||
/* out, own: a copy of the string */
|
||||
mem_heap_t* heap, /* in: memory heap where string is allocated */
|
||||
const char* str) /* in: string to be copied */
|
||||
{
|
||||
ulint len = strlen(str) + 1;
|
||||
return(memcpy(mem_heap_alloc(heap, len), str, len));
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Creates a memory heap block where data can be allocated. */
|
||||
|
||||
|
@ -2243,14 +2243,17 @@ row_drop_table_for_mysql(
|
||||
ulint err;
|
||||
const char* table_name;
|
||||
ulint namelen;
|
||||
char* dir_path_of_temp_table = NULL;
|
||||
ibool success;
|
||||
ibool locked_dictionary = FALSE;
|
||||
char* quoted_name;
|
||||
char* sql;
|
||||
|
||||
/* We use the private SQL parser of Innobase to generate the
|
||||
query graphs needed in deleting the dictionary data from system
|
||||
tables in Innobase. Deleting a row from SYS_INDEXES table also
|
||||
frees the file segments of the B-tree associated with the index. */
|
||||
|
||||
static const char str1[] =
|
||||
"PROCEDURE DROP_TABLE_PROC () IS\n"
|
||||
"table_name CHAR;\n"
|
||||
@ -2509,7 +2512,21 @@ row_drop_table_for_mysql(
|
||||
|
||||
ut_error;
|
||||
} else {
|
||||
ibool is_path;
|
||||
const char* name_or_path;
|
||||
|
||||
space_id = table->space;
|
||||
|
||||
if (table->dir_path_of_temp_table != NULL) {
|
||||
dir_path_of_temp_table =
|
||||
mem_strdup(table->dir_path_of_temp_table);
|
||||
is_path = TRUE;
|
||||
name_or_path = dir_path_of_temp_table;
|
||||
} else {
|
||||
is_path = FALSE;
|
||||
name_or_path = name;
|
||||
}
|
||||
|
||||
dict_table_remove_from_cache(table);
|
||||
|
||||
if (dict_load_table(name) != NULL) {
|
||||
@ -2525,7 +2542,9 @@ row_drop_table_for_mysql(
|
||||
wrong: we do not want to delete valuable data of the user */
|
||||
|
||||
if (err == DB_SUCCESS && space_id > 0) {
|
||||
if (!fil_space_for_table_exists_in_mem(space_id, name,
|
||||
if (!fil_space_for_table_exists_in_mem(space_id,
|
||||
name_or_path,
|
||||
is_path,
|
||||
FALSE, TRUE)) {
|
||||
err = DB_ERROR;
|
||||
|
||||
@ -2551,6 +2570,10 @@ funct_exit:
|
||||
row_mysql_unlock_data_dictionary(trx);
|
||||
}
|
||||
|
||||
if (dir_path_of_temp_table) {
|
||||
mem_free(dir_path_of_temp_table);
|
||||
}
|
||||
|
||||
que_graph_free(graph);
|
||||
|
||||
trx_commit_for_mysql(trx);
|
||||
|
@ -3353,7 +3353,15 @@ create_table_def(
|
||||
trx_t* trx, /* in: InnoDB transaction handle */
|
||||
TABLE* form, /* in: information on table
|
||||
columns and indexes */
|
||||
const char* table_name) /* in: table name */
|
||||
const char* table_name, /* in: table name */
|
||||
const char* path_of_temp_table)/* in: if this is a table explicitly
|
||||
created by the user with the
|
||||
TEMPORARY keyword, then this
|
||||
parameter is the dir path where the
|
||||
table should be placed if we create
|
||||
an .ibd file for it (no .ibd extension
|
||||
in the path, though); otherwise this
|
||||
is NULL */
|
||||
{
|
||||
Field* field;
|
||||
dict_table_t* table;
|
||||
@ -3376,6 +3384,11 @@ create_table_def(
|
||||
|
||||
table = dict_mem_table_create((char*) table_name, 0, n_cols);
|
||||
|
||||
if (path_of_temp_table) {
|
||||
table->dir_path_of_temp_table =
|
||||
mem_heap_strdup(table->heap, path_of_temp_table);
|
||||
}
|
||||
|
||||
for (i = 0; i < n_cols; i++) {
|
||||
field = form->field[i];
|
||||
|
||||
@ -3456,8 +3469,7 @@ create_index(
|
||||
|
||||
ind_type = 0;
|
||||
|
||||
if (key_num == form->primary_key)
|
||||
{
|
||||
if (key_num == form->primary_key) {
|
||||
ind_type = ind_type | DICT_CLUSTERED;
|
||||
}
|
||||
|
||||
@ -3622,7 +3634,7 @@ ha_innobase::create(
|
||||
srv_lower_case_table_names = FALSE;
|
||||
}
|
||||
|
||||
fn_format(name2, name, "", "",2); // Remove the .frm extension
|
||||
fn_format(name2, name, "", "", 2); // Remove the .frm extension
|
||||
|
||||
normalize_table_name(norm_name, name2);
|
||||
|
||||
@ -3634,7 +3646,12 @@ ha_innobase::create(
|
||||
|
||||
/* Create the table definition in InnoDB */
|
||||
|
||||
error = create_table_def(trx, form, norm_name);
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE) {
|
||||
|
||||
error = create_table_def(trx, form, norm_name, name2);
|
||||
} else {
|
||||
error = create_table_def(trx, form, norm_name, NULL);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
innobase_commit_low(trx);
|
||||
@ -3710,8 +3727,8 @@ ha_innobase::create(
|
||||
}
|
||||
|
||||
if (current_thd->query != NULL) {
|
||||
|
||||
LEX_STRING q;
|
||||
|
||||
if (thd->convert_string(&q, system_charset_info,
|
||||
current_thd->query,
|
||||
current_thd->query_length,
|
||||
|
Reference in New Issue
Block a user