Kouhei Sutou
null+****@clear*****
Fri Jun 16 16:40:47 JST 2017
Kouhei Sutou 2017-06-16 16:40:47 +0900 (Fri, 16 Jun 2017) New Revision: 534fc986617a56126d3b17fed4778567e2f548ba https://github.com/groonga/groonga/commit/534fc986617a56126d3b17fed4778567e2f548ba Message: grndb: support orphan "inspect" detection and deletion Modified files: lib/db.c lib/mrb/scripts/command_line/grndb.rb test/command_line/suite/grndb/test_check.rb test/command_line/suite/grndb/test_recover.rb Modified: lib/db.c (+27 -4) =================================================================== --- lib/db.c 2017-06-16 15:41:04 +0900 (63e5573) +++ lib/db.c 2017-06-16 16:40:47 +0900 (52b70bf) @@ -13693,15 +13693,38 @@ exit : } static void +grn_db_recover_database_remove_orphan_inspect(grn_ctx *ctx, grn_obj *db) +{ + GRN_TABLE_EACH_BEGIN_FLAGS(ctx, db, cursor, id, GRN_CURSOR_BY_ID) { + void *key; + int key_size; + + key_size = grn_table_cursor_get_key(ctx, cursor, &key); +#define INSPECT "inspect" +#define INSPECT_LEN (sizeof(INSPECT) - 1) + if (key_size == INSPECT_LEN && memcmp(key, INSPECT, INSPECT_LEN) == 0) { + if (!grn_ctx_at(ctx, id)) { + ERRCLR(ctx); + grn_obj_delete_by_id(ctx, db, id, GRN_TRUE); + } + break; + } +#undef INSPECT +#undef INSPECT_LEN + } GRN_TABLE_EACH_END(ctx, cursor); +} + +static void grn_db_recover_database(grn_ctx *ctx, grn_obj *db) { - if (!grn_obj_is_locked(ctx, db)) { - grn_db_clear_dirty(ctx, db); + if (grn_obj_is_locked(ctx, db)) { + ERR(GRN_OBJECT_CORRUPT, + "[db][recover] database may be broken. Please re-create the database"); return; } - ERR(GRN_OBJECT_CORRUPT, - "[db][recover] database may be broken. Please re-create the database"); + grn_db_clear_dirty(ctx, db); + grn_db_recover_database_remove_orphan_inspect(ctx, db); } static void Modified: lib/mrb/scripts/command_line/grndb.rb (+15 -0) =================================================================== --- lib/mrb/scripts/command_line/grndb.rb 2017-06-16 15:41:04 +0900 (e563e98) +++ lib/mrb/scripts/command_line/grndb.rb 2017-06-16 16:40:47 +0900 (8fba486) @@ -131,6 +131,7 @@ module Groonga end def check_database + check_database_orphan_inspect check_database_locked check_database_corrupt check_database_dirty @@ -172,6 +173,20 @@ module Groonga end private + def check_database_orphan_inspect + open_database_cursor do |cursor| + cursor.each do |id| + if cursor.key == "inspect" and @context[id].nil? + message = + "Database has orphan 'inspect' object. " + + "Remove it by '#{@program_path} recover #{@database_path}'." + failed(message) + break + end + end + end + end + def check_database_locked return unles****@datab*****? Modified: test/command_line/suite/grndb/test_check.rb (+12 -0) =================================================================== --- test/command_line/suite/grndb/test_check.rb 2017-06-16 15:41:04 +0900 (54e21f1) +++ test/command_line/suite/grndb/test_check.rb 2017-06-16 16:40:47 +0900 (4b286f4) @@ -2,6 +2,18 @@ class TestGrnDBCheck < GroongaTestCase def setup end + def test_orphan_inspect + groonga("table_create", "inspect", "TABLE_NO_KEY") + _id, _name, path, *_ = JSON.parse(groonga("table_list").output)[1][1] + FileUtils.rm(path) + error = assert_raise(CommandRunner::Error) do + grndb("check") + end + assert_equal(<<-MESSAGE, error.error_output) +Database has orphan 'inspect' object. Remove it by '#{grndb_path} recover #{@database_path}'. + MESSAGE + end + def test_locked_database groonga("lock_acquire") error = assert_raise(CommandRunner::Error) do Modified: test/command_line/suite/grndb/test_recover.rb (+10 -0) =================================================================== --- test/command_line/suite/grndb/test_recover.rb 2017-06-16 15:41:04 +0900 (4302869) +++ test/command_line/suite/grndb/test_recover.rb 2017-06-16 16:40:47 +0900 (7975fed) @@ -2,6 +2,16 @@ class TestGrnDBRecover < GroongaTestCase def setup end + def test_orphan_inspect + groonga("table_create", "inspect", "TABLE_NO_KEY") + _id, _name, path, *_ = JSON.parse(groonga("table_list").output)[1][1] + FileUtils.rm(path) + result = grndb("recover") + assert_equal("", result.error_output) + result = grndb("check") + assert_equal("", result.error_output) + end + def test_locked_database groonga("lock_acquire") error = assert_raise(CommandRunner::Error) do -------------- next part -------------- HTML����������������������������... 下載