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)
sync_dir= 0;
/* Ignore not found errors and wrong symlink errors */
if (my_errno != ENOENT && my_errno != HA_WRONG_CREATE_OPTION)
got_error= my_errno;;
got_error= my_errno;
}
else
{
......
......@@ -34,7 +34,7 @@
int maria_rename(const char *old_name, const char *new_name)
{
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
uint raid_type=0,raid_chunks=0;
#endif
......@@ -106,28 +106,37 @@ int maria_rename(const char *old_name, const char *new_name)
_ma_reset_state(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(to,new_name,"",MARIA_NAME_IEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
if (mysql_file_rename_with_symlink(key_file_kfile, from, to,
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(to,new_name,"",MARIA_NAME_DEXT,MY_UNPACK_FILENAME|MY_APPEND_EXT);
data_file_rename_error=
mysql_file_rename_with_symlink(key_file_dfile, from, to,
MYF(MY_WME | sync_dir));
if (data_file_rename_error)
if (mysql_file_rename_with_symlink(key_file_dfile, from, to,
MYF(MY_WME | sync_dir)))
data_file_rename_error= my_errno;
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
undo the rename of the index file.
Now we have a renamed index file and a non-renamed data file, try to
undo a successful rename of the index file.
*/
data_file_rename_error= my_errno;
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,
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));
mysql_file_rename_with_symlink(key_file_kfile, to, from,
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 @@
int mi_rename(const char *old_name, const char *new_name)
{
char from[FN_REFLEN],to[FN_REFLEN];
int save_errno= 0;
DBUG_ENTER("mi_rename");
#ifdef EXTRA_DEBUG
......@@ -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(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)))
DBUG_RETURN(my_errno);
save_errno= my_errno;
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);
DBUG_RETURN(mysql_file_rename_with_symlink(mi_key_file_dfile,
from, to,
MYF(MY_WME)) ? my_errno : 0);
if (mysql_file_rename_with_symlink(mi_key_file_dfile,
from, to,
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