Commit 8a2901a7 authored by unknown's avatar unknown

write a magic string "MACF" (MAria Control File) at the start of the control file.

lsn8store, lsn8korr.


storage/maria/control_file.h:
  parameter changes name
parent 52191ea4
......@@ -9,11 +9,20 @@
/* Here is the implementation of this module */
/* should be sector size for atomic write operation */
#define STAT_FILE_FILENO_SIZE 4
#define STAT_FILE_FILEOFFSET_SIZE 4
#define STAT_FILE_LSN_SIZE (STAT_FILE_FILENO_SIZE + STAT_FILE_FILEOFFSET_SIZE)
#define STAT_FILE_MAX_SIZE (STAT_FILE_LSN_SIZE + STAT_FILE_FILENO_SIZE)
/*
a control file contains 3 objects: magic string, LSN of last checkpoint,
number of last log.
*/
/* total size should be < sector size for atomic write operation */
#define CONTROL_FILE_MAGIC_STRING "MACF"
#define CONTROL_FILE_MAGIC_STRING_OFFSET 0
#define CONTROL_FILE_MAGIC_STRING_SIZE sizeof(CONTROL_FILE_MAGIC_STRING)
#define CONTROL_FILE_LSN_OFFSET (CONTROL_FILE_MAGIC_STRING_OFFSET + CONTROL_FILE_MAGIC_STRING_SIZE)
#define CONTROL_FILE_LSN_SIZE (4+4)
#define CONTROL_FILE_FILENO_OFFSET (CONTROL_FILE_LSN_OFFSET + CONTROL_FILE_LSN_SIZE)
#define CONTROL_FILE_FILENO_SIZE 4
#define CONTROL_FILE_MAX_SIZE (CONTROL_FILE_FILENO_OFFSET + CONTROL_FILE_FILENO_SIZE)
LSN last_checkpoint_lsn_at_startup;
......@@ -26,6 +35,19 @@ uint32 last_logno_at_startup;
*/
static int control_file_fd;
static void lsn8store(char *buffer, LSN *lsn)
{
int4store(buffer, lsn->file_no);
int4store(buffer + CONTROL_FILE_FILENO_SIZE, lsn->rec_offset);
}
static LSN lsn8korr(char *buffer)
{
LSN tmp;
tmp.file_no= uint4korr(buffer);
tmp.rec_offset= uint4korr(buffer + CONTROL_FILE_FILENO_SIZE);
return tmp;
}
/*
Initialize control file subsystem
......@@ -43,10 +65,18 @@ static int control_file_fd;
*/
int control_file_create_or_open()
{
char buffer[STAT_FILE_MAX_SIZE];
char buffer[CONTROL_FILE_MAX_SIZE];
char name[FN_REFLEN];
MY_STAT stat_buff;
/*
If you change sizes in the #defines, you at least have to change the
"*store" and "*korr" calls in this file, and can even create backward
compatibility problems. Beware!
*/
DBUG_ASSERT(CONTROL_FILE_LSN_SIZE == (4+4));
DBUG_ASSERT(CONTROL_FILE_FILENO_SIZE == 4);
/* name is concatenation of Maria's home dir and "control" */
if (fn_format(name, "control", maria_data_root, "", MYF(MY_WME)) == NullS)
return 1;
......@@ -68,13 +98,13 @@ int control_file_create_or_open()
if (my_stat(name, &stat_buff, MYF(MY_WME)) == NULL)
return 1;
if (stat_buff.st_size < STAT_FILE_MAX_SIZE)
if (stat_buff.st_size < CONTROL_FILE_MAX_SIZE)
{
/*
File shorter than expected (either we just created it, or a previous run
crashed between creation and first write); do first write.
*/
char buffer[STAT_FILE_MAX_SIZE];
char buffer[CONTROL_FILE_MAX_SIZE];
/*
To be safer we should make sure that there are no logs or data/index
files around (indeed it could be that the control file alone was deleted
......@@ -87,67 +117,83 @@ int control_file_create_or_open()
directory of logs, finding the newest log, reading it to find last
checkpoint... Slow but can save your db.
*/
last_checkpoint_lsn_at_startup.file_no= CONTROL_FILE_IMPOSSIBLE_LOGNO;
last_checkpoint_lsn_at_startup.file_no= CONTROL_FILE_IMPOSSIBLE_FILENO;
last_checkpoint_lsn_at_startup.rec_offset= 0;
last_logno_at_startup= CONTROL_FILE_IMPOSSIBLE_LOGNO;
last_logno_at_startup= CONTROL_FILE_IMPOSSIBLE_FILENO;
/* init the file with these "undefined" values */
return control_file_write_and_force(last_checkpoint_lsn_at_startup,
last_logno_at_startup);
last_logno_at_startup,
CONTROL_FILE_WRITE_ALL);
}
/* Already existing file, read it */
if (my_read(control_file_fd, buffer, STAT_FILE_MAX_SIZE,
if (my_read(control_file_fd, buffer, CONTROL_FILE_MAX_SIZE,
MYF(MY_FNABP | MY_WME)))
return 1;
last_checkpoint_lsn_at_startup.file_no= uint4korr(buffer);
last_checkpoint_lsn_at_startup.rec_offset= uint4korr(buffer +
STAT_FILE_FILENO_SIZE);
last_logno_at_startup= uint4korr(buffer + STAT_FILE_LSN_SIZE);
if (memcmp(buffer + CONTROL_FILE_MAGIC_STRING_OFFSET,
CONTROL_FILE_MAGIC_STRING, CONTROL_FILE_MAGIC_STRING_SIZE))
return 1;
last_checkpoint_lsn_at_startup= lsn8korr(buffer + CONTROL_FILE_LSN_OFFSET);
last_logno_at_startup= uint4korr(buffer + CONTROL_FILE_FILENO_OFFSET);
return 0;
}
#define CONTROL_FILE_WRITE_ALL 0 /* write all 3 objects */
#define CONTROL_FILE_WRITE_ONLY_LSN 1
#define CONTROL_FILE_WRITE_ONLY_LOGNO 2
/*
Write information durably to the control file.
SYNOPSIS
control_file_write_and_force()
checkpoint_lsn LSN of checkpoint
checkpoint_lsn LSN of last checkpoint
log_no last log file number
args_to_write bitmap of 1 (write the LSN) and 2 (write the LOGNO)
objs_to_write what we should write
Called when we have created a new log (after syncing this log's creation)
and when we have written a checkpoint (after syncing this log record).
NOTE
We always want to do one single my_pwrite() here to be as atomic as
possible.
RETURN
0 - OK
1 - Error
*/
int control_file_write_and_force(LSN *checkpoint_lsn, uint32 log_no,
uint args_to_write)
uint objs_to_write)
{
char buffer[STAT_FILE_MAX_SIZE];
uint start= STAT_FILE_LSN_SIZE, end= STAT_FILE_LSN_SIZE;
/*
If LSN was specified...
rec_offset can't be 0 in real LSN, because all files have header page
*/
if ((args_to_write & 1) && checkpoint_lsn) /* write checkpoint LSN */
char buffer[CONTROL_FILE_MAX_SIZE];
uint start, size;
memcpy(buffer + CONTROL_FILE_MAGIC_STRING_OFFSET,
CONTROL_FILE_MAGIC_STRING, CONTROL_FILE_MAGIC_STRING_SIZE);
/* write checkpoint LSN */
if (checkpoint_lsn)
lsn8store(buffer + CONTROL_FILE_LSN_OFFSET, checkpoint_lsn);
/* write logno */
int4store(buffer + CONTROL_FILE_FILENO_OFFSET, log_no);
if (objs_to_write == CONTROL_FILE_WRITE_ALL)
{
start= CONTROL_FILE_MAGIC_STRING_OFFSET;
size= CONTROL_FILE_MAX_SIZE;
}
else if (objs_to_write == CONTROL_FILE_WRITE_ONLY_LSN)
{
start= 0;
int4store(buffer, checkpoint_lsn->file_no);
int4store(buffer + STAT_FILE_FILENO_SIZE, checkpoint_lsn->rec_offset);
start= CONTROL_FILE_LSN_OFFSET;
size= CONTROL_FILE_LSN_SIZE;
}
if (args_to_write & 2) /* write logno */
else if (objs_to_write == CONTROL_FILE_WRITE_ONLY_LOGNO)
{
end= STAT_FILE_MAX_SIZE;
int4store(buffer + STAT_FILE_LSN_SIZE, log_no);
start= CONTROL_FILE_FILENO_OFFSET;
size= CONTROL_FILE_FILENO_SIZE;
}
DBUG_ASSERT(start != end);
return (my_pwrite(control_file_fd, buffer + start, end - start, start,
MYF(MY_FNABP | MY_WME)) ||
else /* incorrect value of objs_to_write */
DBUG_ASSERT(0);
return (my_pwrite(control_file_fd, buffer + start, size,
start, MYF(MY_FNABP | MY_WME)) ||
my_sync(control_file_fd, MYF(MY_WME)));
}
......
......@@ -37,7 +37,7 @@ int control_file_create_or_open();
and when we have written a checkpoint (after syncing this log record).
*/
int control_file_write_and_force(LSN *checkpoint_lsn, uint32 log_no,
uint args_to_write);
uint objs_to_write);
/* Free resources taken by control file subsystem */
......
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