diff options
author | Anurag Shekhar <anurag.shekhar@sun.com> | 2009-07-24 15:41:23 +0530 |
---|---|---|
committer | Anurag Shekhar <anurag.shekhar@sun.com> | 2009-07-24 15:41:23 +0530 |
commit | 0498988b48b0318a6e7e651b1a948967de201eb9 (patch) | |
tree | d15db783325396e0044e82006c84980650316051 /sql/ha_partition.cc | |
parent | c6771e7bde520228caa44233e36974a27d862a22 (diff) | |
download | mariadb-git-0498988b48b0318a6e7e651b1a948967de201eb9.tar.gz |
Bug#30102: Rename table does corrupt tables with partition files on failure
Problem was that a failing rename just left the partitions at the state
it was at the failure.
Solution was to try to revert the started rename if a failure occured.
mysql-test/r/partition_not_embedded.result:
Bug#30102: Rename table does corrupt tables with partition files on failure
New result file
mysql-test/t/partition_not_embedded.test:
Bug#30102: Rename table does corrupt tables with partition files on failure
New test file
(list_files does not report the files in embedded)
sql/ha_partition.cc:
Bug#30102: Rename table does corrupt tables with partition files on failure
Better error handling for rename partitions (reverting the started rename
operation)
Different order of files for delete.
sql/handler.cc:
Bug#30102: Rename table does corrupt tables with partition files on failure
Tries to remove as many table files as possible
if the first delete succeeds.
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r-- | sql/ha_partition.cc | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 74742f58028..06fb9e32e35 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -423,12 +423,9 @@ bool ha_partition::initialize_partition(MEM_ROOT *mem_root) int ha_partition::delete_table(const char *name) { - int error; DBUG_ENTER("ha_partition::delete_table"); - if ((error= del_ren_cre_table(name, NULL, NULL, NULL))) - DBUG_RETURN(error); - DBUG_RETURN(handler::delete_table(name)); + DBUG_RETURN(del_ren_cre_table(name, NULL, NULL, NULL)); } @@ -456,12 +453,9 @@ int ha_partition::delete_table(const char *name) int ha_partition::rename_table(const char *from, const char *to) { - int error; DBUG_ENTER("ha_partition::rename_table"); - if ((error= del_ren_cre_table(from, to, NULL, NULL))) - DBUG_RETURN(error); - DBUG_RETURN(handler::rename_table(from, to)); + DBUG_RETURN(del_ren_cre_table(from, to, NULL, NULL)); } @@ -1807,6 +1801,15 @@ uint ha_partition::del_ren_cre_table(const char *from, 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. @@ -1828,6 +1831,8 @@ uint ha_partition::del_ren_cre_table(const char *from, create_partition_name(to_buff, to_path, name_buffer_ptr, NORMAL_PART_NAME, FALSE); error= (*file)->ha_rename_table(from_buff, to_buff); + if (error) + goto rename_error; } else if (table_arg == NULL) // delete branch error= (*file)->ha_delete_table(from_buff); @@ -1843,6 +1848,15 @@ uint ha_partition::del_ren_cre_table(const char *from, save_error= error; i++; } while (*(++file)); + if (to != NULL) + { + if ((error= handler::rename_table(from, to))) + { + /* Try to revert everything, ignore errors */ + (void) handler::rename_table(to, from); + goto rename_error; + } + } DBUG_RETURN(save_error); create_error: name_buffer_ptr= m_name_buffer_ptr; @@ -1850,7 +1864,21 @@ create_error: { create_partition_name(from_buff, from_path, name_buffer_ptr, NORMAL_PART_NAME, FALSE); - VOID((*file)->ha_delete_table((const char*) from_buff)); + (void) (*file)->ha_delete_table((const char*) from_buff); + name_buffer_ptr= strend(name_buffer_ptr) + 1; + } + DBUG_RETURN(error); +rename_error: + name_buffer_ptr= m_name_buffer_ptr; + for (abort_file= file, file= m_file; file < abort_file; file++) + { + /* Revert the rename, back from 'to' to the original 'from' */ + create_partition_name(from_buff, from_path, name_buffer_ptr, + NORMAL_PART_NAME, FALSE); + create_partition_name(to_buff, to_path, name_buffer_ptr, + NORMAL_PART_NAME, FALSE); + /* Ignore error here */ + (void) (*file)->ha_rename_table(to_buff, from_buff); name_buffer_ptr= strend(name_buffer_ptr) + 1; } DBUG_RETURN(error); |