Commit 5f3c0a45 authored by Aditya A's avatar Aditya A

Bug#13548704 ALGORITHM USED FOR DROPPING PARTITIONED TABLE CAN LEAD

             TO INCONSISTENCY 

PROBLEM
--------
When we drop a partitoned table , we first gather the
information about partitions in the table from the 
table_name.par file and store it in an internal data 
structure.Then we delete this file and the data in 
the table. If the server crashes  after deleting the
file,then after recovering we cannot access the table
.Even we cannot drop the table ,because drop algorithm
requires par file to read the partition information.


FIX
---
1. We move the part of deleting par file after deleting 
   all the table data from the storage egine.
2. During drop operation if we detect that the par 
   file is missing then we delete the .frm file,since 
   there is no way of recovering without par file.
  
[Approved by Mattias rb#2576 ]   
parent 8325f2cf
...@@ -662,8 +662,8 @@ test.t1 check Error Incorrect information in file: './test/t1.frm' ...@@ -662,8 +662,8 @@ test.t1 check Error Incorrect information in file: './test/t1.frm'
test.t1 check error Corrupt test.t1 check error Corrupt
SELECT * FROM t1; SELECT * FROM t1;
ERROR HY000: Failed to read from the .par file ERROR HY000: Failed to read from the .par file
# Note that it is currently impossible to drop a partitioned table # Note that we will remove the frm file when we detect that
# without the .par file # .par file has been deleted.
DROP TABLE t1; DROP TABLE t1;
ERROR 42S02: Unknown table 't1' ERROR 42S02: Unknown table 't1'
# #
......
...@@ -698,11 +698,10 @@ FLUSH TABLES; ...@@ -698,11 +698,10 @@ FLUSH TABLES;
CHECK TABLE t1; CHECK TABLE t1;
--error ER_UNKNOWN_ERROR --error ER_UNKNOWN_ERROR
SELECT * FROM t1; SELECT * FROM t1;
--echo # Note that it is currently impossible to drop a partitioned table --echo # Note that we will remove the frm file when we detect that
--echo # without the .par file --echo # .par file has been deleted.
--error ER_BAD_TABLE_ERROR --error ER_BAD_TABLE_ERROR
DROP TABLE t1; DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.frm
--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI --remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI
--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYD --remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYD
......
...@@ -1864,15 +1864,15 @@ char *ha_partition::update_table_comment(const char *comment) ...@@ -1864,15 +1864,15 @@ char *ha_partition::update_table_comment(const char *comment)
names of the partitions and the underlying storage engines. names of the partitions and the underlying storage engines.
*/ */
uint ha_partition::del_ren_cre_table(const char *from, int ha_partition::del_ren_cre_table(const char *from,
const char *to, const char *to,
TABLE *table_arg, TABLE *table_arg,
HA_CREATE_INFO *create_info) HA_CREATE_INFO *create_info)
{ {
int save_error= 0; int save_error= 0;
int error; int error= HA_ERR_INTERNAL_ERROR;
char from_buff[FN_REFLEN], to_buff[FN_REFLEN], from_lc_buff[FN_REFLEN], char from_buff[FN_REFLEN], to_buff[FN_REFLEN], from_lc_buff[FN_REFLEN],
to_lc_buff[FN_REFLEN]; to_lc_buff[FN_REFLEN], buff[FN_REFLEN];
char *name_buffer_ptr; char *name_buffer_ptr;
const char *from_path; const char *from_path;
const char *to_path= NULL; const char *to_path= NULL;
...@@ -1884,24 +1884,28 @@ uint ha_partition::del_ren_cre_table(const char *from, ...@@ -1884,24 +1884,28 @@ uint ha_partition::del_ren_cre_table(const char *from,
if (create_info && create_info->options & HA_LEX_CREATE_TMP_TABLE) if (create_info && create_info->options & HA_LEX_CREATE_TMP_TABLE)
{ {
my_error(ER_PARTITION_NO_TEMPORARY, MYF(0)); my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(error);
}
fn_format(buff,from, "", ha_par_ext, MY_APPEND_EXT);
/* Check if the par file exists */
if (my_access(buff,F_OK))
{
/*
If the .par file does not exist, return HA_ERR_NO_SUCH_TABLE,
This will signal to the caller that it can remove the .frm
file.
*/
error= HA_ERR_NO_SUCH_TABLE;
DBUG_RETURN(error);
} }
if (get_from_handler_file(from, ha_thd()->mem_root, false)) if (get_from_handler_file(from, ha_thd()->mem_root, false))
DBUG_RETURN(TRUE); DBUG_RETURN(error);
DBUG_ASSERT(m_file_buffer); DBUG_ASSERT(m_file_buffer);
DBUG_PRINT("enter", ("from: (%s) to: (%s)", from, to)); DBUG_PRINT("enter", ("from: (%s) to: (%s)", from, to));
name_buffer_ptr= m_name_buffer_ptr; name_buffer_ptr= m_name_buffer_ptr;
file= m_file; file= m_file;
if (to == NULL && table_arg == NULL)
{
/*
Delete table, start by delete the .par file. If error, break, otherwise
delete as much as possible.
*/
if ((error= handler::delete_table(from)))
DBUG_RETURN(error);
}
/* /*
Since ha_partition has HA_FILE_BASED, it must alter underlying table names Since ha_partition has HA_FILE_BASED, it must alter underlying table names
if they do not have HA_FILE_BASED and lower_case_table_names == 2. if they do not have HA_FILE_BASED and lower_case_table_names == 2.
...@@ -1940,6 +1944,18 @@ uint ha_partition::del_ren_cre_table(const char *from, ...@@ -1940,6 +1944,18 @@ uint ha_partition::del_ren_cre_table(const char *from,
save_error= error; save_error= error;
i++; i++;
} while (*(++file)); } while (*(++file));
if (to == NULL && table_arg == NULL)
{
DBUG_EXECUTE_IF("crash_before_deleting_par_file", DBUG_SUICIDE(););
/* Delete the .par file. If error, break.*/
if ((error= handler::delete_table(from)))
DBUG_RETURN(error);
DBUG_EXECUTE_IF("crash_after_deleting_par_file", DBUG_SUICIDE(););
}
if (to != NULL) if (to != NULL)
{ {
if ((error= handler::rename_table(from, to))) if ((error= handler::rename_table(from, to)))
......
...@@ -285,7 +285,7 @@ class ha_partition :public handler ...@@ -285,7 +285,7 @@ class ha_partition :public handler
delete_table, rename_table and create uses very similar logic which delete_table, rename_table and create uses very similar logic which
is packed into this routine. is packed into this routine.
*/ */
uint del_ren_cre_table(const char *from, const char *to, int del_ren_cre_table(const char *from, const char *to,
TABLE *table_arg, HA_CREATE_INFO *create_info); TABLE *table_arg, HA_CREATE_INFO *create_info);
/* /*
One method to create the table_name.par file containing the names of the One method to create the table_name.par file containing the names of the
......
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