[Groonga-mysql-commit] mroonga/mroonga [master] [wrapper] support repair. fixes #1191.

Back to archive index

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
 




Groonga-mysql-commit メーリングリストの案内
Back to archive index