summaryrefslogtreecommitdiff
path: root/sql/ha_partition.cc
diff options
context:
space:
mode:
authorAditya A <aditya.a@oracle.com>2013-06-14 11:22:05 +0530
committerAditya A <aditya.a@oracle.com>2013-06-14 11:22:05 +0530
commit5f3c0a451d4516041ca7800047055e93085c8b94 (patch)
tree389499896bca3d23e5cce2260fc647e068a471de /sql/ha_partition.cc
parent8325f2cf7802574dc10d005dd9a84b795aafc0d8 (diff)
downloadmariadb-git-5f3c0a451d4516041ca7800047055e93085c8b94.tar.gz
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 ]
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r--sql/ha_partition.cc44
1 files changed, 30 insertions, 14 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 69cf5f74df6..778725c88cf 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1864,15 +1864,15 @@ char *ha_partition::update_table_comment(const char *comment)
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,
TABLE *table_arg,
HA_CREATE_INFO *create_info)
{
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],
- to_lc_buff[FN_REFLEN];
+ to_lc_buff[FN_REFLEN], buff[FN_REFLEN];
char *name_buffer_ptr;
const char *from_path;
const char *to_path= NULL;
@@ -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)
{
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))
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(error);
DBUG_ASSERT(m_file_buffer);
DBUG_PRINT("enter", ("from: (%s) to: (%s)", from, to));
name_buffer_ptr= m_name_buffer_ptr;
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
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,
save_error= error;
i++;
} 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 ((error= handler::rename_table(from, to)))