1
0
mirror of https://github.com/MariaDB/server.git synced 2026-01-06 05:22:24 +03:00

WL 2826: Error handling for ALTER TABLE for partitioning

Step 14: First version of table log for add/Drop partition


sql/ha_partition.cc:
  Moved create partition name code to sql_partition.cc
sql/handler.h:
  Added entries in partition_info to keep track of table log entries
sql/mysql_priv.h:
  Moved create partition name code to sql_partition.cc
sql/sql_partition.cc:
  Moved create partition name code to sql_partition.cc
  First version of table log for add/drop partition
sql/sql_table.cc:
  Add IO_SIZE to table log header
This commit is contained in:
unknown
2006-02-09 11:05:05 +01:00
parent e5200bc17d
commit 836912d1c7
5 changed files with 321 additions and 86 deletions

View File

@@ -5063,6 +5063,50 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
}
/*
Insert log entry into list
SYNOPSIS
insert_part_info_log_entry_list()
log_entry
RETURN VALUES
NONE
*/
static
void
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;
part_info->first_log_entry= log_entry;
}
/*
Release all log entries for this partition info struct
SYNOPSIS
release_part_info_log_entries()
first_log_entry First log entry in list to release
RETURN VALUES
NONE
*/
static
void
release_part_info_log_entries(TABLE_LOG_MEMORY_ENTRY *log_entry)
{
DBUG_ENTER("release_part_info_log_entries");
while (log_entry)
{
release_table_log_memory_entry(log_entry);
log_entry= log_entry->next_log_entry;
}
part_info->first_log_entry= NULL;
DBUG_VOID_RETURN;
}
/*
Write the log entry to ensure that the shadow frm file is removed at
crash.
@@ -5082,11 +5126,111 @@ static bool mysql_drop_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
bool
write_log_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt, bool install_frm)
{
TABLE_LOG_ENTRY table_log_entry;
partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry;
char shadow_path[FN_LEN];
DBUG_ENTER("write_log_shadow_frm");
lock_global_table_log();
do
{
build_table_filename(shadow_path, sizeof(shadow_path), lpt->db,
lpt->table_name, "#");
table_log_entry.action_type= 'd';
table_log_entry.next_entry= 0;
table_log_entry.handler_type= "frm";
table_log_entry.name= shadow_path;
if (write_table_log_entry(&table_log_entry, &log_entry))
break;
insert_part_info_log_entry_list(part_info, log_entry);
if (write_execute_table_log_entry(log_entry->entry_pos, &log_entry))
break;
part_info->exec_log_entry= log_entry;
unlock_global_table_log();
DBUG_RETURN(FALSE);
} while (TRUE);
release_part_info_log_entries(part_info->first_log_entry);
unlock_global_table_log();
DBUG_RETURN(TRUE);
}
/*
Log dropped partitions
SYNOPSIS
write_log_dropped_partitions()
lpt Struct containing parameters
RETURN VALUES
TRUE Error
FALSE Success
*/
static
bool
write_log_dropped_partitions(ALTER_PARTITION_PARAM_TYPE *lpt,
uint *next_entry,
const char *path)
{
TABLE_LOG_ENTRY table_log_entry;
partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry;
char tmp_path[FN_LEN];
List_iterator<partition_element> part_it(part_info->partitions);
uint no_elements= part_info->partitions.elements;
DBUG_ENTER("write_log_dropped_partitions");
table_log_entry.action_type= 'd';
do
{
partition_element part_elem= part_it++;
if (part_elem->part_state == PART_TO_BE_DROPPED ||
part_elem->part_state == PART_TO_BE_ADDED)
{
if (is_sub_partitioned(part_info))
{
List_iterator<partition_element> sub_it(part_elem->subpartitions);
uint no_subparts= part_info->no_subparts;
do
{
partition_element *sub_elem= sub_it++;
table_log_entry.next_entry= *next_entry;
table_log_entry.handler_type=
ha_resolve_storage_engine_name(sub_elem->engine_type);
create_subpartition_name(tmp_path, path,
part_elem->partition_name,
sub_elem->partition_name,
NORMAL_PART_NAME);
table_log_entry.name= tmp_path;
if (write_table_log_entry(&table_log_entry, &log_entry))
{
DBUG_RETURN(TRUE);
}
*next_entry= log_entry->entry_pos;
insert_part_info_log_entry_list(part_info, log_entry);
} while (++i < no_subparts);
}
else
{
table_log_entry.next_entry= *next_entry;
table_log_entry.handler_type=
ha_resolve_storage_engine_name(part_elem->engine_type);
create_partition_name(tmp_path, path,
part_elem->partition_name,
NORMAL_PART_NAME, TRUE);
table_log_entry.name= tmp_path;
if (write_table_log_entry(&table_log_entry, &log_entry))
{
DBUG_RETURN(TRUE);
}
*next_entry= log_entry->entry_pos;
insert_part_info_log_entry_list(part_info, log_entry);
}
}
} while (++i < no_elements);
DBUG_RETURN(FALSE);
error:
}
@@ -5108,11 +5252,47 @@ write_log_shadow_frm(ALTER_PARTITION_PARAM_TYPE *lpt, bool install_frm)
bool
write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
{
TABLE_LOG_ENTRY table_log_entry;
partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry;
char tmp_path[FN_LEN];
char path[FN_LEN];
uint next_entry= 0;
TABLE_LOG_MEMORY_ENTRY *old_log_entry= part_info->first_log_entry;
DBUG_ENTER("write_log_drop_partition");
part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path), lpt->db,
lpt->table_name, "");
lock_global_table_log();
do
{
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path))
break;
/*
At first we write an entry that installs the new frm file
*/
build_table_filename(tmp_path, sizeof(tmp_path), lpt->db,
lpt->table_name, "#");
table_log_entry.action_type= 'r';
table_log_entry.next_entry= next_entry;
table_log_entry.handler_type= "frm";
table_log_entry.name= path;
table_log_entry.from_name= tmp_path;
if (write_table_log_entry(&table_log_entry, &log_entry))
break;
insert_part_info_log_entry_list(part_info, log_entry);
log_entry= part_info->exec_log_entry;
if (write_execute_table_log_entry(log_entry->entry_pos, NULL))
break;
release_part_info_log_entries(old_first_log_entry);
unlock_global_table_log();
DBUG_RETURN(FALSE);
} while (TRUE);
release_part_info_log_entries(part_info->first_log_entry);
part_info->first_log_entry= old_log_entry;
unlock_global_table_log();
DBUG_RETURN(FALSE);
DBUG_RETURN(TRUE);
}
@@ -5129,16 +5309,48 @@ write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
DESCRIPTION
Prepare entries to the table log indicating all partitions to drop and to
remove the shadow frm file.
The removal of the shadow frm file is already in the log file so we only
need to link the new entries to the existing and carefully ensure that
the new linked list has first the dropped partitions and then the
drop of the shadow frm file.
We always inject entries backwards in the list in the table log since we
don't know the entry position until we have written it.
*/
bool
write_log_add_partition(ALTER_PARTITION_PARAM_TYPE *lpt)
{
DBUG_ENTER("write_log_add_partition");
TABLE_LOG_ENTRY table_log_entry;
partition_info *part_info= lpt->part_info;
TABLE_LOG_MEMORY_ENTRY *log_entry;
char tmp_path[FN_LEN];
char path[FN_LEN];
TABLE_LOG_MEMORY_ENTRY *old_log_entry= part_info->first_log_entry;
uint next_entry= old_log_entry->entry_pos;
/* Ensure we linked the existing entries at the back */
DBUG_ENTER("write_log_add_partition");
part_info->first_log_entry= NULL;
build_table_filename(path, sizeof(path), lpt->db,
lpt->table_name, "");
lock_global_table_log();
do
{
if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path))
break;
log_entry= part_info->first_log_entry;
/* Ensure first entry is the last dropped partition */
if (write_execute_table_log_entry(log_entry->entry_pos, NULL))
break;
release_part_info_log_entries(old_first_log_entry);
unlock_global_table_log();
DBUG_RETURN(FALSE);
} while (TRUE);
release_part_info_log_entries(part_info->first_log_entry);
part_info->first_log_entry= old_log_entry;
unlock_global_table_log();
DBUG_RETURN(FALSE);
DBUG_RETURN(TRUE);
}
@@ -6182,5 +6394,87 @@ static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR *part_iter)
part_iter->field_vals.start++;
return part_iter->part_info->get_subpartition_id(part_iter->part_info);
}
/*
Create partition names
SYNOPSIS
create_partition_name()
out:out Created partition name string
in1 First part
in2 Second part
name_variant Normal, temporary or renamed partition name
RETURN VALUE
NONE
DESCRIPTION
This method is used to calculate the partition name, service routine to
the del_ren_cre_table method.
*/
void
create_partition_name(char *out, const char *in1,
const char *in2, uint name_variant,
bool translate)
{
char transl_part_name[FN_REFLEN];
const char *transl_part;
if (translate)
{
tablename_to_filename(in2, transl_part_name, FN_REFLEN);
transl_part= transl_part_name;
}
else
transl_part= in2;
if (name_variant == NORMAL_PART_NAME)
strxmov(out, in1, "#P#", transl_part, NullS);
else if (name_variant == TEMP_PART_NAME)
strxmov(out, in1, "#P#", transl_part, "#TMP#", NullS);
else if (name_variant == RENAMED_PART_NAME)
strxmov(out, in1, "#P#", transl_part, "#REN#", NullS);
}
/*
Create subpartition name
SYNOPSIS
create_subpartition_name()
out:out Created partition name string
in1 First part
in2 Second part
in3 Third part
name_variant Normal, temporary or renamed partition name
RETURN VALUE
NONE
DESCRIPTION
This method is used to calculate the subpartition name, service routine to
the del_ren_cre_table method.
*/
void
create_subpartition_name(char *out, const char *in1,
const char *in2, const char *in3,
uint name_variant)
{
char transl_part_name[FN_REFLEN], transl_subpart_name[FN_REFLEN];
tablename_to_filename(in2, transl_part_name, FN_REFLEN);
tablename_to_filename(in3, transl_subpart_name, FN_REFLEN);
if (name_variant == NORMAL_PART_NAME)
strxmov(out, in1, "#P#", transl_part_name,
"#SP#", transl_subpart_name, NullS);
else if (name_variant == TEMP_PART_NAME)
strxmov(out, in1, "#P#", transl_part_name,
"#SP#", transl_subpart_name, "#TMP#", NullS);
else if (name_variant == RENAMED_PART_NAME)
strxmov(out, in1, "#P#", transl_part_name,
"#SP#", transl_subpart_name, "#REN#", NullS);
}
#endif