Fix for bug#20867 InnoDB Bug - create temporary table+crash => mysqld needs to clean up

2nd version
During tmp tables cleanup we get the handler for temporary table
and delete table using handler method.
parent 5b1b0a6f
...@@ -861,6 +861,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname, ...@@ -861,6 +861,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname,
/* mysqld.cc */ /* mysqld.cc */
extern void yyerror(const char*); extern void yyerror(const char*);
my_bool mysql_rm_tmp_tables(void);
/* item_func.cc */ /* item_func.cc */
extern bool check_reserved_words(LEX_STRING *name); extern bool check_reserved_words(LEX_STRING *name);
......
...@@ -3241,7 +3241,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); ...@@ -3241,7 +3241,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
*/ */
error_handler_hook = my_message_sql; error_handler_hook = my_message_sql;
start_signal_handler(); // Creates pidfile start_signal_handler(); // Creates pidfile
if (acl_init(opt_noacl) || if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
my_tz_init((THD *)0, default_tz_name, opt_bootstrap)) my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
{ {
abort_loop=1; abort_loop=1;
......
...@@ -34,7 +34,6 @@ HASH assign_cache; ...@@ -34,7 +34,6 @@ HASH assign_cache;
static int open_unireg_entry(THD *thd,TABLE *entry,const char *db, static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
const char *name, const char *alias); const char *name, const char *alias);
static void free_cache_entry(TABLE *entry); static void free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void);
extern "C" byte *table_cache_key(const byte *record,uint *length, extern "C" byte *table_cache_key(const byte *record,uint *length,
...@@ -47,7 +46,6 @@ extern "C" byte *table_cache_key(const byte *record,uint *length, ...@@ -47,7 +46,6 @@ extern "C" byte *table_cache_key(const byte *record,uint *length,
bool table_cache_init(void) bool table_cache_init(void)
{ {
mysql_rm_tmp_tables();
return hash_init(&open_cache, &my_charset_bin, table_cache_size+16, return hash_init(&open_cache, &my_charset_bin, table_cache_size+16,
0, 0,table_cache_key, 0, 0,table_cache_key,
(hash_free_key) free_cache_entry, 0) != 0; (hash_free_key) free_cache_entry, 0) != 0;
...@@ -2940,14 +2938,20 @@ fill_record(Field **ptr,List<Item> &values, bool ignore_errors) ...@@ -2940,14 +2938,20 @@ fill_record(Field **ptr,List<Item> &values, bool ignore_errors)
} }
static void mysql_rm_tmp_tables(void) my_bool mysql_rm_tmp_tables(void)
{ {
uint i, idx; uint i, idx;
char filePath[FN_REFLEN], *tmpdir; char filePath[FN_REFLEN], *tmpdir, filePathCopy[FN_REFLEN];
MY_DIR *dirp; MY_DIR *dirp;
FILEINFO *file; FILEINFO *file;
TABLE tmp_table;
THD *thd;
DBUG_ENTER("mysql_rm_tmp_tables"); DBUG_ENTER("mysql_rm_tmp_tables");
if (!(thd= new THD))
DBUG_RETURN(1);
thd->store_globals();
for (i=0; i<=mysql_tmpdir_list.max; i++) for (i=0; i<=mysql_tmpdir_list.max; i++)
{ {
tmpdir=mysql_tmpdir_list.list[i]; tmpdir=mysql_tmpdir_list.list[i];
...@@ -2968,13 +2972,37 @@ static void mysql_rm_tmp_tables(void) ...@@ -2968,13 +2972,37 @@ static void mysql_rm_tmp_tables(void)
if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length)) if (!bcmp(file->name,tmp_file_prefix,tmp_file_prefix_length))
{ {
sprintf(filePath,"%s%s",tmpdir,file->name); char *ext= fn_ext(file->name);
VOID(my_delete(filePath,MYF(MY_WME))); uint ext_len= strlen(ext);
uint filePath_len= my_snprintf(filePath, sizeof(filePath),
"%s%s", tmpdir, file->name);
if (!bcmp(reg_ext, ext, ext_len))
{
TABLE tmp_table;
if (!openfrm(filePath, "tmp_table", (uint) 0,
READ_KEYINFO | COMPUTE_TYPES | EXTRA_RECORD,
0, &tmp_table))
{
/* We should cut file extention before deleting of table */
memcpy(filePathCopy, filePath, filePath_len - ext_len);
filePathCopy[filePath_len - ext_len]= 0;
tmp_table.file->delete_table(filePathCopy);
closefrm(&tmp_table);
}
}
/*
File can be already deleted by tmp_table.file->delete_table().
So we hide error messages which happnes during deleting of these
files(MYF(0)).
*/
VOID(my_delete(filePath, MYF(0)));
} }
} }
my_dirend(dirp); my_dirend(dirp);
} }
DBUG_VOID_RETURN; delete thd;
my_pthread_setspecific_ptr(THR_THD, 0);
DBUG_RETURN(0);
} }
......
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