16 #include "sql_parse.h"
19 #include "sql_table.h"
21 #include "sql_alter.h"
22 #include "sql_partition.h"
25 #include "sql_truncate.h"
27 #include "sql_admin.h"
28 #include "sql_partition_admin.h"
29 #ifdef WITH_PARTITION_STORAGE_ENGINE
30 #include "ha_partition.h"
34 #ifndef WITH_PARTITION_STORAGE_ENGINE
38 DBUG_ENTER(
"Sql_cmd_partition_unsupported::execute");
40 my_error(ER_FEATURE_DISABLED, MYF(0),
"partitioning",
41 "--with-plugin-partition");
52 SELECT_LEX *select_lex= &lex->select_lex;
63 Alter_info alter_info(lex->alter_info, thd->mem_root);
64 ulong priv_needed= ALTER_ACL | DROP_ACL | INSERT_ACL | CREATE_ACL;
66 DBUG_ENTER(
"Sql_cmd_alter_table_exchange_partition::execute");
68 if (thd->is_fatal_error)
72 DBUG_ASSERT(select_lex->db);
74 DBUG_ASSERT(alter_info.flags & Alter_info::ALTER_EXCHANGE_PARTITION);
80 check_access(thd, priv_needed, first_table->next_local->db,
81 &first_table->next_local->grant.
privilege,
86 if (check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, FALSE))
90 DBUG_ASSERT(!create_info.data_file_name && !create_info.index_file_name);
92 thd->enable_slow_log= opt_log_slow_admin_statements;
93 DBUG_RETURN(exchange_partition(thd, first_table, &alter_info));
106 DBUG_ENTER(
"check_exchange_partition");
109 if (!part_table || !table)
111 my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0));
116 if (!part_table->part_info)
118 my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
121 if (table->part_info)
123 my_error(ER_PARTITION_EXCHANGE_PART_TABLE, MYF(0),
124 table->s->table_name.str);
128 if (part_table->file->ht != partition_hton)
134 my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
138 if (table->file->ht != part_table->part_info->default_engine_type)
140 my_error(ER_MIX_HANDLER_ERROR, MYF(0));
145 if (table->s->tmp_table != NO_TMP_TABLE)
147 my_error(ER_PARTITION_EXCHANGE_TEMP_TABLE, MYF(0),
148 table->s->table_name.str);
155 my_error(ER_PARTITION_EXCHANGE_FOREIGN_KEY, MYF(0),
156 table->s->table_name.str);
172 static bool compare_table_with_partition(THD *thd,
TABLE *table,
179 DBUG_ENTER(
"compare_table_with_partition");
181 bool metadata_equal=
false;
185 update_create_info_from_table(&table_create_info, table);
187 table->file->update_create_info(&table_create_info);
189 part_table->use_all_columns();
190 table->use_all_columns();
191 if (mysql_prepare_alter_table(thd, part_table, &part_create_info,
192 &part_alter_info, &part_alter_ctx))
194 my_error(ER_TABLES_DIFFERENT_METADATA, MYF(0));
198 part_create_info.db_type= part_table->part_info->default_engine_type;
203 part_create_info.auto_increment_value=
204 table_create_info.auto_increment_value;
208 enum row_type part_row_type= part_table->file->
get_row_type();
209 enum row_type table_row_type= table->file->
get_row_type();
210 if (part_row_type != table_row_type)
212 my_error(ER_PARTITION_EXCHANGE_DIFFERENT_OPTION, MYF(0),
216 part_create_info.
row_type= table->s->row_type;
225 if (mysql_compare_tables(table, &part_alter_info, &part_create_info,
228 my_error(ER_TABLES_DIFFERENT_METADATA, MYF(0));
232 DEBUG_SYNC(thd,
"swap_partition_after_compare_tables");
235 my_error(ER_TABLES_DIFFERENT_METADATA, MYF(0));
238 DBUG_ASSERT(table->s->db_create_options ==
239 part_table->s->db_create_options);
240 DBUG_ASSERT(table->s->db_options_in_use ==
241 part_table->s->db_options_in_use);
243 if (table_create_info.avg_row_length != part_create_info.avg_row_length)
245 my_error(ER_PARTITION_EXCHANGE_DIFFERENT_OPTION, MYF(0),
250 if (table_create_info.table_options != part_create_info.table_options)
252 my_error(ER_PARTITION_EXCHANGE_DIFFERENT_OPTION, MYF(0),
257 if (table->s->table_charset != part_table->s->table_charset)
259 my_error(ER_PARTITION_EXCHANGE_DIFFERENT_OPTION, MYF(0),
270 if (compare_partition_options(&table_create_info, part_elem))
315 static bool exchange_name_with_ddl_log(THD *thd,
317 const char *from_name,
318 const char *tmp_name,
325 bool error_set= FALSE;
327 DBUG_ENTER(
"exchange_name_with_ddl_log");
329 if (!(file= get_new_handler(NULL, thd->mem_root, ht)))
331 mem_alloc_error(
sizeof(
handler));
336 exchange_entry.entry_type= DDL_LOG_ENTRY_CODE;
337 exchange_entry.action_type= DDL_LOG_EXCHANGE_ACTION;
338 exchange_entry.next_entry= 0;
339 exchange_entry.name=
name;
340 exchange_entry.from_name= from_name;
341 exchange_entry.tmp_name= tmp_name;
342 exchange_entry.handler_name= ha_resolve_storage_engine_name(ht);
343 exchange_entry.phase= EXCH_PHASE_NAME_TO_TEMP;
351 DBUG_EXECUTE_IF(
"exchange_partition_fail_1",
goto err_no_action_written;);
352 DBUG_EXECUTE_IF(
"exchange_partition_abort_1", DBUG_SUICIDE(););
353 if (write_ddl_log_entry(&exchange_entry, &log_entry))
354 goto err_no_action_written;
356 DBUG_EXECUTE_IF(
"exchange_partition_fail_2",
goto err_no_execute_written;);
357 DBUG_EXECUTE_IF(
"exchange_partition_abort_2", DBUG_SUICIDE(););
358 if (write_execute_ddl_log_entry(log_entry->entry_pos, FALSE, &exec_log_entry))
359 goto err_no_execute_written;
371 DBUG_EXECUTE_IF(
"exchange_partition_fail_3",
372 my_error(ER_ERROR_ON_RENAME, MYF(0),
373 name, tmp_name, 0,
"n/a");
376 DBUG_EXECUTE_IF(
"exchange_partition_abort_3", DBUG_SUICIDE(););
379 char errbuf[MYSYS_STRERROR_SIZE];
380 my_error(ER_ERROR_ON_RENAME, MYF(0), name, tmp_name,
381 my_errno, my_strerror(errbuf,
sizeof(errbuf), my_errno));
385 DBUG_EXECUTE_IF(
"exchange_partition_fail_4",
goto err_rename;);
386 DBUG_EXECUTE_IF(
"exchange_partition_abort_4", DBUG_SUICIDE(););
387 if (deactivate_ddl_log_entry(log_entry->entry_pos))
391 DBUG_EXECUTE_IF(
"exchange_partition_fail_5",
392 my_error(ER_ERROR_ON_RENAME, MYF(0),
393 from_name, name, 0,
"n/a");
396 DBUG_EXECUTE_IF(
"exchange_partition_abort_5", DBUG_SUICIDE(););
399 char errbuf[MYSYS_STRERROR_SIZE];
400 my_error(ER_ERROR_ON_RENAME, MYF(0), from_name, name,
401 my_errno, my_strerror(errbuf,
sizeof(errbuf), my_errno));
405 DBUG_EXECUTE_IF(
"exchange_partition_fail_6",
goto err_rename;);
406 DBUG_EXECUTE_IF(
"exchange_partition_abort_6", DBUG_SUICIDE(););
407 if (deactivate_ddl_log_entry(log_entry->entry_pos))
411 DBUG_EXECUTE_IF(
"exchange_partition_fail_7",
412 my_error(ER_ERROR_ON_RENAME, MYF(0),
413 tmp_name, from_name, 0,
"n/a");
416 DBUG_EXECUTE_IF(
"exchange_partition_abort_7", DBUG_SUICIDE(););
419 char errbuf[MYSYS_STRERROR_SIZE];
420 my_error(ER_ERROR_ON_RENAME, MYF(0), tmp_name, from_name,
421 my_errno, my_strerror(errbuf,
sizeof(errbuf), my_errno));
425 DBUG_EXECUTE_IF(
"exchange_partition_fail_8",
goto err_rename;);
426 DBUG_EXECUTE_IF(
"exchange_partition_abort_8", DBUG_SUICIDE(););
427 if (deactivate_ddl_log_entry(log_entry->entry_pos))
431 DBUG_EXECUTE_IF(
"exchange_partition_fail_9",
goto err_rename;);
432 DBUG_EXECUTE_IF(
"exchange_partition_abort_9", DBUG_SUICIDE(););
443 (void) execute_ddl_log_entry(current_thd, log_entry->entry_pos);
446 (void) write_execute_ddl_log_entry(0, TRUE, &exec_log_entry);
448 (void) release_ddl_log_memory_entry(exec_log_entry);
449 err_no_execute_written:
451 (void) release_ddl_log_memory_entry(log_entry);
452 err_no_action_written:
456 my_error(ER_DDL_LOG_ERROR, MYF(0));
483 bool Sql_cmd_alter_table_exchange_partition::
486 TABLE *part_table, *swap_table;
490 char *partition_name;
491 char temp_name[FN_REFLEN+1];
492 char part_file_name[FN_REFLEN+1];
493 char swap_file_name[FN_REFLEN+1];
494 char temp_file_name[FN_REFLEN+1];
496 uint part_file_name_len;
502 DBUG_ENTER(
"mysql_exchange_partition");
503 DBUG_ASSERT(alter_info->flags & Alter_info::ALTER_EXCHANGE_PARTITION);
506 swap_table_list= table_list->next_local;
507 if (check_if_log_table(swap_table_list->db_length, swap_table_list->db,
508 swap_table_list->table_name_length,
509 swap_table_list->table_name, 0))
511 my_error(ER_WRONG_USAGE, MYF(0),
"PARTITION",
"log table");
531 table_list->mdl_request.
set_type(MDL_SHARED_NO_WRITE);
532 if (
open_tables(thd, &table_list, &table_counter, 0,
533 &alter_prelocking_strategy))
536 part_table= table_list->table;
537 swap_table= swap_table_list->table;
539 if (check_exchange_partition(swap_table, part_table))
543 partition_name= alter_info->partition_names.head();
544 if (table_list->table->part_info->
545 set_named_partition_bitmap(partition_name, strlen(partition_name)))
548 if (
lock_tables(thd, table_list, table_counter, 0))
552 table_hton= swap_table->file->ht;
554 THD_STAGE_INFO(thd, stage_verifying_table);
557 part_file_name_len= build_table_filename(part_file_name,
558 sizeof(part_file_name),
560 table_list->table_name,
562 build_table_filename(swap_file_name,
563 sizeof(swap_file_name),
565 swap_table_list->table_name,
568 my_snprintf(temp_name,
sizeof(temp_name),
"%sx-%lx_%lx",
570 if (lower_case_table_names)
571 my_casedn_str(files_charset_info, temp_name);
572 build_table_filename(temp_file_name,
sizeof(temp_file_name),
573 table_list->next_local->db,
574 temp_name,
"", FN_IS_TMP);
576 if (!(part_elem= part_table->part_info->get_part_elem(partition_name,
581 my_error(ER_UNKNOWN_PARTITION, MYF(0), partition_name,
586 if (swap_part_id == NOT_A_PARTITION_ID)
588 DBUG_ASSERT(part_table->part_info->is_sub_partitioned());
589 my_error(ER_PARTITION_INSTEAD_OF_SUBPARTITION, MYF(0));
593 if (compare_table_with_partition(thd, swap_table, part_table, part_elem))
598 thd_proc_info(thd,
"verifying data with partition");
600 if (verify_data_with_partition(swap_table, part_table, swap_part_id))
607 swap_table_mdl_ticket= swap_table->mdl_ticket;
608 part_table_mdl_ticket= part_table->mdl_ticket;
620 DEBUG_SYNC(thd,
"swap_partition_after_wait");
625 DEBUG_SYNC(thd,
"swap_partition_before_rename");
627 if (exchange_name_with_ddl_log(thd, swap_file_name, part_file_name,
628 temp_file_name, table_hton))
636 (void) thd->locked_tables_list.reopen_tables(thd);
638 if ((error= write_bin_log(thd, TRUE, thd->query(), thd->query_length())))
644 (void) exchange_name_with_ddl_log(thd, part_file_name, swap_file_name,
645 temp_file_name, table_hton);
649 if (thd->locked_tables_mode)
651 if (swap_table_mdl_ticket)
653 if (part_table_mdl_ticket)
661 table_list->table= NULL;
662 table_list->next_local->table= NULL;
663 query_cache_invalidate3(thd, table_list, FALSE);
672 DBUG_ENTER(
"Sql_cmd_alter_table_analyze_partition::execute");
678 thd->lex->alter_info.flags|= Alter_info::ALTER_ADMIN_PARTITION;
689 DBUG_ENTER(
"Sql_cmd_alter_table_check_partition::execute");
695 thd->lex->alter_info.flags|= Alter_info::ALTER_ADMIN_PARTITION;
706 DBUG_ENTER(
"Alter_table_optimize_partition_statement::execute");
712 thd->lex->alter_info.flags|= Alter_info::ALTER_ADMIN_PARTITION;
723 DBUG_ENTER(
"Sql_cmd_alter_table_repair_partition::execute");
729 thd->lex->alter_info.flags|= Alter_info::ALTER_ADMIN_PARTITION;
741 ulong timeout= thd->variables.lock_wait_timeout;
742 TABLE_LIST *first_table= thd->lex->select_lex.table_list.first;
743 Alter_info *alter_info= &thd->lex->alter_info;
744 uint table_counter,
i;
747 DBUG_ENTER(
"Sql_cmd_alter_table_truncate_partition::execute");
753 thd->lex->alter_info.flags|= Alter_info::ALTER_ADMIN_PARTITION |
754 Alter_info::ALTER_TRUNCATE_PARTITION;
757 first_table->lock_type= TL_WRITE;
758 first_table->mdl_request.
set_type(MDL_EXCLUSIVE);
770 if (
open_tables(thd, &first_table, &table_counter, 0))
778 if (!first_table->table || first_table->view ||
779 first_table->table->s->db_type() != partition_hton)
781 my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
791 uint num_names= alter_info->partition_names.elements;
792 for (i= 0; i < num_names; i++)
794 char *partition_name= partition_names_it++;
795 String *str_partition_name=
new (thd->mem_root)
796 String(partition_name, system_charset_info);
797 if (!str_partition_name)
799 partition_names_list.push_back(str_partition_name);
801 first_table->partition_names= &partition_names_list;
802 if (first_table->table->part_info->set_partition_bitmaps(first_table))
805 if (
lock_tables(thd, first_table, table_counter, 0))
813 MDL_ticket *ticket= first_table->table->mdl_ticket;
814 if (thd->mdl_context.upgrade_shared_lock(ticket, MDL_EXCLUSIVE, timeout))
818 first_table->table_name, FALSE);
822 if ((error= partition->truncate_partition(alter_info, &binlog_stmt)))
832 if (error != HA_ERR_WRONG_COMMAND && binlog_stmt)
833 error|= write_bin_log(thd, !error, thd->query(), thd->query_length());
840 if (thd->locked_tables_mode)
847 DBUG_ASSERT(!first_table->next_local);
848 query_cache_invalidate3(thd, first_table, FALSE);