1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

WL 2826: Error handling of ALTER TABLE for partitioning

Loads of review comments fixed
inactivate => deactivate
table log => ddl log
Commented on Error Inject Module added
Put various #defines into enums
Fixed abort_and_upgrade_lock, removed unnecessary parameter
Fixed mysqlish method intro's
Fixed warning statements
5.1.7 was released still with partition states in clear text

Fixed io_size bug
Fixed bug in open that TRUNCATED before reading :)
file_entry => file_entry_buf
Don't open DDL log until first write call to DDL log
handler_type => handler_name
no => num
This commit is contained in:
pappa@c-8808e253.1238-1-64736c10.cust.bredbandsbolaget.se
2006-03-24 18:19:13 -05:00
parent ac10cffe80
commit f8088c1804
10 changed files with 659 additions and 654 deletions

View File

@ -701,7 +701,7 @@ int ha_partition::rename_partitions(const char *path)
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if ((ret_error= file->delete_table((const char *) norm_name_buff))) if ((ret_error= file->delete_table((const char *) norm_name_buff)))
error= ret_error; error= ret_error;
else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
else else
sub_elem->log_entry= NULL; /* Indicate success */ sub_elem->log_entry= NULL; /* Indicate success */
@ -716,13 +716,13 @@ int ha_partition::rename_partitions(const char *path)
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if ((ret_error= file->delete_table((const char *) norm_name_buff))) if ((ret_error= file->delete_table((const char *) norm_name_buff)))
error= ret_error; error= ret_error;
else if (inactivate_table_log_entry(part_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
else else
part_elem->log_entry= NULL; /* Indicate success */ part_elem->log_entry= NULL; /* Indicate success */
} }
} while (++i < temp_partitions); } while (++i < temp_partitions);
VOID(sync_table_log()); VOID(sync_ddl_log());
} }
i= 0; i= 0;
do do
@ -771,9 +771,9 @@ int ha_partition::rename_partitions(const char *path)
DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
if ((ret_error= file->delete_table((const char *) norm_name_buff))) if ((ret_error= file->delete_table((const char *) norm_name_buff)))
error= ret_error; error= ret_error;
else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
VOID(sync_table_log()); VOID(sync_ddl_log());
} }
file= m_new_file[part]; file= m_new_file[part];
create_subpartition_name(part_name_buff, path, create_subpartition_name(part_name_buff, path,
@ -785,7 +785,7 @@ int ha_partition::rename_partitions(const char *path)
if ((ret_error= file->rename_table((const char *) part_name_buff, if ((ret_error= file->rename_table((const char *) part_name_buff,
(const char *) norm_name_buff))) (const char *) norm_name_buff)))
error= ret_error; error= ret_error;
else if (inactivate_table_log_entry(sub_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(sub_elem->log_entry->entry_pos))
error= 1; error= 1;
else else
sub_elem->log_entry= NULL; sub_elem->log_entry= NULL;
@ -802,9 +802,9 @@ int ha_partition::rename_partitions(const char *path)
DBUG_PRINT("info", ("Delete partition %s", norm_name_buff)); DBUG_PRINT("info", ("Delete partition %s", norm_name_buff));
if ((ret_error= file->delete_table((const char *) norm_name_buff))) if ((ret_error= file->delete_table((const char *) norm_name_buff)))
error= ret_error; error= ret_error;
else if (inactivate_table_log_entry(part_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
VOID(sync_table_log()); VOID(sync_ddl_log());
} }
file= m_new_file[i]; file= m_new_file[i];
create_partition_name(part_name_buff, path, create_partition_name(part_name_buff, path,
@ -815,14 +815,14 @@ int ha_partition::rename_partitions(const char *path)
if ((ret_error= file->rename_table((const char *) part_name_buff, if ((ret_error= file->rename_table((const char *) part_name_buff,
(const char *) norm_name_buff))) (const char *) norm_name_buff)))
error= ret_error; error= ret_error;
else if (inactivate_table_log_entry(part_elem->log_entry->entry_pos)) else if (deactivate_ddl_log_entry(part_elem->log_entry->entry_pos))
error= 1; error= 1;
else else
part_elem->log_entry= NULL; part_elem->log_entry= NULL;
} }
} }
} while (++i < no_parts); } while (++i < no_parts);
VOID(sync_table_log()); VOID(sync_ddl_log());
DBUG_RETURN(error); DBUG_RETURN(error);
} }

View File

@ -631,9 +631,6 @@ struct Query_cache_query_flags
#else #else
#define SET_ERROR_INJECT_VALUE(x) \
current_thd->error_inject_value= (x)
inline bool inline bool
my_error_inject_name(const char *dbug_str) my_error_inject_name(const char *dbug_str)
{ {
@ -661,6 +658,43 @@ my_error_inject(int value)
return 0; return 0;
} }
/*
ERROR INJECT MODULE:
--------------------
These macros are used to insert macros from the application code.
The event that activates those error injections can be activated
from SQL by using:
SET SESSION dbug=+d,code;
After the error has been injected, the macros will automatically
remove the debug code, thus similar to using:
SET SESSION dbug=-d,code
from SQL.
ERROR_INJECT_CRASH will inject a crash of the MySQL Server if code
is set when macro is called. ERROR_INJECT_CRASH can be used in
if-statements, it will always return FALSE unless of course it
crashes in which case it doesn't return at all.
ERROR_INJECT_ACTION will inject the action specified in the action
parameter of the macro, before performing the action the code will
be removed such that no more events occur. ERROR_INJECT_ACTION
can also be used in if-statements and always returns FALSE.
ERROR_INJECT can be used in a normal if-statement, where the action
part is performed in the if-block. The macro returns TRUE if the
error was activated and otherwise returns FALSE. If activated the
code is removed.
Sometimes it is necessary to perform error inject actions as a serie
of events. In this case one can use one variable on the THD object.
Thus one sets this value by using e.g. SET_ERROR_INJECT_VALUE(100).
Then one can later test for it by using ERROR_INJECT_CRASH_VALUE,
ERROR_INJECT_ACTION_VALUE and ERROR_INJECT_VALUE. This have the same
behaviour as the above described macros except that they use the
error inject value instead of a code used by DBUG macros.
*/
#define SET_ERROR_INJECT_VALUE(x) \
current_thd->error_inject_value= (x)
#define ERROR_INJECT_CRASH(code) \ #define ERROR_INJECT_CRASH(code) \
DBUG_EVALUATE_IF(code, (abort(), 0), 0) DBUG_EVALUATE_IF(code, (abort(), 0), 0)
#define ERROR_INJECT_ACTION(code, action) \ #define ERROR_INJECT_ACTION(code, action) \
@ -1186,57 +1220,86 @@ typedef struct st_lock_param_type
void mem_alloc_error(size_t size); void mem_alloc_error(size_t size);
typedef struct st_table_log_entry enum ddl_log_entry_code
{
/*
DDL_LOG_EXECUTE_CODE:
This is a code that indicates that this is a log entry to
be executed, from this entry a linked list of log entries
can be found and executed.
DDL_LOG_ENTRY_CODE:
An entry to be executed in a linked list from an execute log
entry.
DDL_IGNORE_LOG_ENTRY_CODE:
An entry that is to be ignored
*/
DDL_LOG_EXECUTE_CODE = 'e',
DDL_LOG_ENTRY_CODE = 'l',
DDL_IGNORE_LOG_ENTRY_CODE = 'i'
};
enum ddl_log_action_code
{
/*
The type of action that a DDL_LOG_ENTRY_CODE entry is to
perform.
DDL_LOG_DELETE_ACTION:
Delete an entity
DDL_LOG_RENAME_ACTION:
Rename an entity
DDL_LOG_REPLACE_ACTION:
Rename an entity after removing the previous entry with the
new name, that is replace this entry.
*/
DDL_LOG_DELETE_ACTION = 'd',
DDL_LOG_RENAME_ACTION = 'r',
DDL_LOG_REPLACE_ACTION = 's'
};
typedef struct st_ddl_log_entry
{ {
const char *name; const char *name;
const char *from_name; const char *from_name;
const char *handler_type; const char *handler_name;
uint next_entry; uint next_entry;
uint entry_pos; uint entry_pos;
char action_type; enum ddl_log_entry_code entry_type;
char entry_type; enum ddl_log_action_code action_type;
char phase; char phase;
char not_used; } DDL_LOG_ENTRY;
} TABLE_LOG_ENTRY;
typedef struct st_table_log_memory_entry typedef struct st_ddl_log_memory_entry
{ {
uint entry_pos; uint entry_pos;
struct st_table_log_memory_entry *next_log_entry; struct st_ddl_log_memory_entry *next_log_entry;
struct st_table_log_memory_entry *prev_log_entry; struct st_ddl_log_memory_entry *prev_log_entry;
struct st_table_log_memory_entry *next_active_log_entry; struct st_ddl_log_memory_entry *next_active_log_entry;
} TABLE_LOG_MEMORY_ENTRY; } DDL_LOG_MEMORY_ENTRY;
#define TLOG_EXECUTE_CODE 'e'
#define TLOG_LOG_ENTRY_CODE 'l'
#define TLOG_IGNORE_LOG_ENTRY_CODE 'i'
#define TLOG_DELETE_ACTION_CODE 'd'
#define TLOG_RENAME_ACTION_CODE 'r'
#define TLOG_REPLACE_ACTION_CODE 's'
#define TLOG_HANDLER_TYPE_LEN 32 #define DDL_LOG_HANDLER_TYPE_LEN 32
bool write_table_log_entry(TABLE_LOG_ENTRY *table_log_entry, bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
TABLE_LOG_MEMORY_ENTRY **active_entry); DDL_LOG_MEMORY_ENTRY **active_entry);
bool write_execute_table_log_entry(uint first_entry, bool write_execute_ddl_log_entry(uint first_entry,
bool complete, bool complete,
TABLE_LOG_MEMORY_ENTRY **active_entry); DDL_LOG_MEMORY_ENTRY **active_entry);
bool inactivate_table_log_entry(uint entry_no); bool deactivate_ddl_log_entry(uint entry_no);
void release_table_log_memory_entry(TABLE_LOG_MEMORY_ENTRY *log_entry); void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry);
bool sync_table_log(); bool sync_ddl_log();
void release_table_log(); void release_ddl_log();
void execute_table_log_recovery(); void execute_ddl_log_recovery();
bool execute_table_log_entry(uint first_entry); bool execute_ddl_log_entry(uint first_entry);
void lock_global_table_log(); void lock_global_ddl_log();
void unlock_global_table_log(); void unlock_global_ddl_log();
#define WFRM_WRITE_SHADOW 1 #define WFRM_WRITE_SHADOW 1
#define WFRM_INSTALL_SHADOW 2 #define WFRM_INSTALL_SHADOW 2
#define WFRM_PACK_FRM 4 #define WFRM_PACK_FRM 4
bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags); bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags);
bool abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt, void abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt);
bool can_be_killed);
void close_open_tables_and_downgrade(ALTER_PARTITION_PARAM_TYPE *lpt); void close_open_tables_and_downgrade(ALTER_PARTITION_PARAM_TYPE *lpt);
void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table); void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table);

View File

@ -3665,7 +3665,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(); execute_ddl_log_recovery();
create_shutdown_thread(); create_shutdown_thread();
create_maintenance_thread(); create_maintenance_thread();
@ -3696,7 +3696,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
/* (void) pthread_attr_destroy(&connection_attrib); */ /* (void) pthread_attr_destroy(&connection_attrib); */
DBUG_PRINT("quit",("Exiting main thread")); DBUG_PRINT("quit",("Exiting main thread"));
release_table_log(); release_ddl_log();
#ifndef __WIN__ #ifndef __WIN__
#ifdef EXTRA_DEBUG2 #ifdef EXTRA_DEBUG2

View File

@ -36,7 +36,7 @@ enum partition_state {
PART_IS_ADDED= 8 PART_IS_ADDED= 8
}; };
struct st_table_log_memory_entry; struct st_ddl_log_memory_entry;
class partition_element :public Sql_alloc { class partition_element :public Sql_alloc {
public: public:
@ -46,7 +46,7 @@ public:
ulonglong part_min_rows; ulonglong part_min_rows;
char *partition_name; char *partition_name;
char *tablespace_name; char *tablespace_name;
struct st_table_log_memory_entry *log_entry; struct st_ddl_log_memory_entry *log_entry;
longlong range_value; longlong range_value;
char* part_comment; char* part_comment;
char* data_file_name; char* data_file_name;

View File

@ -28,7 +28,7 @@ typedef int (*get_part_id_func)(partition_info *part_info,
longlong *func_value); longlong *func_value);
typedef uint32 (*get_subpart_id_func)(partition_info *part_info); typedef uint32 (*get_subpart_id_func)(partition_info *part_info);
struct st_table_log_memory_entry; struct st_ddl_log_memory_entry;
class partition_info : public Sql_alloc class partition_info : public Sql_alloc
{ {
@ -77,9 +77,9 @@ public:
Item *item_free_list; Item *item_free_list;
struct st_table_log_memory_entry *first_log_entry; struct st_ddl_log_memory_entry *first_log_entry;
struct st_table_log_memory_entry *exec_log_entry; struct st_ddl_log_memory_entry *exec_log_entry;
struct st_table_log_memory_entry *frm_log_entry; struct st_ddl_log_memory_entry *frm_log_entry;
/* /*
A bitmap of partitions used by the current query. A bitmap of partitions used by the current query.

View File

@ -5826,5 +5826,5 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT
eng "The NDB cluster engine does not support changing the binlog format on the fly yet" eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
ER_PARTITION_NO_TEMPORARY ER_PARTITION_NO_TEMPORARY
eng "Cannot create temporary table with partitions" eng "Cannot create temporary table with partitions"
ER_TABLE_LOG_ERROR ER_DDL_LOG_ERROR
eng "Error in table log" eng "Error in DDL log"

View File

@ -6124,24 +6124,17 @@ bool is_equal(const LEX_STRING *a, const LEX_STRING *b)
old_lock_level Old lock level old_lock_level Old lock level
*/ */
bool abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt, void abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt)
bool can_be_killed)
{ {
uint flags= RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG; uint flags= RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG;
int error= FALSE;
DBUG_ENTER("abort_and_upgrade_locks"); DBUG_ENTER("abort_and_upgrade_locks");
lpt->old_lock_type= lpt->table->reginfo.lock_type; lpt->old_lock_type= lpt->table->reginfo.lock_type;
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
mysql_lock_abort(lpt->thd, lpt->table, TRUE); mysql_lock_abort(lpt->thd, lpt->table, TRUE);
VOID(remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, flags)); VOID(remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, flags));
if (can_be_killed && lpt->thd->killed)
{
lpt->thd->no_warnings_for_error= 0;
error= TRUE;
}
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(error); DBUG_VOID_RETURN;
} }

View File

@ -5037,10 +5037,8 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
NONE NONE
*/ */
static static void insert_part_info_log_entry_list(partition_info *part_info,
void DDL_LOG_MEMORY_ENTRY *log_entry)
insert_part_info_log_entry_list(partition_info *part_info,
TABLE_LOG_MEMORY_ENTRY *log_entry)
{ {
log_entry->next_active_log_entry= part_info->first_log_entry; log_entry->next_active_log_entry= part_info->first_log_entry;
part_info->first_log_entry= log_entry; part_info->first_log_entry= log_entry;
@ -5056,15 +5054,13 @@ insert_part_info_log_entry_list(partition_info *part_info,
NONE NONE
*/ */
static static void release_part_info_log_entries(DDL_LOG_MEMORY_ENTRY *log_entry)
void
release_part_info_log_entries(TABLE_LOG_MEMORY_ENTRY *log_entry)
{ {
DBUG_ENTER("release_part_info_log_entries"); DBUG_ENTER("release_part_info_log_entries");
while (log_entry) while (log_entry)
{ {
release_table_log_memory_entry(log_entry); release_ddl_log_memory_entry(log_entry);
log_entry= log_entry->next_active_log_entry; log_entry= log_entry->next_active_log_entry;
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -5084,32 +5080,30 @@ release_part_info_log_entries(TABLE_LOG_MEMORY_ENTRY *log_entry)
FALSE Success FALSE Success
DESCRIPTION DESCRIPTION
Support routine that writes a replace or delete of an frm file into the Support routine that writes a replace or delete of an frm file into the
table log. It also inserts an entry that keeps track of used space into ddl log. It also inserts an entry that keeps track of used space into
the partition info object the partition info object
*/ */
static static bool write_log_replace_delete_frm(ALTER_PARTITION_PARAM_TYPE *lpt,
bool
write_log_replace_delete_frm(ALTER_PARTITION_PARAM_TYPE *lpt,
uint next_entry, uint next_entry,
const char *from_path, const char *from_path,
const char *to_path, const char *to_path,
bool replace_flag) bool replace_flag)
{ {
TABLE_LOG_ENTRY table_log_entry; DDL_LOG_ENTRY ddl_log_entry;
TABLE_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *log_entry;
DBUG_ENTER("write_log_replace_delete_frm"); DBUG_ENTER("write_log_replace_delete_frm");
if (replace_flag) if (replace_flag)
table_log_entry.action_type= TLOG_REPLACE_ACTION_CODE; ddl_log_entry.action_type= DDL_LOG_REPLACE_ACTION;
else else
table_log_entry.action_type= TLOG_DELETE_ACTION_CODE; ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION;
table_log_entry.next_entry= next_entry; ddl_log_entry.next_entry= next_entry;
table_log_entry.handler_type= "frm"; ddl_log_entry.handler_name= "frm";
table_log_entry.name= to_path; ddl_log_entry.name= to_path;
if (replace_flag) if (replace_flag)
table_log_entry.from_name= from_path; ddl_log_entry.from_name= from_path;
if (write_table_log_entry(&table_log_entry, &log_entry)) if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5140,14 +5134,12 @@ write_log_replace_delete_frm(ALTER_PARTITION_PARAM_TYPE *lpt,
the partition handler. the partition handler.
*/ */
static static bool write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
bool
write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
uint *next_entry, const char *path) uint *next_entry, const char *path)
{ {
TABLE_LOG_ENTRY table_log_entry; DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *log_entry;
char tmp_path[FN_LEN]; char tmp_path[FN_LEN];
char normal_path[FN_LEN]; char normal_path[FN_LEN];
List_iterator<partition_element> part_it(part_info->partitions); List_iterator<partition_element> part_it(part_info->partitions);
@ -5170,8 +5162,8 @@ write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
do do
{ {
partition_element *sub_elem= sub_it++; partition_element *sub_elem= sub_it++;
table_log_entry.next_entry= *next_entry; ddl_log_entry.next_entry= *next_entry;
table_log_entry.handler_type= ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(sub_elem->engine_type); ha_resolve_storage_engine_name(sub_elem->engine_type);
create_subpartition_name(tmp_path, path, create_subpartition_name(tmp_path, path,
part_elem->partition_name, part_elem->partition_name,
@ -5181,13 +5173,13 @@ write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
part_elem->partition_name, part_elem->partition_name,
sub_elem->partition_name, sub_elem->partition_name,
NORMAL_PART_NAME); NORMAL_PART_NAME);
table_log_entry.name= normal_path; ddl_log_entry.name= normal_path;
table_log_entry.from_name= tmp_path; ddl_log_entry.from_name= tmp_path;
if (part_elem->part_state == PART_IS_CHANGED) if (part_elem->part_state == PART_IS_CHANGED)
table_log_entry.action_type= TLOG_REPLACE_ACTION_CODE; ddl_log_entry.action_type= DDL_LOG_REPLACE_ACTION;
else else
table_log_entry.action_type= TLOG_RENAME_ACTION_CODE; ddl_log_entry.action_type= DDL_LOG_RENAME_ACTION;
if (write_table_log_entry(&table_log_entry, &log_entry)) if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5198,8 +5190,8 @@ write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
} }
else else
{ {
table_log_entry.next_entry= *next_entry; ddl_log_entry.next_entry= *next_entry;
table_log_entry.handler_type= ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(part_elem->engine_type); ha_resolve_storage_engine_name(part_elem->engine_type);
create_partition_name(tmp_path, path, create_partition_name(tmp_path, path,
part_elem->partition_name, part_elem->partition_name,
@ -5207,13 +5199,13 @@ write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
create_partition_name(normal_path, path, create_partition_name(normal_path, path,
part_elem->partition_name, part_elem->partition_name,
NORMAL_PART_NAME, TRUE); NORMAL_PART_NAME, TRUE);
table_log_entry.name= normal_path; ddl_log_entry.name= normal_path;
table_log_entry.from_name= tmp_path; ddl_log_entry.from_name= tmp_path;
if (part_elem->part_state == PART_IS_CHANGED) if (part_elem->part_state == PART_IS_CHANGED)
table_log_entry.action_type= TLOG_REPLACE_ACTION_CODE; ddl_log_entry.action_type= DDL_LOG_REPLACE_ACTION;
else else
table_log_entry.action_type= TLOG_RENAME_ACTION_CODE; ddl_log_entry.action_type= DDL_LOG_RENAME_ACTION;
if (write_table_log_entry(&table_log_entry, &log_entry)) if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5237,16 +5229,14 @@ write_log_changed_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
FALSE Success FALSE Success
*/ */
static static bool write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
bool
write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
uint *next_entry, uint *next_entry,
const char *path, const char *path,
bool temp_list) bool temp_list)
{ {
TABLE_LOG_ENTRY table_log_entry; DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *log_entry;
char tmp_path[FN_LEN]; char tmp_path[FN_LEN];
List_iterator<partition_element> part_it(part_info->partitions); List_iterator<partition_element> part_it(part_info->partitions);
List_iterator<partition_element> temp_it(part_info->temp_partitions); List_iterator<partition_element> temp_it(part_info->temp_partitions);
@ -5255,7 +5245,7 @@ write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
uint i= 0; uint i= 0;
DBUG_ENTER("write_log_dropped_partitions"); DBUG_ENTER("write_log_dropped_partitions");
table_log_entry.action_type= TLOG_DELETE_ACTION_CODE; ddl_log_entry.action_type= DDL_LOG_DELETE_ACTION;
if (temp_list) if (temp_list)
no_elements= no_temp_partitions; no_elements= no_temp_partitions;
while (no_elements--) while (no_elements--)
@ -5284,15 +5274,15 @@ write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
do do
{ {
partition_element *sub_elem= sub_it++; partition_element *sub_elem= sub_it++;
table_log_entry.next_entry= *next_entry; ddl_log_entry.next_entry= *next_entry;
table_log_entry.handler_type= ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(sub_elem->engine_type); ha_resolve_storage_engine_name(sub_elem->engine_type);
create_subpartition_name(tmp_path, path, create_subpartition_name(tmp_path, path,
part_elem->partition_name, part_elem->partition_name,
sub_elem->partition_name, sub_elem->partition_name,
name_variant); name_variant);
table_log_entry.name= tmp_path; ddl_log_entry.name= tmp_path;
if (write_table_log_entry(&table_log_entry, &log_entry)) if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5304,14 +5294,14 @@ write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
} }
else else
{ {
table_log_entry.next_entry= *next_entry; ddl_log_entry.next_entry= *next_entry;
table_log_entry.handler_type= ddl_log_entry.handler_name=
ha_resolve_storage_engine_name(part_elem->engine_type); ha_resolve_storage_engine_name(part_elem->engine_type);
create_partition_name(tmp_path, path, create_partition_name(tmp_path, path,
part_elem->partition_name, part_elem->partition_name,
name_variant, TRUE); name_variant, TRUE);
table_log_entry.name= tmp_path; ddl_log_entry.name= tmp_path;
if (write_table_log_entry(&table_log_entry, &log_entry)) if (write_ddl_log_entry(&ddl_log_entry, &log_entry))
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5327,7 +5317,7 @@ write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
/* /*
Set execute log entry in table log for this partitioned table Set execute log entry in ddl log for this partitioned table
SYNOPSIS SYNOPSIS
set_part_info_exec_log_entry() set_part_info_exec_log_entry()
part_info Partition info object part_info Partition info object
@ -5336,10 +5326,8 @@ write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
NONE NONE
*/ */
static static void set_part_info_exec_log_entry(partition_info *part_info,
void DDL_LOG_MEMORY_ENTRY *exec_log_entry)
set_part_info_exec_log_entry(partition_info *part_info,
TABLE_LOG_MEMORY_ENTRY *exec_log_entry)
{ {
part_info->exec_log_entry= exec_log_entry; part_info->exec_log_entry= exec_log_entry;
exec_log_entry->next_active_log_entry= NULL; exec_log_entry->next_active_log_entry= NULL;
@ -5358,41 +5346,38 @@ set_part_info_exec_log_entry(partition_info *part_info,
TRUE Error TRUE Error
FALSE Success FALSE Success
DESCRIPTION DESCRIPTION
Prepare an entry to the table log indicating a drop/install of the shadow frm Prepare an entry to the ddl log indicating a drop/install of the shadow frm
file and its corresponding handler file. file and its corresponding handler file.
*/ */
static static bool write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
bool
write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
{ {
TABLE_LOG_ENTRY table_log_entry; DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *log_entry;
TABLE_LOG_MEMORY_ENTRY *exec_log_entry= NULL; DDL_LOG_MEMORY_ENTRY *exec_log_entry= NULL;
char shadow_path[FN_LEN]; char shadow_path[FN_LEN];
DBUG_ENTER("write_log_drop_shadow_frm"); DBUG_ENTER("write_log_drop_shadow_frm");
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#");
lock_global_table_log(); lock_global_ddl_log();
do
{
if (write_log_replace_delete_frm(lpt, 0UL, NULL, if (write_log_replace_delete_frm(lpt, 0UL, NULL,
(const char*)shadow_path, FALSE)) (const char*)shadow_path, FALSE))
break; goto error;
log_entry= part_info->first_log_entry; log_entry= part_info->first_log_entry;
if (write_execute_table_log_entry(log_entry->entry_pos, if (write_execute_ddl_log_entry(log_entry->entry_pos,
FALSE, &exec_log_entry)) FALSE, &exec_log_entry))
break; goto error;
unlock_global_table_log(); unlock_global_ddl_log();
set_part_info_exec_log_entry(part_info, exec_log_entry); set_part_info_exec_log_entry(part_info, exec_log_entry);
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} while (TRUE);
error:
release_part_info_log_entries(part_info->first_log_entry); release_part_info_log_entries(part_info->first_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
my_error(ER_TABLE_LOG_ERROR, MYF(0)); my_error(ER_DDL_LOG_ERROR, MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5410,17 +5395,15 @@ write_log_drop_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
file if failure occurs in the middle of the rename process. file if failure occurs in the middle of the rename process.
*/ */
static static bool write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
bool
write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
{ {
TABLE_LOG_ENTRY table_log_entry; DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *log_entry;
TABLE_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry;
char path[FN_LEN]; char path[FN_LEN];
char shadow_path[FN_LEN]; char shadow_path[FN_LEN];
TABLE_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry;
DBUG_ENTER("write_log_rename_frm"); DBUG_ENTER("write_log_rename_frm");
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
@ -5428,25 +5411,24 @@ write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
lpt->table_name, ""); lpt->table_name, "");
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#");
lock_global_table_log(); lock_global_ddl_log();
do
{
if (write_log_replace_delete_frm(lpt, 0UL, path, shadow_path, FALSE)) if (write_log_replace_delete_frm(lpt, 0UL, path, shadow_path, FALSE))
break; goto error;
log_entry= part_info->first_log_entry; log_entry= part_info->first_log_entry;
part_info->frm_log_entry= log_entry; part_info->frm_log_entry= log_entry;
if (write_execute_table_log_entry(log_entry->entry_pos, if (write_execute_ddl_log_entry(log_entry->entry_pos,
FALSE, &exec_log_entry)) FALSE, &exec_log_entry))
break; goto error;
release_part_info_log_entries(old_first_log_entry); release_part_info_log_entries(old_first_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} while (TRUE);
error:
release_part_info_log_entries(part_info->first_log_entry); release_part_info_log_entries(part_info->first_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
part_info->first_log_entry= old_first_log_entry; part_info->first_log_entry= old_first_log_entry;
part_info->frm_log_entry= NULL; part_info->frm_log_entry= NULL;
my_error(ER_TABLE_LOG_ERROR, MYF(0)); my_error(ER_DDL_LOG_ERROR, MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5462,22 +5444,20 @@ write_log_rename_frm(ALTER_PARTITION_PARAM_TYPE *lpt)
TRUE Error TRUE Error
FALSE Success FALSE Success
DESCRIPTION DESCRIPTION
Prepare entries to the table log indicating all partitions to drop and to Prepare entries to the ddl log indicating all partitions to drop and to
install the shadow frm file and remove the old frm file. install the shadow frm file and remove the old frm file.
*/ */
static static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
bool
write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
{ {
TABLE_LOG_ENTRY table_log_entry; DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *log_entry;
TABLE_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry;
char tmp_path[FN_LEN]; char tmp_path[FN_LEN];
char path[FN_LEN]; char path[FN_LEN];
uint next_entry= 0; uint next_entry= 0;
TABLE_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry;
DBUG_ENTER("write_log_drop_partition"); DBUG_ENTER("write_log_drop_partition");
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
@ -5485,29 +5465,28 @@ write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
lpt->table_name, ""); lpt->table_name, "");
build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, build_table_filename(tmp_path, sizeof(tmp_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#");
lock_global_table_log(); lock_global_ddl_log();
do
{
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE)) FALSE))
break; goto error;
if (write_log_replace_delete_frm(lpt, next_entry, (const char*)path, if (write_log_replace_delete_frm(lpt, next_entry, (const char*)path,
(const char*)tmp_path, TRUE)) (const char*)tmp_path, TRUE))
break; goto error;
log_entry= part_info->first_log_entry; log_entry= part_info->first_log_entry;
part_info->frm_log_entry= log_entry; part_info->frm_log_entry= log_entry;
if (write_execute_table_log_entry(log_entry->entry_pos, if (write_execute_ddl_log_entry(log_entry->entry_pos,
FALSE, &exec_log_entry)) FALSE, &exec_log_entry))
break; goto error;
release_part_info_log_entries(old_first_log_entry); release_part_info_log_entries(old_first_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} while (TRUE);
error:
release_part_info_log_entries(part_info->first_log_entry); release_part_info_log_entries(part_info->first_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
part_info->first_log_entry= old_first_log_entry; part_info->first_log_entry= old_first_log_entry;
part_info->frm_log_entry= NULL; part_info->frm_log_entry= NULL;
my_error(ER_TABLE_LOG_ERROR, MYF(0)); my_error(ER_DDL_LOG_ERROR, MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5523,19 +5502,17 @@ write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
TRUE Error TRUE Error
FALSE Success FALSE Success
DESCRIPTION DESCRIPTION
Prepare entries to the table log indicating all partitions to drop and to Prepare entries to the ddl log indicating all partitions to drop and to
remove the shadow frm file. remove the shadow frm file.
We always inject entries backwards in the list in the table log since we We always inject entries backwards in the list in the ddl log since we
don't know the entry position until we have written it. don't know the entry position until we have written it.
*/ */
static static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
bool
write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
{ {
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *log_entry;
TABLE_LOG_MEMORY_ENTRY *exec_log_entry= NULL; DDL_LOG_MEMORY_ENTRY *exec_log_entry= NULL;
char tmp_path[FN_LEN]; char tmp_path[FN_LEN];
char path[FN_LEN]; char path[FN_LEN];
uint next_entry= 0; uint next_entry= 0;
@ -5545,27 +5522,26 @@ write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
lpt->table_name, ""); lpt->table_name, "");
build_table_filename(tmp_path, sizeof(tmp_path), lpt->db, build_table_filename(tmp_path, sizeof(tmp_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#");
lock_global_table_log(); lock_global_ddl_log();
do
{
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
FALSE)) FALSE))
break; goto error;
if (write_log_replace_delete_frm(lpt, next_entry, NULL, tmp_path, if (write_log_replace_delete_frm(lpt, next_entry, NULL, tmp_path,
FALSE)) FALSE))
break; goto error;
log_entry= part_info->first_log_entry; log_entry= part_info->first_log_entry;
if (write_execute_table_log_entry(log_entry->entry_pos, if (write_execute_ddl_log_entry(log_entry->entry_pos,
FALSE, &exec_log_entry)) FALSE, &exec_log_entry))
break; goto error;
unlock_global_table_log(); unlock_global_ddl_log();
set_part_info_exec_log_entry(part_info, exec_log_entry); set_part_info_exec_log_entry(part_info, exec_log_entry);
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} while (TRUE);
error:
release_part_info_log_entries(part_info->first_log_entry); release_part_info_log_entries(part_info->first_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
my_error(ER_TABLE_LOG_ERROR, MYF(0)); my_error(ER_DDL_LOG_ERROR, MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -5586,17 +5562,15 @@ write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
frm file. frm file.
*/ */
static static bool write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
bool
write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
{ {
TABLE_LOG_ENTRY table_log_entry; DDL_LOG_ENTRY ddl_log_entry;
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry; DDL_LOG_MEMORY_ENTRY *log_entry;
TABLE_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry; DDL_LOG_MEMORY_ENTRY *exec_log_entry= part_info->exec_log_entry;
char path[FN_LEN]; char path[FN_LEN];
char shadow_path[FN_LEN]; char shadow_path[FN_LEN];
TABLE_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry; DDL_LOG_MEMORY_ENTRY *old_first_log_entry= part_info->first_log_entry;
uint next_entry= 0; uint next_entry= 0;
DBUG_ENTER("write_log_final_change_partition"); DBUG_ENTER("write_log_final_change_partition");
@ -5605,36 +5579,35 @@ write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
lpt->table_name, ""); lpt->table_name, "");
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db, build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
lpt->table_name, "#"); lpt->table_name, "#");
lock_global_table_log(); lock_global_ddl_log();
do
{
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path,
TRUE)) TRUE))
break; goto error;
if (write_log_changed_partitions(lpt, &next_entry, (const char*)path)) if (write_log_changed_partitions(lpt, &next_entry, (const char*)path))
break; goto error;
if (write_log_replace_delete_frm(lpt, 0UL, path, shadow_path, FALSE)) if (write_log_replace_delete_frm(lpt, 0UL, path, shadow_path, FALSE))
break; goto error;
log_entry= part_info->first_log_entry; log_entry= part_info->first_log_entry;
part_info->frm_log_entry= log_entry; part_info->frm_log_entry= log_entry;
if (write_execute_table_log_entry(log_entry->entry_pos, if (write_execute_ddl_log_entry(log_entry->entry_pos,
FALSE, &exec_log_entry)) FALSE, &exec_log_entry))
break; goto error;
release_part_info_log_entries(old_first_log_entry); release_part_info_log_entries(old_first_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} while (TRUE);
error:
release_part_info_log_entries(part_info->first_log_entry); release_part_info_log_entries(part_info->first_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
part_info->first_log_entry= old_first_log_entry; part_info->first_log_entry= old_first_log_entry;
part_info->frm_log_entry= NULL; part_info->frm_log_entry= NULL;
my_error(ER_TABLE_LOG_ERROR, MYF(0)); my_error(ER_DDL_LOG_ERROR, MYF(0));
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/* /*
Remove entry from table log and release resources for others to use Remove entry from ddl log and release resources for others to use
SYNOPSIS SYNOPSIS
write_log_completed() write_log_completed()
@ -5644,37 +5617,30 @@ write_log_final_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
FALSE Success FALSE Success
*/ */
static static void write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt,
void bool dont_crash)
write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, bool dont_crash)
{ {
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
uint count_loop= 0; uint count_loop= 0;
bool not_success; bool not_success;
TABLE_LOG_MEMORY_ENTRY *log_entry= part_info->exec_log_entry; DDL_LOG_MEMORY_ENTRY *log_entry= part_info->exec_log_entry;
DBUG_ENTER("write_log_completed"); DBUG_ENTER("write_log_completed");
DBUG_ASSERT(log_entry); DBUG_ASSERT(log_entry);
lock_global_table_log(); lock_global_ddl_log();
do if (write_execute_ddl_log_entry(0UL, TRUE, &log_entry))
{
if (!(not_success= write_execute_table_log_entry(0UL, TRUE, &log_entry)))
break;
my_sleep(1);
} while (count_loop++ < 20);
if (not_success && !dont_crash)
{ {
/* /*
Failed to write 20 consecutive attempts to write. Bad... Failed to write, Bad...
We have completed the operation but have log records to REMOVE We have completed the operation but have log records to REMOVE
stuff that shouldn't be removed. What clever things could one do stuff that shouldn't be removed. What clever things could one do
here? here?
*/ */
abort(); ;
} }
release_part_info_log_entries(part_info->first_log_entry); release_part_info_log_entries(part_info->first_log_entry);
release_part_info_log_entries(part_info->exec_log_entry); release_part_info_log_entries(part_info->exec_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
part_info->exec_log_entry= NULL; part_info->exec_log_entry= NULL;
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -5690,14 +5656,12 @@ write_log_completed(ALTER_PARTITION_PARAM_TYPE *lpt, bool dont_crash)
NONE NONE
*/ */
static static void release_log_entries(partition_info *part_info)
void
release_log_entries(partition_info *part_info)
{ {
lock_global_table_log(); lock_global_ddl_log();
release_part_info_log_entries(part_info->first_log_entry); release_part_info_log_entries(part_info->first_log_entry);
release_part_info_log_entries(part_info->exec_log_entry); release_part_info_log_entries(part_info->exec_log_entry);
unlock_global_table_log(); unlock_global_ddl_log();
part_info->first_log_entry= NULL; part_info->first_log_entry= NULL;
part_info->exec_log_entry= NULL; part_info->exec_log_entry= NULL;
} }
@ -5713,43 +5677,41 @@ release_log_entries(partition_info *part_info)
NONE NONE
*/ */
void void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt,
handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, bool not_completed, bool not_completed,
bool drop_partition, bool frm_install) bool drop_partition,
bool frm_install)
{ {
partition_info *part_info= lpt->part_info; partition_info *part_info= lpt->part_info;
DBUG_ENTER("handle_alter_part_error"); DBUG_ENTER("handle_alter_part_error");
if (!part_info->first_log_entry && if (!part_info->first_log_entry &&
execute_table_log_entry(part_info->first_log_entry->entry_pos)) execute_ddl_log_entry(part_info->first_log_entry->entry_pos))
{ {
/* /*
We couldn't recover from error, most likely manual interaction is required. We couldn't recover from error, most likely manual interaction
is required.
*/ */
write_log_completed(lpt, FALSE); write_log_completed(lpt, FALSE);
release_log_entries(part_info); release_log_entries(part_info);
if (not_completed) if (not_completed)
{ {
char *text1=
(char*)"Operation was unsuccessful, table is still intact, ";
if (drop_partition) if (drop_partition)
{ {
/* Table is still ok, but we left a shadow frm file behind. */ /* Table is still ok, but we left a shadow frm file behind. */
char *text2=
(char*)"but it is possible that a shadow frm file was left behind";
push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1, push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1,
"%s \n %s", text1, text2); "%s %s",
"Operation was unsuccessful, table is still intact,",
"but it is possible that a shadow frm file was left behind");
} }
else else
{ {
char *text2=
(char*)"but it is possible that a shadow frm file was left behind.";
char *text3=
(char*)"It is also possible that temporary partitions are left behind, ";
char *text4=
(char*)"these could be empty or more or less filled with records";
push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1, push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1,
"%s \n %s \n %s \n %s", text1, text2, text3, text4); "%s %s %s %s",
"Operation was unsuccessful, table is still intact,",
"but it is possible that a shadow frm file was left behind.",
"It is also possible that temporary partitions are left behind,",
"these could be empty or more or less filled with records");
} }
} }
else else
@ -5760,48 +5722,39 @@ handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, bool not_completed,
Failed during install of shadow frm file, table isn't intact Failed during install of shadow frm file, table isn't intact
and dropped partitions are still there and dropped partitions are still there
*/ */
char *text1=
(char*)"Failed during alter of partitions, table is no longer intact, ";
char *text2=
(char*)"The frm file is in an unknown state, and a backup";
char *text3=
(char*)" is required.";
push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1, push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1,
"%s \n %s%s\n", text1, text2, text3); "%s %s %s",
"Failed during alter of partitions, table is no longer intact.",
"The frm file is in an unknown state, and a backup",
"is required.");
} }
else if (drop_partition) else if (drop_partition)
{ {
/* /*
Table is ok, we have switched to new table but left dropped partitions Table is ok, we have switched to new table but left dropped
still in their places. We remove the log records and ask the user to partitions still in their places. We remove the log records and
perform the action manually. We remove the log records and ask the user ask the user to perform the action manually. We remove the log
to perform the action manually. records and ask the user to perform the action manually.
*/ */
char *text1=
(char*)"Failed during drop of partitions, table is intact, ";
char *text2=
(char*)"Manual drop of remaining partitions is required";
push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1, push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1,
"%s\n%s", text1, text2); "%s %s",
"Failed during drop of partitions, table is intact.",
"Manual drop of remaining partitions is required");
} }
else else
{ {
/* /*
We failed during renaming of partitions. The table is most certainly in We failed during renaming of partitions. The table is most
a very bad state so we give user warning and disable the table by certainly in a very bad state so we give user warning and disable
writing an ancient frm version into it. the table by writing an ancient frm version into it.
*/ */
char *text1=
(char*)"Failed during renaming of partitions. We are now in a position";
char *text2=
(char*)" where table is not reusable";
char *text3=
(char*)"Table is disabled by writing ancient frm file version into it";
push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1, push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1,
"%s%s\n%s", text1, text2, text3); "%s %s %s",
"Failed during renaming of partitions. We are now in a position",
"where table is not reusable",
"Table is disabled by writing ancient frm file version into it");
} }
} }
} }
else else
{ {
@ -5824,8 +5777,9 @@ handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, bool not_completed,
even though we reported an error the operation was successfully even though we reported an error the operation was successfully
completed. completed.
*/ */
push_warning(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1, push_warning_printf(lpt->thd, MYSQL_ERROR::WARN_LEVEL_WARN, 1,"%s %s",
"Operation was successfully completed after failure of normal operation"); "Operation was successfully completed by failure handling,",
"after failure of normal operation");
} }
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
@ -5999,7 +5953,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
0) Write an entry that removes the shadow frm file if crash occurs 0) Write an entry that removes the shadow frm file if crash occurs
1) Write the new frm file as a shadow frm 1) Write the new frm file as a shadow frm
2) Write the table log to ensure that the operation is completed 2) Write the ddl log to ensure that the operation is completed
even in the presence of a MySQL Server crash even in the presence of a MySQL Server crash
3) Lock the table in TL_WRITE_ONLY to ensure all other accesses to 3) Lock the table in TL_WRITE_ONLY to ensure all other accesses to
the table have completed the table have completed
@ -6010,8 +5964,8 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
where crashes make strange things occur. In this placement it can where crashes make strange things occur. In this placement it can
happen that the ALTER TABLE DROP PARTITION gets performed in the happen that the ALTER TABLE DROP PARTITION gets performed in the
master but not in the slaves if we have a crash, after writing the master but not in the slaves if we have a crash, after writing the
table log but before writing the binlog. A solution to this would ddl log but before writing the binlog. A solution to this would
require writing the statement first in the table log and then require writing the statement first in the ddl log and then
when recovering from the crash read the binlog and insert it into when recovering from the crash read the binlog and insert it into
the binlog if not written already. the binlog if not written already.
5) Install the previously written shadow frm file 5) Install the previously written shadow frm file
@ -6019,7 +5973,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
reached the abort lock do that before downgrading the lock. reached the abort lock do that before downgrading the lock.
7) Prepare MyISAM handlers for drop of partitions 7) Prepare MyISAM handlers for drop of partitions
8) Drop the partitions 8) Drop the partitions
9) Remove entries from table log 9) Remove entries from ddl log
10) Wait until all accesses using the old frm file has completed 10) Wait until all accesses using the old frm file has completed
11) Complete query 11) Complete query
@ -6033,7 +5987,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
write_log_drop_partition(lpt) || write_log_drop_partition(lpt) ||
ERROR_INJECT_CRASH("crash_drop_partition_3") || ERROR_INJECT_CRASH("crash_drop_partition_3") ||
((not_completed= FALSE), FALSE) || ((not_completed= FALSE), FALSE) ||
(abort_and_upgrade_lock(lpt, FALSE), FALSE) || (abort_and_upgrade_lock(lpt), FALSE) ||
((!thd->lex->no_write_to_binlog) && ((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE, (write_bin_log(thd, FALSE,
thd->query, thd->query_length), FALSE)) || thd->query, thd->query_length), FALSE)) ||
@ -6070,7 +6024,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
0) Write an entry that removes the shadow frm file if crash occurs 0) Write an entry that removes the shadow frm file if crash occurs
1) Write the new frm file as a shadow frm file 1) Write the new frm file as a shadow frm file
2) Log the changes to happen in table log 2) Log the changes to happen in ddl log
2) Add the new partitions 2) Add the new partitions
3) Lock all partitions in TL_WRITE_ONLY to ensure that no users 3) Lock all partitions in TL_WRITE_ONLY to ensure that no users
are still using the old partitioning scheme. Wait until all are still using the old partitioning scheme. Wait until all
@ -6082,7 +6036,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
6) Install the new frm file of the table where the partitions are 6) Install the new frm file of the table where the partitions are
added to the table. added to the table.
7) Wait until all accesses using the old frm file has completed 7) Wait until all accesses using the old frm file has completed
8) Remove entries from table log 8) Remove entries from ddl log
9) Complete query 9) Complete query
*/ */
if (write_log_add_change_partition(lpt) || if (write_log_add_change_partition(lpt) ||
@ -6091,7 +6045,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
ERROR_INJECT_CRASH("crash_add_partition_2") || ERROR_INJECT_CRASH("crash_add_partition_2") ||
mysql_change_partitions(lpt) || mysql_change_partitions(lpt) ||
ERROR_INJECT_CRASH("crash_add_partition_3") || ERROR_INJECT_CRASH("crash_add_partition_3") ||
(abort_and_upgrade_lock(lpt, FALSE), FALSE) || (abort_and_upgrade_lock(lpt), FALSE) ||
((!thd->lex->no_write_to_binlog) && ((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE, (write_bin_log(thd, FALSE,
thd->query, thd->query_length), FALSE)) || thd->query, thd->query_length), FALSE)) ||
@ -6174,7 +6128,7 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
write_log_final_change_partition(lpt) || write_log_final_change_partition(lpt) ||
ERROR_INJECT_CRASH("crash_change_partition_4") || ERROR_INJECT_CRASH("crash_change_partition_4") ||
((not_completed= FALSE), FALSE) || ((not_completed= FALSE), FALSE) ||
(abort_and_upgrade_lock(lpt, FALSE), FALSE) || (abort_and_upgrade_lock(lpt), FALSE) ||
((!thd->lex->no_write_to_binlog) && ((!thd->lex->no_write_to_binlog) &&
(write_bin_log(thd, FALSE, (write_bin_log(thd, FALSE,
thd->query, thd->query_length), FALSE)) || thd->query, thd->query_length), FALSE)) ||

File diff suppressed because it is too large Load Diff

View File

@ -667,8 +667,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
#endif #endif
next_chunk+= 5 + partition_info_len; next_chunk+= 5 + partition_info_len;
} }
#if 0 #if 1
if (share->mysql_version == 50106) if (share->mysql_version == 50106 ||
share->mysql_version == 50107)
{ {
/* /*
Partition state array was here in version 5.1.6, this code makes Partition state array was here in version 5.1.6, this code makes