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
parent ac10cffe
...@@ -701,7 +701,7 @@ int ha_partition::rename_partitions(const char *path) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
......
...@@ -631,9 +631,6 @@ struct Query_cache_query_flags ...@@ -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) ...@@ -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 ...@@ -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);
......
...@@ -3665,7 +3665,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); ...@@ -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."); ...@@ -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
......
...@@ -36,7 +36,7 @@ enum partition_state { ...@@ -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: ...@@ -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;
......
...@@ -28,7 +28,7 @@ typedef int (*get_part_id_func)(partition_info *part_info, ...@@ -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: ...@@ -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.
......
...@@ -5826,5 +5826,5 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT ...@@ -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"
...@@ -6124,24 +6124,17 @@ bool is_equal(const LEX_STRING *a, const LEX_STRING *b) ...@@ -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;
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -667,8 +667,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, ...@@ -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
......
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