Commit 910bf380 authored by unknown's avatar unknown

WL 2826: Error handling for ALTER TABLE for partitioning

Most of the code for handling the table log is in place now, except
the action part at recovery and proper error handling in some places.


sql/mysql_priv.h:
  Removed internal methods from external table log interface
  Added and changed interface
sql/mysqld.cc:
  Added call to execute table log recovery
sql/sql_table.cc:
  Most of the code for handling the table log is in place now, except
  the action part at recovery and proper error handling in some places.
parent e09fb5ce
...@@ -1168,21 +1168,24 @@ typedef struct st_table_log_entry ...@@ -1168,21 +1168,24 @@ typedef struct st_table_log_entry
char entry_type; char entry_type;
} TABLE_LOG_ENTRY; } TABLE_LOG_ENTRY;
typedef struct st_table_log_memory_entry
{
uint entry_pos;
TABLE_LOG_MEMORY *next_log_entry;
TABLE_LOG_MEMORY *prev_log_entry;
TABLE_LOG_MEMORY *next_active_log_entry;
} TABLE_LOG_MEMORY_ENTRY;
bool write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry, bool write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry,
uint next_entry, TABLE_LOG_MEMORY_ENTRY **active_entry);
uint *entry_written); bool write_execute_table_log_entry(uint first_entry,
bool write_execute_table_log_entry(uint first_entry, uint *exec_entry); TABLE_LOG_MEMORY_ENTRY **active_entry);
uint read_table_log_header(); void release_table_log_memory_entry(TABLE_LOG_MEMORY_ENTRY *log_entry);
bool read_table_log_entry(uint read_entry, TABLE_LOG_ENTRY *table_log_entry);
bool init_table_log();
void release_table_log(); void release_table_log();
void execute_table_log_recovery(); void execute_table_log_recovery();
bool execute_table_log_entry(uint first_entry); 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 lock_global_table_log();
void unlock_global_table_log(); void unlock_global_table_log();
bool sync_table_log();
bool write_log_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt, bool install_flag); bool write_log_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt, bool install_flag);
bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt); bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt);
......
...@@ -3676,7 +3676,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); ...@@ -3676,7 +3676,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
unireg_abort(1); unireg_abort(1);
} }
} }
execute_table_log_recovery();
init_events(); init_events();
create_shutdown_thread(); create_shutdown_thread();
......
...@@ -265,22 +265,19 @@ static int mysql_copy_key_list(List<Key> *orig_key, ...@@ -265,22 +265,19 @@ static int mysql_copy_key_list(List<Key> *orig_key,
and there is a global struct that contains information about its current and there is a global struct that contains information about its current
state. state.
History:
First version written in 2006 by Mikael Ronstrom
-------------------------------------------------------------------------- --------------------------------------------------------------------------
*/ */
typedef struct st_table_log_memory_entry
{
uint entry_pos;
} TABLE_LOG_MEMORY_ENTRY;
typedef struct st_global_table_log typedef struct st_global_table_log
{ {
char file_entry[IO_SIZE]; char file_entry[IO_SIZE];
char file_name_str[FN_REFLEN]; char file_name_str[FN_REFLEN];
char *file_name; char *file_name;
List<TABLE_LOG_MEMORY_ENTRY> free_entries; TABLE_LOG_MEMORY_ENTRY *first_free;
List<TABLE_LOG_MEMORY_ENTRY> log_entries; TABLE_LOG_MEMORY_ENTRY *first_used;
uint no_entries; uint no_entries;
File file_id; File file_id;
uint name_len; uint name_len;
...@@ -301,6 +298,7 @@ pthread_mutex_t LOCK_gtl; ...@@ -301,6 +298,7 @@ pthread_mutex_t LOCK_gtl;
FALSE Success FALSE Success
*/ */
static
bool bool
sync_table_log() sync_table_log()
{ {
...@@ -308,7 +306,10 @@ sync_table_log() ...@@ -308,7 +306,10 @@ sync_table_log()
DBUG_ENTER("sync_table_log"); DBUG_ENTER("sync_table_log");
if (my_sync(global_table_log.file_id, MYF(0))) if (my_sync(global_table_log.file_id, MYF(0)))
{
/* Write to error log */
error= TRUE; error= TRUE;
}
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -317,8 +318,6 @@ sync_table_log() ...@@ -317,8 +318,6 @@ sync_table_log()
Write one entry from table log file Write one entry from table log file
SYNOPSIS SYNOPSIS
write_table_log_file_entry() write_table_log_file_entry()
file_id File identifier
file_entry Memory area to read entry into
entry_no Entry number to read entry_no Entry number to read
RETURN VALUES RETURN VALUES
TRUE Error TRUE Error
...@@ -327,10 +326,12 @@ sync_table_log() ...@@ -327,10 +326,12 @@ sync_table_log()
static static
bool bool
write_table_log_file_entry(File file_id, byte *file_entry, uint entry_no) write_table_log_file_entry(uint entry_no)
{ {
bool error= FALSE; bool error= FALSE;
DBUG_ENTER("read_table_log_file_entry"); File file_id= global_table_log.file_id;
char *file_entry= (char*)global_table_log.file_entry;
DBUG_ENTER("write_table_log_file_entry");
if (my_pwrite(file_id, file_entry, IO_SIZE, IO_SIZE * entry_no, MYF(0))) if (my_pwrite(file_id, file_entry, IO_SIZE, IO_SIZE * entry_no, MYF(0)))
error= TRUE; error= TRUE;
...@@ -338,64 +339,6 @@ write_table_log_file_entry(File file_id, byte *file_entry, uint entry_no) ...@@ -338,64 +339,6 @@ write_table_log_file_entry(File file_id, byte *file_entry, uint entry_no)
} }
/*
SYNOPSIS
write_table_log_entry()
table_log_entry Information about log entry
out:entry_written Entry information written into
RETURN VALUES
TRUE Error
FALSE Success
DESCRIPTION
A careful write of the table log is performed to ensure that we can
handle crashes occurring during CREATE and ALTER TABLE processing.
*/
bool
write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry,
uint *entry_written)
{
bool write_header, error;
DBUG_ENTER("write_table_log_entry");
global_table_log.file_entry[0]= 'i';
global_table_log.file_entry[1]= table_log_entry->action_type;
int4store(&global_table_log.file_entry[2],
table_log_entry->next_entry);
strcpy(&global_table_log.file_entry[6], table_log_entry->name);
if (table_log_entry.action_type == 'r')
global_table_log.file_entry[6 + NAMELEN]= 0;
else
strcpy(&global_table_log.file_entry[6 + NAMELEN],
table_log_entry->from_name);
strcpy(&global_table_log.file_entry[6 + (2*NAMELEN)],
table_log_entry->handler_type);
if (global_table_log.free_entries.is_empty())
{
global_table_log.no_entries++;
entry_no= global_table_log.no_entries;
write_header= TRUE;
}
else
{
TABLE_LOG_MEMORY *tmp= global_table_log.free_entries.pop();
global_table_log.log_entries.push_back(tmp);
entry_no= tmp->entry_pos;
write_header= FALSE;
}
error= FALSE;
if (write_table_log_entry(global_table_log.file_id,
global_table_log.file_entry,
entry_no))
error= TRUE;
else if (write_header || !(write_table_log_header()))
error= TRUE;
DBUG_RETURN(error);
}
/* /*
Write table log header Write table log header
SYNOPSIS SYNOPSIS
...@@ -405,10 +348,12 @@ write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry, ...@@ -405,10 +348,12 @@ write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry,
FALSE Success FALSE Success
*/ */
static
bool bool
write_table_log_header() write_table_log_header()
{ {
uint16 const_var; uint16 const_var;
bool error= FALSE;
DBUG_ENTER("write_table_log_header"); DBUG_ENTER("write_table_log_header");
int4store(&global_table_log.file_entry[0], global_table_log.no_entries); int4store(&global_table_log.file_entry[0], global_table_log.no_entries);
...@@ -416,36 +361,9 @@ write_table_log_header() ...@@ -416,36 +361,9 @@ write_table_log_header()
int2store(&global_table_log.file_entry[4], const_var); int2store(&global_table_log.file_entry[4], const_var);
const_var= 32; const_var= 32;
int2store(&global_table_log.file_entry[6], const_var); int2store(&global_table_log.file_entry[6], const_var);
DBUG_RETURN(FALSE); if (write_table_log_file_entry(0UL))
} error= TRUE;
DBUG_RETURN(error);
/*
Write final entry in the table log
SYNOPSIS
write_execute_table_log_entry()
first_entry First entry in linked list of entries
to execute, if 0 = NULL it means that
the entry is removed and the entries
are put into the free list.
in:out:exec_entry Entry to execute, 0 = NULL if the entry
is written first time and needs to be
returned. In this case the entry written
is returned in this parameter
RETURN VALUES
TRUE Error
FALSE Success
DESCRIPTION
This is the last write in the table log. The previous log entries have
already been written but not yet synched to disk.
*/
bool
write_execute_table_log_entry(uint first_entry, uint *exec_entry)
{
DBUG_ENTER("write_execute_table_log_entry");
DBUG_RETURN(FALSE);
} }
...@@ -453,8 +371,6 @@ write_execute_table_log_entry(uint first_entry, uint *exec_entry) ...@@ -453,8 +371,6 @@ write_execute_table_log_entry(uint first_entry, uint *exec_entry)
Read one entry from table log file Read one entry from table log file
SYNOPSIS SYNOPSIS
read_table_log_file_entry() read_table_log_file_entry()
file_id File identifier
file_entry Memory area to read entry into
entry_no Entry number to read entry_no Entry number to read
RETURN VALUES RETURN VALUES
TRUE Error TRUE Error
...@@ -463,9 +379,11 @@ write_execute_table_log_entry(uint first_entry, uint *exec_entry) ...@@ -463,9 +379,11 @@ write_execute_table_log_entry(uint first_entry, uint *exec_entry)
static static
bool bool
read_table_log_file_entry(File file_id, byte *file_entry, uint entry_no) read_table_log_file_entry(uint entry_no)
{ {
bool error= FALSE; bool error= FALSE;
File file_id= global_table_log.file_id;
char *file_entry= (char*)global_table_log.file_entry;
DBUG_ENTER("read_table_log_file_entry"); DBUG_ENTER("read_table_log_file_entry");
if (my_pread(file_id, file_entry, IO_SIZE, IO_SIZE * entry_no, MYF(0))) if (my_pread(file_id, file_entry, IO_SIZE, IO_SIZE * entry_no, MYF(0)))
...@@ -474,6 +392,23 @@ read_table_log_file_entry(File file_id, byte *file_entry, uint entry_no) ...@@ -474,6 +392,23 @@ read_table_log_file_entry(File file_id, byte *file_entry, uint entry_no)
} }
/*
Create table log file name
SYNOPSIS
create_table_log_file_name()
file_name Filename setup
RETURN VALUES
NONE
*/
static
void
create_table_log_file_name(char *file_name)
{
strxmov(file_name, mysql_data_home, "/", "table_log.log", NullS);
}
/* /*
Read header of table log file Read header of table log file
SYNOPSIS SYNOPSIS
...@@ -487,22 +422,28 @@ read_table_log_file_entry(File file_id, byte *file_entry, uint entry_no) ...@@ -487,22 +422,28 @@ read_table_log_file_entry(File file_id, byte *file_entry, uint entry_no)
of entries in the table log. of entries in the table log.
*/ */
static
uint uint
read_table_log_header() read_table_log_header()
{ {
char *file_entry= (char*)&global_table_log.file_entry; char *file_entry= (char*)global_table_log.file_entry;
char file_name[FN_REFLEN];
DBUG_ENTER("read_table_log_header"); DBUG_ENTER("read_table_log_header");
if (read_table_log_file_entry(global_table_log.file_id, bzero(file_entry, sizeof(global_table_log.file_entry));
(char*)&file_entry, 0UL)) create_table_log_file_name(file_name);
if (!(my_open(file_name, O_RDWR |O_TRUNC, MYF(0))))
{ {
DBUG_RETURN(0); if (read_table_log_file_entry(0UL))
{
/* Write message into error log */
}
} }
entry_no= uint4korr(&file_entry[0]); entry_no= uint4korr(&file_entry[0]);
global_table_log.name_len= uint2korr(&file_entry[4]); global_table_log.name_len= uint2korr(&file_entry[4]);
global_table_log.handler_type_len= uint2korr(&file_entry[6]); global_table_log.handler_type_len= uint2korr(&file_entry[6]);
global_table_log.free_entries.clear(); global_table_log.first_free= NULL;
global_table_log.log_entries.clear(); global_table_log.first_used= NULL;
global_table_log.no_entries= 0; global_table_log.no_entries= 0;
VOID(pthread_mutex_init(&LOCK_gtl, MY_MUTEX_INIT_FAST)); VOID(pthread_mutex_init(&LOCK_gtl, MY_MUTEX_INIT_FAST));
DBUG_RETURN(entry_no); DBUG_RETURN(entry_no);
...@@ -525,7 +466,23 @@ read_table_log_header() ...@@ -525,7 +466,23 @@ read_table_log_header()
bool bool
read_table_log_entry(uint read_entry, TABLE_LOG_ENTRY *table_log_entry) read_table_log_entry(uint read_entry, TABLE_LOG_ENTRY *table_log_entry)
{ {
char *file_entry= (char*)&global_table_log.file_entry;
DBUG_ENTER("read_table_log_entry"); DBUG_ENTER("read_table_log_entry");
if (read_table_log_file_entry(global_table_log.file_id,
(char*)&file_entry, read_entry))
{
/* Error handling */
DBUG_RETURN(TRUE);
}
table_log_entry->entry_type= file_entry[0];
table_log_entry->action_type= file_entry[1];
table_log_entry->next_entry= uint4korr(&file_entry[2]);
table_log_entry->name= &file_entry[6];
index= 6 + global_table_log->name_len;
table_log_entry->from_name= &file_entry[index];
index+= global_table_log->name_len;
table_log_entry->handler_type= &file_entry[index];
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
...@@ -542,93 +499,234 @@ read_table_log_entry(uint read_entry, TABLE_LOG_ENTRY *table_log_entry) ...@@ -542,93 +499,234 @@ read_table_log_entry(uint read_entry, TABLE_LOG_ENTRY *table_log_entry)
number of entries to zero. number of entries to zero.
*/ */
static
bool bool
init_table_log() init_table_log()
{ {
bool error= FALSE; bool error= FALSE;
char file_name[FN_REFLEN];
DBUG_ENTER("init_table_log"); DBUG_ENTER("init_table_log");
VOID(my_delete(global_table_log.file_name)); create_table_log_file_name(file_name);
global_table_log.file_id= my_open(global_table_log.file_name, VOID(my_delete(file_name));
0, 0, MYF(0)); if ((global_table_log.file_id= my_create(file_name,
CREATE_MODE,
create_flags, MYF(0))) < 0)
{
/* Couldn't create table log file, this is serious error */
abort();
}
if (write_table_log_header()) if (write_table_log_header())
{
/* Write to error log */
error= TRUE; error= TRUE;
}
DBUG_RETURN(error); DBUG_RETURN(error);
} }
/* /*
Release all memory allocated to the table log Execute one action in a table log entry
SYNOPSIS SYNOPSIS
release_table_log() execute_table_log_action()
table_log_entry Information in action entry to execute
RETURN VALUES RETURN VALUES
NONE TRUE Error
FALSE Success
*/ */
void static
release_table_log() bool
execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry)
{ {
DBUG_ENTER("release_table_log"); DBUG_ENTER("execute_table_log_action");
DBUG_RETURN(FALSE);
VOID(pthread_mutex_destroy(&LOCK_gtl));
DBUG_RETURN_VOID;
} }
/* /*
Lock mutex for global table log Get a free entry in the table log
SYNOPSIS SYNOPSIS
lock_global_table_log() get_free_table_log_entry()
out:active_entry A table log memory entry returned
RETURN VALUES RETURN VALUES
NONE TRUE Error
FALSE Success
*/ */
void static
lock_global_table_log() bool
get_free_table_log_entry(TABLE_LOG_MEMORY_ENTRY **active_entry)
{ {
DBUG_ENTER("lock_global_table_log"); bool write_header;
TABLE_LOG_MEMORY_ENTRY *used_entry;
TABLE_LOG_MEMORY_ENTRY *first_used= global_table_log.first_used;
if (global_table_log.first_free == NULL)
{
if (!(used_entry= my_malloc(sizeof(TABLE_LOG_MEMORY_ENTRY))))
{
DBUG_RETURN(TRUE);
}
global_table_log.no_entries++;
used_entry->entry_no= entry_no= global_table_log.no_entries;
write_header= TRUE;
}
else
{
used_entry= global_table_log.first_free;
global_table_log.first_free= used_entry->next_log_entry;
entry_no= first_free->entry_pos;
used_entry= first_free;
write_header= FALSE;
}
/*
Move from free list to used list
*/
used_entry->next_log_entry= first_used;
used_entry->prev_log_entry= NULL;
global_table_log.first_used= used_entry;
if (first_used)
first_used->prev_log_entry= used_entry;
VOID(pthread_mutex_lock(&LOCK_gtl)); *active_entry= used_entry;
DBUG_RETURN_VOID;
} }
/* /*
Unlock mutex for global table log External interface methods for the Table log Module
---------------------------------------------------
*/
/*
SYNOPSIS SYNOPSIS
unlock_global_table_log() write_table_log_entry()
table_log_entry Information about log entry
out:entry_written Entry information written into
RETURN VALUES RETURN VALUES
NONE TRUE Error
FALSE Success
DESCRIPTION
A careful write of the table log is performed to ensure that we can
handle crashes occurring during CREATE and ALTER TABLE processing.
*/ */
void bool
unlock_global_table_log() write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry,
TABLE_LOG_MEMORY_ENTRY **active_entry)
{ {
DBUG_ENTER("unlock_global_table_log"); bool error;
DBUG_ENTER("write_table_log_entry");
VOID(pthread_mutex_unlock(&LOCK_gtl)); global_table_log.file_entry[0]= 'i';
DBUG_RETURN_VOID; global_table_log.file_entry[1]= table_log_entry->action_type;
int4store(&global_table_log.file_entry[2],
table_log_entry->next_entry);
strcpy(&global_table_log.file_entry[6], table_log_entry->name);
if (table_log_entry.action_type == 'r')
global_table_log.file_entry[6 + NAMELEN]= 0;
else
strcpy(&global_table_log.file_entry[6 + NAMELEN],
table_log_entry->from_name);
strcpy(&global_table_log.file_entry[6 + (2*NAMELEN)],
table_log_entry->handler_type);
if (get_free_table_log_entry(active_entry))
{
DBUG_RETURN(TRUE);
}
error= FALSE;
if (write_table_log_file_entry(global_table_log.file_id,
global_table_log.file_entry,
(*active_entry)->entry_pos))
error= TRUE;
else if (write_header || !(write_table_log_header()))
error= TRUE;
if (error)
release_table_log_memory_entry(*active_entry);
DBUG_RETURN(error);
} }
/* /*
Execute one action in a table log entry Write final entry in the table log
SYNOPSIS SYNOPSIS
execute_table_log_action() write_execute_table_log_entry()
table_log_entry Information in action entry to execute first_entry First entry in linked list of entries
to execute, if 0 = NULL it means that
the entry is removed and the entries
are put into the free list.
in:out:exec_entry Entry to execute, 0 = NULL if the entry
is written first time and needs to be
returned. In this case the entry written
is returned in this parameter
RETURN VALUES RETURN VALUES
TRUE Error TRUE Error
FALSE Success FALSE Success
*/
DESCRIPTION
This is the last write in the table log. The previous log entries have
already been written but not yet synched to disk.
*/
bool bool
execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) write_execute_table_log_entry(uint first_entry,
TABLE_LOG_MEMORY_ENTRY **active_entry)
{ {
DBUG_ENTER("execute_table_log_action"); char *file_entry= (char*)global_table_log.file_entry;
DBUG_ENTER("write_execute_table_log_entry");
VOID(sync_table_log());
file_entry[0]= 'e';
file_entry[1]= 0; /* Ignored for execute entries */
int4store(&file_entry[2], first_entry);
file_entry[6]= 0;
file_entry[6 + NAMELEN]= 0;
file_entry[6 + 2*NAMELEN]= 0;
if (get_free_table_log_entry(active_entry))
{
DBUG_RETURN(TRUE);
}
if (write_table_log_file_entry((*active_entry)->entry_pos))
{
release_table_log_memory_entry(*active_entry);
DBUG_RETURN(TRUE);
}
VOID(sync_table_log());
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
/*
Release a log memory entry
SYNOPSIS
release_table_log_memory_entry()
log_memory_entry Log memory entry to release
RETURN VALUES
NONE
*/
void
release_table_log_memory_entry(TABLE_LOG_MEMORY_ENTRY *log_entry)
{
TABLE_LOG_MEMORY_ENTRY *first_free= global_table_log.first_free;
TABLE_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
TABLE_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
DBUG_ENTER("release_table_log_memory_entry");
global_table_log.first_free= log_entry;
log_entry->next_log_entry= first_free;
if (prev_log_entry)
prev_log_entry->next_log_entry= next_log_entry;
else
global_table_log.first_used= next_log_entry;
if (next_log_entry)
next_log_entry->prev_log_entry= prev_log_entry;
DBUG_RETURN_VOID;
}
/* /*
Execute one entry in the table log. Executing an entry means executing Execute one entry in the table log. Executing an entry means executing
a linked list of actions. a linked list of actions.
...@@ -640,6 +738,7 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry) ...@@ -640,6 +738,7 @@ execute_table_log_action(TABLE_LOG_ENTRY *table_log_entry)
FALSE Success FALSE Success
*/ */
static
bool bool
execute_table_log_entry(uint first_entry) execute_table_log_entry(uint first_entry)
{ {
...@@ -649,19 +748,24 @@ execute_table_log_entry(uint first_entry) ...@@ -649,19 +748,24 @@ execute_table_log_entry(uint first_entry)
do do
{ {
read_table_log_entry(read_entry, &table_log_entry); if (read_table_log_entry(read_entry, &table_log_entry))
{
DBUG_ASSERT(0);
/* Write to error log and continue with next log entry */
break;
}
DBUG_ASSERT(table_log_entry.entry_type == 'i'); DBUG_ASSERT(table_log_entry.entry_type == 'i');
if (execute_table_log_action(&table_log_entry)) if (execute_table_log_action(&table_log_entry))
{ {
/* error handling */ DBUG_ASSERT(0);
DBUG_RETURN(TRUE); /* Write to error log and continue with next log entry */
break;
} }
read_entry= table_log_entry.next_entry; read_entry= table_log_entry.next_entry;
} while (read_entry); } while (read_entry);
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
/* /*
Execute the table log at recovery of MySQL Server Execute the table log at recovery of MySQL Server
SYNOPSIS SYNOPSIS
...@@ -680,17 +784,94 @@ execute_table_log_recovery() ...@@ -680,17 +784,94 @@ execute_table_log_recovery()
no_entries= read_log_header(); no_entries= read_log_header();
for (i= 0; i < no_entries; i++) for (i= 0; i < no_entries; i++)
{ {
read_table_log_entry(i, &table_log_entry); if (read_table_log_entry(i, &table_log_entry))
{
DBUG_ASSERT(0);
/* Write to error log */
break;
}
if (table_log_entry.entry_type == 'e') if (table_log_entry.entry_type == 'e')
{ {
if (execute_table_log_entry(table_log_entry.next_entry)) if (execute_table_log_entry(table_log_entry.next_entry))
{ {
/* error handling */ /*
Currently errors are either crashing or ignored so we should
never end up here
*/
abort();
DBUG_RETURN_VOID; DBUG_RETURN_VOID;
} }
} }
} }
init_table_log(); VOID(init_table_log());
DBUG_RETURN_VOID;
}
/*
Release all memory allocated to the table log
SYNOPSIS
release_table_log()
RETURN VALUES
NONE
*/
void
release_table_log()
{
TABLE_LOG_MEMORY_ENTRY *free_list= global_table_log.first_free;
TABLE_LOG_MEMORY_ENTRY *used_list= global_table_log.first_used;
DBUG_ENTER("release_table_log");
VOID(pthread_mutex_destroy(&LOCK_gtl));
while (used_list)
{
TABLE_LOG_MEMORY_ENTRY tmp= used_list;
my_free(used_list, MYF(0));
used_list= tmp->next_log_entry;
}
while (free_list)
{
TABLE_LOG_MEMORY_ENTRY tmp= free_list;
my_free(free_list, MYF(0));
free_list= tmp->next_log_entry;
}
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; DBUG_RETURN_VOID;
} }
......
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