Loading Docs/manual.texi +11 −3 Original line number Diff line number Diff line Loading @@ -17687,7 +17687,7 @@ to set the column to some other value than 0. @findex REPAIR TABLE @example REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] [USE_FRM] @end example @code{REPAIR TABLE} only works on @code{MyISAM} tables and is the same Loading Loading @@ -17724,6 +17724,10 @@ by row instead of creating one index at a time with sorting; This may be better than sorting on fixed-length keys if you have long @code{char()} keys that compress very good. As of MySQL 4.0.2 there is @code{USE_FRM} mode for @code{REPAIR}. Use it if @code{.MYI} file is missing or its header is corrupted. In this mode MySQL will recreate the table, using information from @code{.frm} file. This kind of repair cannot be done with @code{myisamchk}. @node Table maintenance, Maintenance regimen, REPAIR TABLE, Disaster Prevention @subsection Using @code{myisamchk} for Table Maintenance and Crash Recovery Loading Loading @@ -18019,8 +18023,7 @@ If you have lots of memory, you should increase the size of @code{key_buffer_size}! @item -n or --sort-recover Force @code{myisamchk} to use sorting to resolve the keys even if the temporary files should be very big. This will not have any effect if you have full-text keys in the table. temporary files should be very big. @item --character-sets-dir=... Directory where character sets are stored. Loading Loading @@ -18388,6 +18391,9 @@ a copy in case something goes wrong.) Go back to Stage 2. @code{myisamchk -r -q} should work now. (This shouldn't be an endless loop.) As of MySQL 4.0.2 you can also use @code{REPAIR ... USE_FRM} that does the whole procedure automatically. @noindent @strong{Stage 4: Very difficult repair} Loading Loading @@ -48764,6 +48770,8 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @item Fixed bug in UNION's with last offset being transposed to total result set @item @code{REPAIR ... USE_FRM} added. @item Fixed that DEFAULT_SELECT_LIMIT is always imposed on UNION's result set @item Fixed that some SELECT options can appear only in the first SELECT include/myisam.h +6 −0 Original line number Diff line number Diff line Loading @@ -295,6 +295,12 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def); #define T_QUICK (1L << 30) #define T_RETRY_WITHOUT_QUICK (1L << 31) /* flags used by myisamchk.c or/and ha_myisam.cc that are NOT passed * to mi_check.c follows: * */ #define TT_USEFRM 1 #define O_NEW_INDEX 1 /* Bits set in out_flag */ #define O_NEW_DATA 2 #define O_DATA_LOST 4 Loading sql/sql_table.cc +57 −4 Original line number Diff line number Diff line Loading @@ -870,7 +870,8 @@ static int send_check_errmsg(THD* thd, TABLE_LIST* table, return 1; } static int prepare_for_restore(THD* thd, TABLE_LIST* table) static int prepare_for_restore(THD* thd, TABLE_LIST* table, HA_CHECK_OPT *check_opt) { DBUG_ENTER("prepare_for_restore"); Loading Loading @@ -919,6 +920,57 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) DBUG_RETURN(0); } static int prepare_for_repair(THD* thd, TABLE_LIST* table, HA_CHECK_OPT *check_opt) { DBUG_ENTER("prepare_for_repair"); if (!(check_opt->sql_flags & TT_USEFRM)) { DBUG_RETURN(0); } else { char from[FN_REFLEN],to[FN_REFLEN]; char* db = thd->db ? thd->db : table->db; sprintf(from, "%s/%s/%s", mysql_real_data_home, db, table->name); fn_format(from, from, "", MI_NAME_DEXT, 4); sprintf(to,"%s-%lx_%lx", from, current_pid, thd->thread_id); my_rename(to, from, MYF(MY_WME)); if (lock_and_wait_for_table_name(thd,table)) DBUG_RETURN(-1); if (my_rename(from, to, MYF(MY_WME))) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "repair", "Failed renaming .MYD file")); } if (mysql_truncate(thd, table, 1)) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "repair", "Failed generating table from .frm file")); } if (my_rename(to, from, MYF(MY_WME))) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "repair", "Failed restoring .MYD file")); } } // now we should be able to open the partially repaired table // to finish the repair in the handler later on if (!(table->table = reopen_name_locked_table(thd, table))) unlock_table_name(thd, table); DBUG_RETURN(0); } static int mysql_admin_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt, Loading @@ -926,7 +978,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, thr_lock_type lock_type, bool open_for_modify, uint extra_open_options, int (*prepare_func)(THD *, TABLE_LIST *), int (*prepare_func)(THD *, TABLE_LIST *, HA_CHECK_OPT *), int (handler::*operator_func) (THD *, HA_CHECK_OPT *)) { Loading Loading @@ -960,7 +1012,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, packet->length(0); if (prepare_func) { switch ((*prepare_func)(thd, table)) { switch ((*prepare_func)(thd, table, check_opt)) { case 1: continue; // error, message written to net case -1: goto err; // error, message could be written to net default: ; // should be 0 otherwise Loading Loading @@ -1106,7 +1158,8 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_repair_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, 0, "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, &prepare_for_repair, &handler::repair)); } Loading sql/sql_yacc.yy +2 −2 Original line number Diff line number Diff line Loading @@ -1326,7 +1326,7 @@ mi_repair_types: mi_repair_type: QUICK { Lex->check_opt.flags|= T_QUICK; } | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } | USE_FRM { /*Lex->check_opt.flags|= T_USEFRM;*/ } | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; } analyze: ANALYZE_SYM table_or_tables Loading Loading
Docs/manual.texi +11 −3 Original line number Diff line number Diff line Loading @@ -17687,7 +17687,7 @@ to set the column to some other value than 0. @findex REPAIR TABLE @example REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] REPAIR TABLE tbl_name[,tbl_name...] [QUICK] [EXTENDED] [USE_FRM] @end example @code{REPAIR TABLE} only works on @code{MyISAM} tables and is the same Loading Loading @@ -17724,6 +17724,10 @@ by row instead of creating one index at a time with sorting; This may be better than sorting on fixed-length keys if you have long @code{char()} keys that compress very good. As of MySQL 4.0.2 there is @code{USE_FRM} mode for @code{REPAIR}. Use it if @code{.MYI} file is missing or its header is corrupted. In this mode MySQL will recreate the table, using information from @code{.frm} file. This kind of repair cannot be done with @code{myisamchk}. @node Table maintenance, Maintenance regimen, REPAIR TABLE, Disaster Prevention @subsection Using @code{myisamchk} for Table Maintenance and Crash Recovery Loading Loading @@ -18019,8 +18023,7 @@ If you have lots of memory, you should increase the size of @code{key_buffer_size}! @item -n or --sort-recover Force @code{myisamchk} to use sorting to resolve the keys even if the temporary files should be very big. This will not have any effect if you have full-text keys in the table. temporary files should be very big. @item --character-sets-dir=... Directory where character sets are stored. Loading Loading @@ -18388,6 +18391,9 @@ a copy in case something goes wrong.) Go back to Stage 2. @code{myisamchk -r -q} should work now. (This shouldn't be an endless loop.) As of MySQL 4.0.2 you can also use @code{REPAIR ... USE_FRM} that does the whole procedure automatically. @noindent @strong{Stage 4: Very difficult repair} Loading Loading @@ -48764,6 +48770,8 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @item Fixed bug in UNION's with last offset being transposed to total result set @item @code{REPAIR ... USE_FRM} added. @item Fixed that DEFAULT_SELECT_LIMIT is always imposed on UNION's result set @item Fixed that some SELECT options can appear only in the first SELECT
include/myisam.h +6 −0 Original line number Diff line number Diff line Loading @@ -295,6 +295,12 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def); #define T_QUICK (1L << 30) #define T_RETRY_WITHOUT_QUICK (1L << 31) /* flags used by myisamchk.c or/and ha_myisam.cc that are NOT passed * to mi_check.c follows: * */ #define TT_USEFRM 1 #define O_NEW_INDEX 1 /* Bits set in out_flag */ #define O_NEW_DATA 2 #define O_DATA_LOST 4 Loading
sql/sql_table.cc +57 −4 Original line number Diff line number Diff line Loading @@ -870,7 +870,8 @@ static int send_check_errmsg(THD* thd, TABLE_LIST* table, return 1; } static int prepare_for_restore(THD* thd, TABLE_LIST* table) static int prepare_for_restore(THD* thd, TABLE_LIST* table, HA_CHECK_OPT *check_opt) { DBUG_ENTER("prepare_for_restore"); Loading Loading @@ -919,6 +920,57 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) DBUG_RETURN(0); } static int prepare_for_repair(THD* thd, TABLE_LIST* table, HA_CHECK_OPT *check_opt) { DBUG_ENTER("prepare_for_repair"); if (!(check_opt->sql_flags & TT_USEFRM)) { DBUG_RETURN(0); } else { char from[FN_REFLEN],to[FN_REFLEN]; char* db = thd->db ? thd->db : table->db; sprintf(from, "%s/%s/%s", mysql_real_data_home, db, table->name); fn_format(from, from, "", MI_NAME_DEXT, 4); sprintf(to,"%s-%lx_%lx", from, current_pid, thd->thread_id); my_rename(to, from, MYF(MY_WME)); if (lock_and_wait_for_table_name(thd,table)) DBUG_RETURN(-1); if (my_rename(from, to, MYF(MY_WME))) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "repair", "Failed renaming .MYD file")); } if (mysql_truncate(thd, table, 1)) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "repair", "Failed generating table from .frm file")); } if (my_rename(to, from, MYF(MY_WME))) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "repair", "Failed restoring .MYD file")); } } // now we should be able to open the partially repaired table // to finish the repair in the handler later on if (!(table->table = reopen_name_locked_table(thd, table))) unlock_table_name(thd, table); DBUG_RETURN(0); } static int mysql_admin_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt, Loading @@ -926,7 +978,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, thr_lock_type lock_type, bool open_for_modify, uint extra_open_options, int (*prepare_func)(THD *, TABLE_LIST *), int (*prepare_func)(THD *, TABLE_LIST *, HA_CHECK_OPT *), int (handler::*operator_func) (THD *, HA_CHECK_OPT *)) { Loading Loading @@ -960,7 +1012,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, packet->length(0); if (prepare_func) { switch ((*prepare_func)(thd, table)) { switch ((*prepare_func)(thd, table, check_opt)) { case 1: continue; // error, message written to net case -1: goto err; // error, message could be written to net default: ; // should be 0 otherwise Loading Loading @@ -1106,7 +1158,8 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_repair_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, 0, "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, &prepare_for_repair, &handler::repair)); } Loading
sql/sql_yacc.yy +2 −2 Original line number Diff line number Diff line Loading @@ -1326,7 +1326,7 @@ mi_repair_types: mi_repair_type: QUICK { Lex->check_opt.flags|= T_QUICK; } | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } | USE_FRM { /*Lex->check_opt.flags|= T_USEFRM;*/ } | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; } analyze: ANALYZE_SYM table_or_tables Loading