Commit 326bfb07 authored by Michael Widenius's avatar Michael Widenius

MDEV-14378 - Allow on to drop orphaned #sql- tables

DROP TABLE now also works on empty or short .frm files
parent cf5e193d
...@@ -95,7 +95,7 @@ FLUSH TABLES; ...@@ -95,7 +95,7 @@ FLUSH TABLES;
--echo # Drop the orphaned original table. --echo # Drop the orphaned original table.
--disable_query_log --disable_query_log
eval DROP TABLE `#mysql50#$temp_table_name`; eval DROP TABLE `$temp_table_name`;
--enable_query_log --enable_query_log
--echo # Files in datadir after manual recovery. --echo # Files in datadir after manual recovery.
......
...@@ -24,7 +24,7 @@ static int read_string(File file, uchar**to, size_t length) ...@@ -24,7 +24,7 @@ static int read_string(File file, uchar**to, size_t length)
{ {
DBUG_ENTER("read_string"); DBUG_ENTER("read_string");
my_free(*to); /* This can't use MY_THREAD_SPECIFIC as it's used on server start */
if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) || if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
mysql_file_read(file, *to, length, MYF(MY_NABP))) mysql_file_read(file, *to, length, MYF(MY_NABP)))
{ {
...@@ -51,7 +51,7 @@ static int read_string(File file, uchar**to, size_t length) ...@@ -51,7 +51,7 @@ static int read_string(File file, uchar**to, size_t length)
@param[out] is_sequence 1 if table is a SEQUENCE, 0 otherwise @param[out] is_sequence 1 if table is a SEQUENCE, 0 otherwise
@retval TABLE_TYPE_UNKNOWN error @retval TABLE_TYPE_UNKNOWN error - file can't be opened
@retval TABLE_TYPE_NORMAL table @retval TABLE_TYPE_NORMAL table
@retval TABLE_TYPE_SEQUENCE sequence table @retval TABLE_TYPE_SEQUENCE sequence table
@retval TABLE_TYPE_VIEW view @retval TABLE_TYPE_VIEW view
...@@ -72,32 +72,35 @@ Table_type dd_frm_type(THD *thd, char *path, LEX_CSTRING *engine_name, ...@@ -72,32 +72,35 @@ Table_type dd_frm_type(THD *thd, char *path, LEX_CSTRING *engine_name,
if ((file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) if ((file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0)))
< 0) < 0)
DBUG_RETURN(TABLE_TYPE_UNKNOWN); DBUG_RETURN(TABLE_TYPE_UNKNOWN);
error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP));
if (error)
goto err;
if (!strncmp((char*) header, "TYPE=VIEW\n", 10))
{
type= TABLE_TYPE_VIEW;
goto err;
}
/* /*
We return TABLE_TYPE_NORMAL if we can read the .frm file. This allows us We return TABLE_TYPE_NORMAL if we can open the .frm file. This allows us
to drop a bad .frm file with DROP TABLE to drop a bad .frm file with DROP TABLE
*/ */
type= TABLE_TYPE_NORMAL; type= TABLE_TYPE_NORMAL;
/* engine_name is 0 if we only want to know if table is view or not */
if (!engine_name)
goto err;
/* /*
Initialize engine name in case we are not able to find it out Initialize engine name in case we are not able to find it out
The cast is safe, as engine_name->str points to a usable buffer. The cast is safe, as engine_name->str points to a usable buffer.
*/ */
if (engine_name)
{
engine_name->length= 0; engine_name->length= 0;
((char*) (engine_name->str))[0]= 0; ((char*) (engine_name->str))[0]= 0;
}
if ((error= mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP))))
goto err;
if (!strncmp((char*) header, "TYPE=VIEW\n", 10))
{
type= TABLE_TYPE_VIEW;
goto err;
}
/* engine_name is 0 if we only want to know if table is view or not */
if (!engine_name)
goto err;
if (!is_binary_frm_header(header)) if (!is_binary_frm_header(header))
goto err; goto err;
......
...@@ -438,6 +438,13 @@ uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length) ...@@ -438,6 +438,13 @@ uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length)
} }
static bool check_if_frm_exists(char *path, const char *db, const char *table)
{
fn_format(path, table, db, reg_ext, MYF(0));
return !access(path, F_OK);
}
/* /*
Translate a table name to a file name (WL #1324). Translate a table name to a file name (WL #1324).
...@@ -528,13 +535,18 @@ uint build_table_filename(char *buff, size_t bufflen, const char *db, ...@@ -528,13 +535,18 @@ uint build_table_filename(char *buff, size_t bufflen, const char *db,
DBUG_PRINT("enter", ("db: '%s' table_name: '%s' ext: '%s' flags: %x", DBUG_PRINT("enter", ("db: '%s' table_name: '%s' ext: '%s' flags: %x",
db, table_name, ext, flags)); db, table_name, ext, flags));
(void) tablename_to_filename(db, dbbuff, sizeof(dbbuff));
/* Check if this is a temporary table name. Allow it if a corresponding .frm file exists */
if (is_prefix(table_name, tmp_file_prefix) && strlen(table_name) < NAME_CHAR_LEN &&
check_if_frm_exists(tbbuff, dbbuff, table_name))
flags|= FN_IS_TMP;
if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
strmake(tbbuff, table_name, sizeof(tbbuff)-1); strmake(tbbuff, table_name, sizeof(tbbuff)-1);
else else
(void) tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)); (void) tablename_to_filename(table_name, tbbuff, sizeof(tbbuff));
(void) tablename_to_filename(db, dbbuff, sizeof(dbbuff));
char *end = buff + bufflen; char *end = buff + bufflen;
/* Don't add FN_ROOTDIR if mysql_data_home already includes it */ /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
char *pos = strnmov(buff, mysql_data_home, bufflen); char *pos = strnmov(buff, mysql_data_home, bufflen);
......
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