null+****@clear*****
null+****@clear*****
2012年 1月 24日 (火) 16:15:09 JST
Kouhei Sutou 2012-01-24 16:15:09 +0900 (Tue, 24 Jan 2012) New Revision: d40d7611d61db73d07b40a219c20a0c8a9a91cd2 Log: [wrapper] support repair. fixes #1191. Modified files: ha_mroonga.cc ha_mroonga.h test/sql/suite/mroonga_wrapper/r/repair_table.result test/sql/suite/mroonga_wrapper/t/repair_table.test Modified: ha_mroonga.cc (+59 -29) =================================================================== --- ha_mroonga.cc 2012-01-23 20:02:03 +0900 (fadcf15) +++ ha_mroonga.cc 2012-01-24 16:15:09 +0900 (dbe24b0) @@ -38,6 +38,7 @@ #include <pthread.h> #include <sys/types.h> #include <sys/stat.h> +#include <dirent.h> #include <unistd.h> #include "mrn_err.h" #include "mrn_table.h" @@ -2872,7 +2873,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked) if (error) DBUG_RETURN(error); - error = wrapper_open_indexes(name); + error = wrapper_open_indexes(name, thd_sql_command(ha_thd()) == SQLCOM_REPAIR); if (error) { grn_obj_unlink(ctx, grn_table); grn_table = NULL; @@ -2951,7 +2952,7 @@ int ha_mroonga::wrapper_open(const char *name, int mode, uint test_if_locked) DBUG_RETURN(error); } -int ha_mroonga::wrapper_open_indexes(const char *name) +int ha_mroonga::wrapper_open_indexes(const char *name, bool ignore_open_error) { int error; @@ -3005,7 +3006,13 @@ int ha_mroonga::wrapper_open_indexes(const char *name) grn_index_tables[i] = grn_ctx_get(ctx, index_name, strlen(index_name)); if (ctx->rc) { DBUG_PRINT("info", - ("mroonga: sql_command=%u", thd_sql_command(ha_thd()))); + ("mroonga: sql_command=%u", thd_sql_command(ha_thd()))); + if (ignore_open_error) + { + DBUG_PRINT("info", ("mroonga: continue")); + grn_index_tables[i] = NULL; + continue; + } error = ER_CANT_OPEN_FILE; my_message(error, ctx->errbuf, MYF(0)); free(key_min[i]); @@ -3027,6 +3034,12 @@ int ha_mroonga::wrapper_open_indexes(const char *name) if (ctx->rc) { DBUG_PRINT("info", ("mroonga: sql_command=%u", thd_sql_command(ha_thd()))); + if (ignore_open_error) + { + DBUG_PRINT("info", ("mroonga: continue")); + grn_index_columns[i] = NULL; + continue; + } error = ER_CANT_OPEN_FILE; my_message(error, ctx->errbuf, MYF(0)); free(key_min[i]); @@ -6528,6 +6541,40 @@ void ha_mroonga::clear_indexes() DBUG_VOID_RETURN; } +void ha_mroonga::remove_grn_obj_force(const char *name) +{ + MRN_DBUG_ENTER_METHOD(); + + grn_obj *obj = grn_ctx_get(ctx, name, strlen(name)); + if (obj) { + grn_obj_remove(ctx, obj); + } else { + grn_obj *db = grn_ctx_db(ctx); + grn_id id = grn_table_get(ctx, db, name, strlen(name)); + if (id) { + char path[MRN_MAX_PATH_SIZE]; + grn_obj_delete_by_id(ctx, db, id, GRN_TRUE); + if (grn_obj_path_by_id(ctx, db, id, path) == GRN_SUCCESS) { + size_t path_length = strlen(path); + DIR *dir = opendir("."); + if (dir) { + while (struct dirent *entry = readdir(dir)) { + if (entry->d_type != DT_REG) { + continue; + } + if (strncmp(entry->d_name, path, path_length) == 0) { + unlink(entry->d_name); + } + } + closedir(dir); + } + } + } + } + + DBUG_VOID_RETURN; +} + grn_obj *ha_mroonga::find_tokenizer(const char *name, int name_length) { MRN_DBUG_ENTER_METHOD(); @@ -8550,7 +8597,6 @@ int ha_mroonga::wrapper_recreate_indexes(THD *thd) char db_name[MRN_MAX_PATH_SIZE]; char table_name[MRN_MAX_PATH_SIZE]; char decode_name[MRN_MAX_PATH_SIZE]; - grn_obj *db, *grn_table; MRN_DBUG_ENTER_METHOD(); mrn_decode((uchar *) decode_name, (uchar *) decode_name + MRN_MAX_PATH_SIZE, (const uchar *) table_share->normalized_path.str, @@ -8558,45 +8604,28 @@ int ha_mroonga::wrapper_recreate_indexes(THD *thd) table_share->normalized_path.length); mrn_db_name_gen(decode_name, db_name); mrn_table_name_gen(decode_name, table_name); - mrn_hash_get(&mrn_ctx, mrn_hash, db_name, &db); bitmap_clear_all(table->read_set); clear_indexes(); - grn_table = grn_ctx_get(ctx, table_name, strlen(table_name)); - if (grn_table != NULL) { - grn_obj_remove(ctx, grn_table); - } else { - record_id = grn_table_get(ctx, db, - table_name, - strlen(table_name)); - if (record_id != GRN_ID_NIL) { - grn_obj_delete_by_id(ctx, db, record_id, GRN_TRUE); - } - } + remove_grn_obj_force(table_name); mrn_set_bitmap_by_key(table->read_set, p_key_info); for (i = 0; i < n_keys; i++) { if (!(key_info[i].flags & HA_FULLTEXT) && !mrn_is_geo_key(&key_info[i])) { continue; } char index_name[MRN_MAX_PATH_SIZE]; + char index_column_full_name[MRN_MAX_PATH_SIZE]; mrn_index_table_name_gen(table_name, table_share->key_info[i].name, index_name); - grn_table = grn_ctx_get(ctx, index_name, strlen(index_name)); - if (grn_table != NULL) { - grn_obj_remove(ctx, grn_table); - } else { - record_id = grn_table_get(ctx, db, - index_name, - strlen(index_name)); - if (record_id != GRN_ID_NIL) { - grn_obj_delete_by_id(ctx, db, record_id, GRN_TRUE); - } - } + snprintf(index_column_full_name, MRN_MAX_PATH_SIZE, + "%s.%s", index_name, index_column_name); + remove_grn_obj_force(index_column_full_name); + remove_grn_obj_force(index_name); mrn_set_bitmap_by_key(table->read_set, &key_info[i]); } if ( (res = wrapper_create_index(table_share->normalized_path.str, table, NULL, share)) || - (res = wrapper_open_indexes(table_share->normalized_path.str)) + (res = wrapper_open_indexes(table_share->normalized_path.str, false)) ) DBUG_RETURN(res); if ( @@ -8692,7 +8721,8 @@ int ha_mroonga::wrapper_repair(THD* thd, HA_CHECK_OPT* check_opt) MRN_SET_BASE_TABLE_KEY(this, table); if (error && error != HA_ADMIN_NOT_IMPLEMENTED) DBUG_RETURN(error); - DBUG_RETURN(wrapper_recreate_indexes(thd)); + error = wrapper_recreate_indexes(thd); + DBUG_RETURN(error); } int ha_mroonga::storage_repair(THD* thd, HA_CHECK_OPT* check_opt) Modified: ha_mroonga.h (+3 -2) =================================================================== --- ha_mroonga.h 2012-01-23 20:02:03 +0900 (4de7400) +++ ha_mroonga.h 2012-01-24 16:15:09 +0900 (cc02f4d) @@ -1,7 +1,7 @@ /* Copyright(C) 2010 Tetsuro IKEDA Copyright(C) 2010-2012 Kentoku SHIBA - Copyright(C) 2011 Kouhei Sutou <kou****@clear*****> + Copyright(C) 2011-2012 Kouhei Sutou <kou****@clear*****> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -386,6 +386,7 @@ private: void clear_search_result(); void clear_search_result_geo(); void clear_indexes(); + void remove_grn_obj_force(const char *name); grn_obj *find_tokenizer(const char *name, int name_length); int wrapper_get_next_record(uchar *buf); int storage_get_next_record(uchar *buf); @@ -453,7 +454,7 @@ private: int storage_delete_table(const char *name, MRN_SHARE *tmp_share, const char *table_name); int wrapper_open(const char *name, int mode, uint test_if_locked); - int wrapper_open_indexes(const char *name); + int wrapper_open_indexes(const char *name, bool ignore_open_error); int storage_open(const char *name, int mode, uint test_if_locked); int open_table(const char *name); int storage_open_columns(void); Modified: test/sql/suite/mroonga_wrapper/r/repair_table.result (+0 -1) =================================================================== --- test/sql/suite/mroonga_wrapper/r/repair_table.result 2012-01-23 20:02:03 +0900 (7f30813) +++ test/sql/suite/mroonga_wrapper/r/repair_table.result 2012-01-24 16:15:09 +0900 (490dc6f) @@ -25,7 +25,6 @@ SELECT * FROM diaries WHERE MATCH(body) AGAINST("starting"); ERROR HY000: syscall error 'test.mrn.0000101' (No such file or directory) REPAIR TABLE diaries; Table Op Msg_type Msg_text -test.diaries repair note Table does not support optimize, doing recreate + analyze instead test.diaries repair status OK SELECT * FROM diaries; id title body Modified: test/sql/suite/mroonga_wrapper/t/repair_table.test (+0 -2) =================================================================== --- test/sql/suite/mroonga_wrapper/t/repair_table.test 2012-01-23 20:02:03 +0900 (a657e4b) +++ test/sql/suite/mroonga_wrapper/t/repair_table.test 2012-01-24 16:15:09 +0900 (0cb2597) @@ -14,8 +14,6 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -skip repair is not implemetned yet...; - --source include/have_mroonga.inc --source include/have_mroonga_helper.inc