summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2004-10-07 20:53:20 +0300
committerunknown <heikki@hundin.mysql.fi>2004-10-07 20:53:20 +0300
commit7efa215e254dc21ec89a30578669d31064d15f9c (patch)
tree6f703fce19246e6df6d180aa783050b5119d5b15 /innobase
parent5a390c9c70c8f28ea481870bf8ee6c5daabe00bc (diff)
downloadmariadb-git-7efa215e254dc21ec89a30578669d31064d15f9c.tar.gz
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)
Diffstat (limited to 'innobase')
-rw-r--r--innobase/dict/dict0crea.c15
-rw-r--r--innobase/dict/dict0dict.c12
-rw-r--r--innobase/dict/dict0load.c4
-rw-r--r--innobase/dict/dict0mem.c1
-rw-r--r--innobase/fil/fil0fil.c61
-rw-r--r--innobase/include/dict0mem.h6
-rw-r--r--innobase/include/fil0fil.h14
-rw-r--r--innobase/include/mem0mem.h2
-rw-r--r--innobase/include/mem0mem.ic14
-rw-r--r--innobase/mem/mem0mem.c14
-rw-r--r--innobase/row/row0mysql.c25
11 files changed, 124 insertions, 44 deletions
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index c887d821a3f..137964b26c1 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -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) {
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index aa7e90700f8..fd98538d2ad 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -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);
diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c
index 9293b117899..1866921c589 100644
--- a/innobase/dict/dict0load.c
+++ b/innobase/dict/dict0load.c
@@ -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 {
diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c
index 8f05475df47..1d45585aac1 100644
--- a/innobase/dict/dict0mem.c
+++ b/innobase/dict/dict0mem.c
@@ -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;
diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c
index edc459f2605..c4fc055dcde 100644
--- a/innobase/fil/fil0fil.c
+++ b/innobase/fil/fil0fil.c
@@ -959,7 +959,7 @@ fil_assign_new_space_id(void)
"InnoDB: Current counter is %lu and it must not exceed %lu!\n"
"InnoDB: To reset the counter to zero you have to dump all your tables and\n"
"InnoDB: recreate the whole InnoDB installation.\n", (ulong) id,
- (ulong) SRV_LOG_SPACE_FIRST_ID);
+ (ulong) SRV_LOG_SPACE_FIRST_ID);
}
if (id >= SRV_LOG_SPACE_FIRST_ID) {
@@ -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");
- memcpy(filename, fil_path_to_mysql_datadir, dirlen);
- filename[dirlen] = '/';
- memcpy(filename + dirlen + 1, name, namelen);
- memcpy(filename + dirlen + namelen + 1, ".ibd", 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 */
diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h
index 944fad1a8c8..1e496a25477 100644
--- a/innobase/include/dict0mem.h
+++ b/innobase/include/dict0mem.h
@@ -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
diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h
index 45549aee63c..5a5db77073a 100644
--- a/innobase/include/fil0fil.h
+++ b/innobase/include/fil0fil.h
@@ -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
diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h
index cd01ac77bf3..056d3dc508f 100644
--- a/innobase/include/mem0mem.h
+++ b/innobase/include/mem0mem.h
@@ -295,7 +295,7 @@ mem_strdupq(
/**************************************************************************
Duplicates a NUL-terminated string, allocated from a memory heap. */
-UNIV_INLINE
+
char*
mem_heap_strdup(
/*============*/
diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic
index d97b7d6c4dd..714c30e3642 100644
--- a/innobase/include/mem0mem.ic
+++ b/innobase/include/mem0mem.ic
@@ -628,20 +628,6 @@ mem_strdupq(
}
/**************************************************************************
-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. */
UNIV_INLINE
diff --git a/innobase/mem/mem0mem.c b/innobase/mem/mem0mem.c
index c090b25a632..85f0119d02a 100644
--- a/innobase/mem/mem0mem.c
+++ b/innobase/mem/mem0mem.c
@@ -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. */
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 88227d61f1d..b38fab45a8e 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -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);