对含唯一索引的表执行optimize table的时候,可能会遇到Optimize table fails with duplicate entry on UNIQUE KEY的错误下面分析下这个错误的原因 mysql在执行optimize table的时候,内部会转化成alter table 使用online ddl的方式执行alter table 命令 堆栈如下
mysqld!mysql_recreate_table(THD*, TABLE_LIST*, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_table.cc:10539) mysqld!mysql_admin_table(THD*, TABLE_LIST*, st_ha_check_opt*, char const*, thr_lock_type, bool, bool, unsigned int, int (*)(THD*, TABLE_LIST*, st_ha_check_opt*), int (handler::*)(THD*, st_ha_check_opt*), int (*)(THD*, TABLE_LIST*)) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_admin.cc:870) mysqld!Sql_cmd_optimize_table::execute(THD*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_admin.cc:1274) mysqld!mysql_execute_command(THD*, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:4845) mysqld!mysql_parse(THD*, Parser_state*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:5584) mysqld!dispatch_command(THD*, COM_DATA const*, enum_server_command) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:1491) mysqld!do_command(THD*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:1032) mysqld!::handle_connection(void *) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/conn_handler/connection_handler_per_thread.cc:313) mysqld!::pfs_spawn_thread(void *) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/perfschema/pfs.cc:2197) libsystem_pthread.dylib!_pthread_start (未知源:0) libsystem_pthread.dylib!thread_start (未知源:0)
alter期间,会创建新表,同步数据,应用row log中的增量数据,根据sql的类型执行对应的插入,删除,update操作,针对insert,执行row_log_table_apply_insert_low这个逻辑中调用的就是插入的函数,会判断是否存在冲突的键 堆栈
mysqld!row_log_table_apply_ops(que_thr_t*, row_merge_dup_t*, ut_stage_alter_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0log.cc:3128) mysqld!row_log_table_apply(que_thr_t*, dict_table_t*, TABLE*, ut_stage_alter_t*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/row/row0log.cc:3176) mysqld!ha_innobase::inplace_alter_table(TABLE*, Alter_inplace_info*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/innobase/handler/handler0alter.cc:6445) mysqld!handler::ha_inplace_alter_table(TABLE*, Alter_inplace_info*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/handler.h:3444) mysqld!mysql_inplace_alter_table(THD*, TABLE_LIST*, TABLE*, TABLE*, Alter_inplace_info*, enum_alter_inplace_result, MDL_request*, Alter_table_ctx*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_table.cc:7588) mysqld!mysql_alter_table(THD*, char const*, char const*, st_ha_create_information*, TABLE_LIST*, Alter_info*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_table.cc:9807) mysqld!mysql_recreate_table(THD*, TABLE_LIST*, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_table.cc:10539) mysqld!mysql_admin_table(THD*, TABLE_LIST*, st_ha_check_opt*, char const*, thr_lock_type, bool, bool, unsigned int, int (*)(THD*, TABLE_LIST*, st_ha_check_opt*), int (handler::*)(THD*, st_ha_check_opt*), int (*)(THD*, TABLE_LIST*)) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_admin.cc:870) mysqld!Sql_cmd_optimize_table::execute(THD*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_admin.cc:1274) mysqld!mysql_execute_command(THD*, bool) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:4845) mysqld!mysql_parse(THD*, Parser_state*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:5584) mysqld!dispatch_command(THD*, COM_DATA const*, enum_server_command) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:1491) mysqld!do_command(THD*) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/sql_parse.cc:1032) mysqld!::handle_connection(void *) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/sql/conn_handler/connection_handler_per_thread.cc:313) mysqld!::pfs_spawn_thread(void *) (/Users/xiaoyu.bai/Downloads/mysql-5.7.29/storage/perfschema/pfs.cc:2197) libsystem_pthread.dylib!_pthread_start (未知源:0) libsystem_pthread.dylib!thread_start (未知源:0)
