summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2021-05-16 13:45:54 +0300
committerSergei Golubchik <serg@mariadb.org>2021-05-19 22:54:13 +0200
commitad02d53a715b9aeb7637f6a2c3685b094b15fa6b (patch)
tree2ba2be863377a5ce74aa91fdb121b5ddf5143e5f
parent7762ee5dbec5c336628c06bbe950837257276e57 (diff)
downloadmariadb-git-ad02d53a715b9aeb7637f6a2c3685b094b15fa6b.tar.gz
Create a backup file of ddl_recovery.log before starting recovery
This is done by prefixing -backup.log to the --log-ddl-recovery file. The reason for this is to have a copy of the original ddl log file if ddl recovery does not succeed.
-rw-r--r--sql/ddl_log.cc67
1 files changed, 52 insertions, 15 deletions
diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc
index 93ebc92b421..8b2813327df 100644
--- a/sql/ddl_log.cc
+++ b/sql/ddl_log.cc
@@ -115,7 +115,7 @@ struct st_global_ddl_log
uint name_pos;
uint io_size;
bool initialized;
- bool open;
+ bool open, backup_done, created;
};
/*
@@ -174,8 +174,10 @@ mysql_mutex_t LOCK_gdl;
/* Header is stored in positions 0-3 */
#define DDL_LOG_IO_SIZE_POS 4
#define DDL_LOG_NAME_OFFSET_POS 6
+/* Marks if we have done a backup of the ddl log */
+#define DDL_LOG_BACKUP_OFFSET_POS 8
/* Sum of the above variables */
-#define DDL_LOG_HEADER_SIZE 4+2+2
+#define DDL_LOG_HEADER_SIZE 4+2+2+1
/**
Sync the ddl log file.
@@ -207,9 +209,10 @@ static bool ddl_log_sync_no_lock()
@param file_name Filename setup
*/
-static inline void create_ddl_log_file_name(char *file_name)
+static inline void create_ddl_log_file_name(char *file_name, bool backup)
{
- fn_format(file_name, opt_ddl_recovery_file, mysql_data_home, ".log", 0);
+ fn_format(file_name, opt_ddl_recovery_file, mysql_data_home,
+ backup ? "-backup.log" : ".log", MYF(MY_REPLACE_EXT));
}
@@ -229,6 +232,7 @@ static bool write_ddl_log_header()
memcpy(&header, ddl_log_file_magic, DDL_LOG_MAGIC_LENGTH);
int2store(&header[DDL_LOG_IO_SIZE_POS], global_ddl_log.io_size);
int2store(&header[DDL_LOG_NAME_OFFSET_POS], global_ddl_log.name_pos);
+ header[DDL_LOG_BACKUP_OFFSET_POS]= 0;
if (mysql_file_pwrite(global_ddl_log.file_id,
header, sizeof(header), 0,
@@ -238,6 +242,33 @@ static bool write_ddl_log_header()
}
+/*
+ Mark in the ddl log file that we have made a backup of it
+*/
+
+static void mark_ddl_log_header_backup_done()
+{
+ uchar marker[1];
+ marker[0]= 1;
+ (void) mysql_file_pwrite(global_ddl_log.file_id,
+ marker, sizeof(marker), DDL_LOG_BACKUP_OFFSET_POS,
+ MYF(MY_WME | MY_NABP));
+}
+
+
+void ddl_log_create_backup_file()
+{
+ char org_file_name[FN_REFLEN];
+ char backup_file_name[FN_REFLEN];
+
+ create_ddl_log_file_name(org_file_name, 0);
+ create_ddl_log_file_name(backup_file_name, 1);
+
+ my_copy(org_file_name, backup_file_name, MYF(MY_WME));
+ mark_ddl_log_header_backup_done();
+}
+
+
/**
Read one entry from ddl log file.
@@ -452,8 +483,8 @@ static int read_ddl_log_header(const char *file_name)
DBUG_ENTER("read_ddl_log_header");
if ((file_id= mysql_file_open(key_file_global_ddl_log,
- file_name,
- O_RDWR | O_BINARY, MYF(0))) < 0)
+ file_name,
+ O_RDWR | O_BINARY, MYF(0))) < 0)
DBUG_RETURN(-1);
if (mysql_file_read(file_id,
@@ -476,6 +507,7 @@ static int read_ddl_log_header(const char *file_name)
io_size= uint2korr(&header[DDL_LOG_IO_SIZE_POS]);
global_ddl_log.name_pos= uint2korr(&header[DDL_LOG_NAME_OFFSET_POS]);
+ global_ddl_log.backup_done= header[DDL_LOG_BACKUP_OFFSET_POS];
max_entry= (uint) (mysql_file_seek(file_id, 0L, MY_SEEK_END, MYF(0)) /
io_size);
@@ -488,6 +520,7 @@ static int read_ddl_log_header(const char *file_name)
goto err;
global_ddl_log.open= TRUE;
+ global_ddl_log.created= 0;
global_ddl_log.file_id= file_id;
global_ddl_log.num_entries= max_entry;
global_ddl_log.io_size= io_size;
@@ -697,8 +730,11 @@ static bool create_ddl_log()
DBUG_ENTER("create_ddl_log");
global_ddl_log.open= 0;
+ global_ddl_log.created= 1;
global_ddl_log.num_entries= 0;
global_ddl_log.name_pos= DDL_LOG_TMP_NAME_POS;
+ global_ddl_log.num_entries= 0;
+ global_ddl_log.backup_done= 0;
/*
Fix file_entry_buf if the old log had a different io_size or if open of old
@@ -708,19 +744,19 @@ static bool create_ddl_log()
{
uchar *ptr= (uchar*)
my_realloc(key_memory_DDL_LOG_MEMORY_ENTRY,
- global_ddl_log.file_entry_buf, IO_SIZE,
+ global_ddl_log.file_entry_buf, DDL_LOG_IO_SIZE,
MYF(MY_WME | MY_ALLOW_ZERO_PTR));
if (ptr) // Resize succeded */
{
global_ddl_log.file_entry_buf= ptr;
- global_ddl_log.io_size= IO_SIZE;
+ global_ddl_log.io_size= DDL_LOG_IO_SIZE;
}
if (!global_ddl_log.file_entry_buf)
DBUG_RETURN(TRUE);
}
DBUG_ASSERT(global_ddl_log.file_entry_buf);
bzero(global_ddl_log.file_entry_buf, global_ddl_log.io_size);
- create_ddl_log_file_name(file_name);
+ create_ddl_log_file_name(file_name, 0);
if ((global_ddl_log.file_id=
mysql_file_create(key_file_global_ddl_log,
file_name, CREATE_MODE,
@@ -747,11 +783,11 @@ static bool create_ddl_log()
/**
Open ddl log and initialise ddl log variables
+ Create a backuip of of
*/
bool ddl_log_initialize()
{
- int num_entries;
char file_name[FN_REFLEN];
DBUG_ENTER("ddl_log_initialize");
@@ -761,15 +797,13 @@ bool ddl_log_initialize()
mysql_mutex_init(key_LOCK_gdl, &LOCK_gdl, MY_MUTEX_INIT_SLOW);
- create_ddl_log_file_name(file_name);
- if (likely((num_entries= read_ddl_log_header(file_name)) < 0))
+ create_ddl_log_file_name(file_name, 0);
+ if (unlikely(read_ddl_log_header(file_name) < 0))
{
/* Fatal error, log not opened. Recreate it */
if (create_ddl_log())
DBUG_RETURN(1);
}
- else
- global_ddl_log.num_entries= (uint) num_entries;
DBUG_RETURN(0);
}
@@ -2669,6 +2703,9 @@ int ddl_log_execute_recovery()
static char recover_query_string[]= "INTERNAL DDL LOG RECOVER IN PROGRESS";
DBUG_ENTER("ddl_log_execute_recovery");
+ if (!global_ddl_log.backup_done && !global_ddl_log.created)
+ ddl_log_create_backup_file();
+
if (global_ddl_log.num_entries == 0)
DBUG_RETURN(0);
@@ -2794,7 +2831,7 @@ void ddl_log_release()
global_ddl_log.file_entry_buf= 0;
close_ddl_log();
- create_ddl_log_file_name(file_name);
+ create_ddl_log_file_name(file_name, 0);
(void) mysql_file_delete(key_file_global_ddl_log, file_name, MYF(0));
mysql_mutex_destroy(&LOCK_gdl);
DBUG_VOID_RETURN;