mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
WL 2826: Step 11
Lots of new code for table log
This commit is contained in:

parent
83890afeb2
commit
5091f3a8a5
@ -559,7 +559,7 @@ extern File my_register_filename(File fd, const char *FileName,
|
||||
enum file_type type_of_file,
|
||||
uint error_message_number, myf MyFlags);
|
||||
extern File my_create(const char *FileName,int CreateFlags,
|
||||
int AccsesFlags, myf MyFlags);
|
||||
int AccessFlags, myf MyFlags);
|
||||
extern int my_close(File Filedes,myf MyFlags);
|
||||
extern File my_dup(File file, myf MyFlags);
|
||||
extern int my_mkdir(const char *dir, int Flags, myf MyFlags);
|
||||
|
@ -1163,7 +1163,9 @@ typedef struct st_table_log_entry
|
||||
const char *name;
|
||||
const char *from_name;
|
||||
const char *handler_type;
|
||||
uint next_entry;
|
||||
char action_type;
|
||||
char entry_type;
|
||||
} TABLE_LOG_ENTRY;
|
||||
|
||||
|
||||
@ -1175,6 +1177,11 @@ uint read_table_log_header();
|
||||
bool read_table_log_entry(uint read_entry, TABLE_LOG_ENTRY *table_log_entry);
|
||||
bool init_table_log();
|
||||
void release_table_log();
|
||||
void execute_table_log_recovery();
|
||||
bool execute_table_log_entry(uint first_entry);
|
||||
bool execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry);
|
||||
void lock_global_table_log();
|
||||
void unlock_global_table_log();
|
||||
|
||||
bool write_log_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt, bool install_flag);
|
||||
bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt);
|
||||
|
@ -5083,6 +5083,9 @@ bool
|
||||
write_log_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt, bool install_frm)
|
||||
{
|
||||
DBUG_ENTER("write_log_shadow_frm");
|
||||
|
||||
lock_global_table_log();
|
||||
unlock_global_table_log();
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
@ -5106,6 +5109,9 @@ bool
|
||||
write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
{
|
||||
DBUG_ENTER("write_log_drop_partition");
|
||||
|
||||
lock_global_table_log();
|
||||
unlock_global_table_log();
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
@ -5129,6 +5135,9 @@ bool
|
||||
write_log_add_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
{
|
||||
DBUG_ENTER("write_log_add_partition");
|
||||
|
||||
lock_global_table_log();
|
||||
unlock_global_table_log();
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
@ -5152,6 +5161,9 @@ bool
|
||||
write_log_ph1_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
{
|
||||
DBUG_ENTER("write_log_ph1_change_partition");
|
||||
|
||||
lock_global_table_log();
|
||||
unlock_global_table_log();
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
@ -5176,6 +5188,9 @@ bool
|
||||
write_log_ph2_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
{
|
||||
DBUG_ENTER("write_log_ph2_change_partition");
|
||||
|
||||
lock_global_table_log();
|
||||
unlock_global_table_log();
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
@ -5195,6 +5210,9 @@ bool
|
||||
write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt)
|
||||
{
|
||||
DBUG_ENTER("write_log_ph2_change_partition");
|
||||
|
||||
lock_global_table_log();
|
||||
unlock_global_table_log();
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
225
sql/sql_table.cc
225
sql/sql_table.cc
@ -244,6 +244,52 @@ static int mysql_copy_key_list(List<Key> *orig_key,
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
MODULE: Table log
|
||||
-----------------
|
||||
|
||||
This module is used to ensure that we can recover from crashes that occur
|
||||
in the middle of a meta-data operation in MySQL. E.g. DROP TABLE t1, t2;
|
||||
We need to ensure that both t1 and t2 are dropped and not only t1 and
|
||||
also that each table drop is entirely done and not "half-baked".
|
||||
|
||||
To support this we create log entries for each meta-data statement in the
|
||||
table log while we are executing. These entries are dropped when the
|
||||
operation is completed.
|
||||
|
||||
At recovery those entries that were not completed will be executed.
|
||||
|
||||
There is only one table log in the system and it is protected by a mutex
|
||||
and there is a global struct that contains information about its current
|
||||
state.
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
typedef struct st_table_log_memory_entry
|
||||
{
|
||||
uint entry_pos;
|
||||
} TABLE_LOG_MEMORY_ENTRY;
|
||||
|
||||
typedef struct st_global_table_log
|
||||
{
|
||||
char file_entry[IO_SIZE];
|
||||
char file_name_str[FN_REFLEN];
|
||||
char *file_name;
|
||||
List<TABLE_LOG_MEMORY_ENTRY> free_entries;
|
||||
List<TABLE_LOG_MEMORY_ENTRY> log_entries;
|
||||
File file_id;
|
||||
uint name_len;
|
||||
uint handler_type_len;
|
||||
} GLOBAL_TABLE_LOG;
|
||||
|
||||
GLOBAL_TABLE_LOG global_table_log;
|
||||
|
||||
pthread_mutex_t LOCK_gtl;
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
@ -299,6 +345,31 @@ write_execute_table_log_entry(uint first_entry, uint *exec_entry)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Read one entry from table log file
|
||||
SYNOPSIS
|
||||
read_table_log_file_entry()
|
||||
file_id File identifier
|
||||
file_entry Memory area to read entry into
|
||||
entry_no Entry number to read
|
||||
RETURN VALUES
|
||||
TRUE Error
|
||||
FALSE Success
|
||||
*/
|
||||
|
||||
static
|
||||
bool
|
||||
read_table_log_file_entry(File file_id, byte *file_entry, uint entry_no)
|
||||
{
|
||||
bool error= FALSE;
|
||||
DBUG_ENTER("read_table_log_file_entry");
|
||||
|
||||
if (my_pread(file_id, file_entry, IO_SIZE, IO_SIZE * entry_no, MYF(0)))
|
||||
error= TRUE;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Read header of table log file
|
||||
SYNOPSIS
|
||||
@ -315,9 +386,21 @@ write_execute_table_log_entry(uint first_entry, uint *exec_entry)
|
||||
uint
|
||||
read_table_log_header()
|
||||
{
|
||||
char *file_entry= (char*)&global_table_log.file_entry;
|
||||
DBUG_ENTER("read_table_log_header");
|
||||
|
||||
if (read_table_log_file_entry(global_table_log.file_id,
|
||||
(char*)&file_entry, 0UL))
|
||||
{
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
entry_no= uint4korr(&file_entry[0]);
|
||||
global_table_log.name_len= uint2korr(&file_entry[4]);
|
||||
global_table_log.handler_type_len= uint2korr(&file_entry[6]);
|
||||
global_table_log.free_entries.clear();
|
||||
VOID(pthread_mutex_init(&LOCK_gtl, MY_MUTEX_INIT_FAST));
|
||||
DBUG_RETURN(entry_no);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@ -356,7 +439,17 @@ read_table_log_entry(uint read_entry, TABLE_LOG_ENTRY *table_log_entry)
|
||||
bool
|
||||
init_table_log()
|
||||
{
|
||||
uint no_entries= 0;
|
||||
uint16 const_var;
|
||||
DBUG_ENTER("init_table_log");
|
||||
VOID(my_delete(global_table_log.file_name));
|
||||
global_table_log.file_id= my_open(global_table_log.file_name,
|
||||
0, 0, MYF(0));
|
||||
int4store(&global_table_log.file_entry[0], &no_entries);
|
||||
const_var= NAMELEN;
|
||||
int2store(&global_table_log.file_entry[4], &const_var);
|
||||
const_var= 32;
|
||||
int2store(&global_table_log.file_entry[6], &const_var);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
@ -373,10 +466,142 @@ void
|
||||
release_table_log()
|
||||
{
|
||||
DBUG_ENTER("release_table_log");
|
||||
|
||||
VOID(pthread_mutex_destroy(&LOCK_gtl));
|
||||
DBUG_RETURN_VOID;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Lock mutex for global table log
|
||||
SYNOPSIS
|
||||
lock_global_table_log()
|
||||
RETURN VALUES
|
||||
NONE
|
||||
*/
|
||||
|
||||
void
|
||||
lock_global_table_log()
|
||||
{
|
||||
DBUG_ENTER("lock_global_table_log");
|
||||
|
||||
VOID(pthread_mutex_lock(&LOCK_gtl));
|
||||
DBUG_RETURN_VOID;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Unlock mutex for global table log
|
||||
SYNOPSIS
|
||||
unlock_global_table_log()
|
||||
RETURN VALUES
|
||||
NONE
|
||||
*/
|
||||
|
||||
void
|
||||
unlock_global_table_log()
|
||||
{
|
||||
DBUG_ENTER("unlock_global_table_log");
|
||||
|
||||
VOID(pthread_mutex_unlock(&LOCK_gtl));
|
||||
DBUG_RETURN_VOID;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Execute one action in a table log entry
|
||||
SYNOPSIS
|
||||
execute_table_log_action()
|
||||
table_log_entry Information in action entry to execute
|
||||
RETURN VALUES
|
||||
TRUE Error
|
||||
FALSE Success
|
||||
*/
|
||||
|
||||
bool
|
||||
execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry)
|
||||
{
|
||||
DBUG_ENTER("execute_table_log_action");
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Execute one entry in the table log. Executing an entry means executing
|
||||
a linked list of actions.
|
||||
SYNOPSIS
|
||||
execute_table_log_entry()
|
||||
first_entry Reference to first action in entry
|
||||
RETURN VALUES
|
||||
TRUE Error
|
||||
FALSE Success
|
||||
*/
|
||||
|
||||
bool
|
||||
execute_table_log_entry(uint first_entry)
|
||||
{
|
||||
TABLE_LOG_ENTRY table_log_entry;
|
||||
uint read_entry= first_entry;
|
||||
DBUG_ENTER("execute_table_log_entry");
|
||||
|
||||
do
|
||||
{
|
||||
read_table_log_entry(read_entry, &table_log_entry);
|
||||
DBUG_ASSERT(table_log_entry.entry_type == 'i');
|
||||
if (execute_table_log_action(&table_log_entry))
|
||||
{
|
||||
/* error handling */
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
read_entry= table_log_entry.next_entry;
|
||||
} while (read_entry);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Execute the table log at recovery of MySQL Server
|
||||
SYNOPSIS
|
||||
execute_table_log_recovery()
|
||||
RETURN VALUES
|
||||
NONE
|
||||
*/
|
||||
|
||||
void
|
||||
execute_table_log_recovery()
|
||||
{
|
||||
uint no_entries, i;
|
||||
TABLE_LOG_ENTRY table_log_entry;
|
||||
DBUG_ENTER("execute_table_log_recovery");
|
||||
|
||||
no_entries= read_log_header();
|
||||
for (i= 0; i < no_entries; i++)
|
||||
{
|
||||
read_table_log_entry(i, &table_log_entry);
|
||||
if (table_log_entry.entry_type == 'e')
|
||||
{
|
||||
if (execute_table_log_entry(table_log_entry.next_entry))
|
||||
{
|
||||
/* error handling */
|
||||
DBUG_RETURN_VOID;
|
||||
}
|
||||
}
|
||||
}
|
||||
init_table_log();
|
||||
DBUG_RETURN_VOID;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
END MODULE Table log
|
||||
--------------------
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
SYNOPSIS
|
||||
mysql_write_frm()
|
||||
|
Reference in New Issue
Block a user