diff options
author | unknown <heikki@hundin.mysql.fi> | 2004-10-07 20:53:20 +0300 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2004-10-07 20:53:20 +0300 |
commit | 7efa215e254dc21ec89a30578669d31064d15f9c (patch) | |
tree | 6f703fce19246e6df6d180aa783050b5119d5b15 /innobase | |
parent | 5a390c9c70c8f28ea481870bf8ee6c5daabe00bc (diff) | |
download | mariadb-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.c | 15 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 12 | ||||
-rw-r--r-- | innobase/dict/dict0load.c | 4 | ||||
-rw-r--r-- | innobase/dict/dict0mem.c | 1 | ||||
-rw-r--r-- | innobase/fil/fil0fil.c | 61 | ||||
-rw-r--r-- | innobase/include/dict0mem.h | 6 | ||||
-rw-r--r-- | innobase/include/fil0fil.h | 14 | ||||
-rw-r--r-- | innobase/include/mem0mem.h | 2 | ||||
-rw-r--r-- | innobase/include/mem0mem.ic | 14 | ||||
-rw-r--r-- | innobase/mem/mem0mem.c | 14 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 25 |
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); |