From 78fa270f88605a92cb9b5cf5fb606d19d726caf1 Mon Sep 17 00:00:00 2001 From: Abhinav Sharma Date: Fri, 18 Nov 2016 11:27:49 -0800 Subject: [PATCH] Delete crash safe index file if index file exists Summary: Crash safe index file is created when any change is made to the index file. The index file is first copied over to the crash safe one and then stuff is added/removed from the crash safe index file. Finally, the old index file is deleted and crash safe index file is renamed to the index file. There might be a scenario where mysql crashes after stuff is changed in the crash safe file but before the old index file is deleted. In this case we should delete the crash safe index file at restart. If we don't delete it subsequent changes to the index file can corrupt it because it can be copied to the old crash safe file which already has some data in it. Closes https://github.com/facebook/mysql-5.6/pull/433 Reviewed By: santoshbanda Differential Revision: D4198274 Pulled By: abhinav04sharma fbshipit-source-id: a6f8993 --- sql/binlog.cc | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/sql/binlog.cc b/sql/binlog.cc index 2bc08426c237..e81649d797ca 100644 --- a/sql/binlog.cc +++ b/sql/binlog.cc @@ -2750,18 +2750,35 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, return TRUE; } - /* - We need move crash_safe_index_file to index_file if the index_file - does not exist and crash_safe_index_file exists when mysqld server - restarts. - */ - if (my_access(index_file_name, F_OK) && - !my_access(crash_safe_index_file_name, F_OK) && - my_rename(crash_safe_index_file_name, index_file_name, MYF(MY_WME))) + // case: crash_safe_index_file exists + if (!my_access(crash_safe_index_file_name, F_OK)) { - sql_print_error("MYSQL_BIN_LOG::open_index_file failed to " - "move crash_safe_index_file to index file."); - return TRUE; + /* + We need move crash_safe_index_file to index_file if the index_file + does not exist or delete it if the index_file exists when mysqld server + restarts. + */ + + // case: index_file does not exist + if (my_access(index_file_name, F_OK)) + { + if (my_rename(crash_safe_index_file_name, index_file_name, MYF(MY_WME))) + { + sql_print_error("MYSQL_BIN_LOG::open_index_file failed to " + "move crash_safe_index_file to index_file."); + return TRUE; + } + + } + else + { + if (my_delete(crash_safe_index_file_name, MYF(MY_WME))) + { + sql_print_error("MYSQL_BIN_LOG::open_index_file failed to " + "delete crash_safe_index_file."); + return TRUE; + } + } } if ((index_file_nr= mysql_file_open(m_key_file_log_index,