Commit 3928d962 authored by unknown's avatar unknown
Browse files

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



sql/ha_partition.cc:
  Loads of review comments fixed
  inactivate => deactivate
  table log => ddl log
sql/mysql_priv.h:
  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
sql/mysqld.cc:
  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
sql/partition_element.h:
  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
sql/partition_info.h:
  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
sql/share/errmsg.txt:
  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
sql/sql_base.cc:
  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
sql/sql_partition.cc:
  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
sql/sql_table.cc:
  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
  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
sql/table.cc:
  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 81a463ad
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -701,7 +701,7 @@ int ha_partition::rename_partitions(const char *path)
          DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
          if ((ret_error= file->delete_table((const char *) norm_name_buff)))
            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;
          else
            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));
        if ((ret_error= file->delete_table((const char *) norm_name_buff)))
          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;
        else
          part_elem->log_entry= NULL; /* Indicate success */
      }
    } while (++i < temp_partitions);
    VOID(sync_table_log());
    VOID(sync_ddl_log());
  }
  i= 0;
  do
@@ -771,9 +771,9 @@ int ha_partition::rename_partitions(const char *path)
            DBUG_PRINT("info", ("Delete subpartition %s", norm_name_buff));
            if ((ret_error= file->delete_table((const char *) norm_name_buff)))
              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;
            VOID(sync_table_log());
            VOID(sync_ddl_log());
          }
          file= m_new_file[part];
          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,
                                             (const char *) norm_name_buff)))
            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;
          else
            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));
          if ((ret_error= file->delete_table((const char *) norm_name_buff)))
            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;
          VOID(sync_table_log());
          VOID(sync_ddl_log());
        }
        file= m_new_file[i];
        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,
                                           (const char *) norm_name_buff)))
          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;
        else
          part_elem->log_entry= NULL;
      }
    }
  } while (++i < no_parts);
  VOID(sync_table_log());
  VOID(sync_ddl_log());
  DBUG_RETURN(error);
}

+98 −35
Original line number Diff line number Diff line
@@ -631,9 +631,6 @@ struct Query_cache_query_flags

#else

#define SET_ERROR_INJECT_VALUE(x) \
  current_thd->error_inject_value= (x)

inline bool
my_error_inject_name(const char *dbug_str)
{
@@ -661,6 +658,43 @@ my_error_inject(int value)
  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) \
  DBUG_EVALUATE_IF(code, (abort(), 0), 0)
#define ERROR_INJECT_ACTION(code, action) \
@@ -1186,57 +1220,86 @@ typedef struct st_lock_param_type

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 *from_name;
  const char *handler_type;
  const char *handler_name;
  uint next_entry;
  uint entry_pos;
  char action_type;
  char entry_type;
  enum ddl_log_entry_code entry_type;
  enum ddl_log_action_code action_type;
  char phase;
  char not_used;
} TABLE_LOG_ENTRY;
} DDL_LOG_ENTRY;

typedef struct st_table_log_memory_entry
typedef struct st_ddl_log_memory_entry
{
  uint entry_pos;
  struct st_table_log_memory_entry *next_log_entry;
  struct st_table_log_memory_entry *prev_log_entry;
  struct st_table_log_memory_entry *next_active_log_entry;
} TABLE_LOG_MEMORY_ENTRY;
  struct st_ddl_log_memory_entry *next_log_entry;
  struct st_ddl_log_memory_entry *prev_log_entry;
  struct st_ddl_log_memory_entry *next_active_log_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,
                           TABLE_LOG_MEMORY_ENTRY **active_entry);
bool write_execute_table_log_entry(uint first_entry,
bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
                           DDL_LOG_MEMORY_ENTRY **active_entry);
bool write_execute_ddl_log_entry(uint first_entry,
                                   bool complete,
                                   TABLE_LOG_MEMORY_ENTRY **active_entry);
bool inactivate_table_log_entry(uint entry_no);
void release_table_log_memory_entry(TABLE_LOG_MEMORY_ENTRY *log_entry);
bool sync_table_log();
void release_table_log();
void execute_table_log_recovery();
bool execute_table_log_entry(uint first_entry);
void lock_global_table_log();
void unlock_global_table_log();
                                   DDL_LOG_MEMORY_ENTRY **active_entry);
bool deactivate_ddl_log_entry(uint entry_no);
void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry);
bool sync_ddl_log();
void release_ddl_log();
void execute_ddl_log_recovery();
bool execute_ddl_log_entry(uint first_entry);
void lock_global_ddl_log();
void unlock_global_ddl_log();

#define WFRM_WRITE_SHADOW 1
#define WFRM_INSTALL_SHADOW 2
#define WFRM_PACK_FRM 4
bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags);
bool abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt,
                            bool can_be_killed);
void abort_and_upgrade_lock(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);

+2 −2
Original line number Diff line number Diff line
@@ -3665,7 +3665,7 @@ we force server id to 2, but this MySQL server will not act as a slave.");
      unireg_abort(1);
    }
  }
  execute_table_log_recovery();
  execute_ddl_log_recovery();

  create_shutdown_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); */
  
  DBUG_PRINT("quit",("Exiting main thread"));
  release_table_log();
  release_ddl_log();

#ifndef __WIN__
#ifdef EXTRA_DEBUG2
+2 −2
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ enum partition_state {
  PART_IS_ADDED= 8
};

struct st_table_log_memory_entry;
struct st_ddl_log_memory_entry;

class partition_element :public Sql_alloc {
public:
@@ -46,7 +46,7 @@ class partition_element :public Sql_alloc {
  ulonglong part_min_rows;
  char *partition_name;
  char *tablespace_name;
  struct st_table_log_memory_entry *log_entry;
  struct st_ddl_log_memory_entry *log_entry;
  longlong range_value;
  char* part_comment;
  char* data_file_name;
+4 −4
Original line number Diff line number Diff line
@@ -28,7 +28,7 @@ typedef int (*get_part_id_func)(partition_info *part_info,
                                 longlong *func_value);
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
{
@@ -77,9 +77,9 @@ class partition_info : public Sql_alloc

  Item *item_free_list;

  struct st_table_log_memory_entry *first_log_entry;
  struct st_table_log_memory_entry *exec_log_entry;
  struct st_table_log_memory_entry *frm_log_entry;
  struct st_ddl_log_memory_entry *first_log_entry;
  struct st_ddl_log_memory_entry *exec_log_entry;
  struct st_ddl_log_memory_entry *frm_log_entry;

  /* 
    A bitmap of partitions used by the current query. 
Loading