Commit 55c771b4 authored by Monty's avatar Monty Committed by Sergei Golubchik

Make rename atomic/repeatable in MyISAM and Aria

This is required to make Atomic RENAME TABLE work for these engines

The requirement is that if we have a server crash in the middle of a
storage engine rename call, the upcoming ddl log recovery should be able
to finalize it by re-execute the rename.
parent 5e7b1bad
...@@ -48,7 +48,7 @@ int maria_delete_table(const char *name) ...@@ -48,7 +48,7 @@ int maria_delete_table(const char *name)
sync_dir= 0; sync_dir= 0;
/* Ignore not found errors and wrong symlink errors */ /* Ignore not found errors and wrong symlink errors */
if (my_errno != ENOENT && my_errno != HA_WRONG_CREATE_OPTION) if (my_errno != ENOENT && my_errno != HA_WRONG_CREATE_OPTION)
got_error= my_errno;; got_error= my_errno;
} }
else else
{ {
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
int maria_rename(const char *old_name, const char *new_name) int maria_rename(const char *old_name, const char *new_name)
{ {
char from[FN_REFLEN],to[FN_REFLEN]; char from[FN_REFLEN],to[FN_REFLEN];
int data_file_rename_error; int data_file_rename_error= 0, index_file_rename_error= 0;
#ifdef USE_RAID #ifdef USE_RAID
uint raid_type=0,raid_chunks=0; uint raid_type=0,raid_chunks=0;
#endif #endif
...@@ -106,28 +106,37 @@ int maria_rename(const char *old_name, const char *new_name) ...@@ -106,28 +106,37 @@ int maria_rename(const char *old_name, const char *new_name)
_ma_reset_state(info); _ma_reset_state(info);
maria_close(info); maria_close(info);
/*
This code is written so that it should be possible to re-run a
failed rename (even if there is a server crash in between the
renames) and complete it.
*/
fn_format(from,old_name,"",MARIA_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(from,old_name,"",MARIA_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
fn_format(to,new_name,"",MARIA_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(to,new_name,"",MARIA_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
if (mysql_file_rename_with_symlink(key_file_kfile, from, to, if (mysql_file_rename_with_symlink(key_file_kfile, from, to,
MYF(MY_WME | sync_dir))) MYF(MY_WME | sync_dir)))
DBUG_RETURN(my_errno); index_file_rename_error= my_errno;
fn_format(from,old_name,"",MARIA_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(from,old_name,"",MARIA_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
fn_format(to,new_name,"",MARIA_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(to,new_name,"",MARIA_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
data_file_rename_error= if (mysql_file_rename_with_symlink(key_file_dfile, from, to,
mysql_file_rename_with_symlink(key_file_dfile, from, to, MYF(MY_WME | sync_dir)))
MYF(MY_WME | sync_dir)); data_file_rename_error= my_errno;
if (data_file_rename_error) if (data_file_rename_error && data_file_rename_error != ENOENT)
{ {
/* /*
now we have a renamed index file and a non-renamed data file, try to Now we have a renamed index file and a non-renamed data file, try to
undo the rename of the index file. undo a successful rename of the index file.
*/ */
data_file_rename_error= my_errno; if (!index_file_rename_error)
fn_format(from, old_name, "", MARIA_NAME_IEXT, MYF(MY_UNPACK_FILENAME|MY_APPEND_EXT)); {
fn_format(to, new_name, "", MARIA_NAME_IEXT, MYF(MY_UNPACK_FILENAME|MY_APPEND_EXT)); fn_format(from, old_name, "", MARIA_NAME_IEXT,
MYF(MY_UNPACK_FILENAME|MY_APPEND_EXT));
fn_format(to, new_name, "", MARIA_NAME_IEXT,
MYF(MY_UNPACK_FILENAME|MY_APPEND_EXT));
mysql_file_rename_with_symlink(key_file_kfile, to, from, mysql_file_rename_with_symlink(key_file_kfile, to, from,
MYF(MY_WME | sync_dir)); MYF(MY_WME | sync_dir));
} }
DBUG_RETURN(data_file_rename_error); }
DBUG_RETURN(data_file_rename_error ? data_file_rename_error:
index_file_rename_error);
} }
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
int mi_rename(const char *old_name, const char *new_name) int mi_rename(const char *old_name, const char *new_name)
{ {
char from[FN_REFLEN],to[FN_REFLEN]; char from[FN_REFLEN],to[FN_REFLEN];
int save_errno= 0;
DBUG_ENTER("mi_rename"); DBUG_ENTER("mi_rename");
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
...@@ -32,10 +33,13 @@ int mi_rename(const char *old_name, const char *new_name) ...@@ -32,10 +33,13 @@ int mi_rename(const char *old_name, const char *new_name)
fn_format(from,old_name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(from,old_name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
fn_format(to,new_name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(to,new_name,"",MI_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
if (mysql_file_rename_with_symlink(mi_key_file_kfile, from, to, MYF(MY_WME))) if (mysql_file_rename_with_symlink(mi_key_file_kfile, from, to, MYF(MY_WME)))
DBUG_RETURN(my_errno); save_errno= my_errno;
fn_format(from,old_name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(from,old_name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
fn_format(to,new_name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT); fn_format(to,new_name,"",MI_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
DBUG_RETURN(mysql_file_rename_with_symlink(mi_key_file_dfile, if (mysql_file_rename_with_symlink(mi_key_file_dfile,
from, to, from, to,
MYF(MY_WME)) ? my_errno : 0); MYF(MY_WME)))
if (save_errno)
save_errno= my_errno;
DBUG_RETURN(save_errno);
} }
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