Kouhei Sutou
null+****@clear*****
Wed Jun 14 16:43:22 JST 2017
Kouhei Sutou 2017-06-14 16:43:22 +0900 (Wed, 14 Jun 2017) New Revision: 9a50d57f619ec2beea6da2d1180338ea06dc7212 https://github.com/groonga/groonga/commit/9a50d57f619ec2beea6da2d1180338ea06dc7212 Message: grndb check: add corrupt object check TODO: * Index column corrupt case * Double array table corrupt case Modified files: lib/mrb/scripts/command_line/grndb.rb test/command_line/suite/grndb/test_check.rb Modified: lib/mrb/scripts/command_line/grndb.rb (+44 -0) =================================================================== --- lib/mrb/scripts/command_line/grndb.rb 2017-06-14 16:39:14 +0900 (2498375) +++ lib/mrb/scripts/command_line/grndb.rb 2017-06-14 16:43:22 +0900 (e563e98) @@ -132,6 +132,7 @@ module Groonga def check_database check_database_locked + check_database_corrupt check_database_dirty end @@ -181,6 +182,15 @@ module Groonga failed(message) end + def check_database_corrupt + return unles****@datab*****? + + message = + "Database is corrupt. " + + "Re-create the database." + failed(message) + end + def check_database_dirty return unles****@datab*****? @@ -209,6 +219,11 @@ module Groonga return if****@check*****?(object.id) @checked[object.id] = true + check_object_locked(object) + check_object_corrupt(object) + end + + def check_object_locked(object) case object when IndexColumn return unless object.locked? @@ -240,6 +255,35 @@ module Groonga end end + def check_object_corrupt(object) + case object + when IndexColumn + return unless object.corrupt? + message = + "[#{object.name}] Index column is corrupt. " + + "Re-create index by '#{@program_path} recover #{@database_path}'." + failed(message) + when Column + return unless object.corrupt? + name = object.name + message = + "[#{name}] Data column is corrupt. " + + "(1) Truncate the column (truncate #{name} or " + + "'#{@program_path} recover --force-truncate #{@database_path}') " + + "and (2) load data again." + failed(message) + when Table + return unless object.corrupt? + name = object.name + message = + "[#{name}] Table is corrupt. " + + "(1) Truncate the table (truncate #{name} or " + + "'#{@program_path} recover --force-truncate #{@database_path}') " + + "and (2) load data again." + failed(message) + end + end + def check_object_recursive(target) return if****@check*****?(target.id) Modified: test/command_line/suite/grndb/test_check.rb (+45 -0) =================================================================== --- test/command_line/suite/grndb/test_check.rb 2017-06-14 16:39:14 +0900 (67d07ae) +++ test/command_line/suite/grndb/test_check.rb 2017-06-14 16:43:22 +0900 (1db5035) @@ -127,6 +127,51 @@ load --table Users end end + def test_corrupt_table + groonga("table_create", "Users", "TABLE_HASH_KEY", "ShortText") + groonga do |external_process| + external_process.input.puts("load --table Users") + external_process.input.puts("[") + 300000.times do |i| + key = (("%04d" % i) * 1024)[0, 4096] + external_process.input.puts("{\"_key\": \"#{key}\"},") + external_process.input.flush + end + external_process.input.puts("{\"_key\": \"x\"}") + external_process.input.puts("]") + end + FileUtils.rm("#{@database_path}.0000100.001") + error = assert_raise(CommandRunner::Error) do + grndb("check") + end + assert_equal(<<-MESSAGE, error.error_output) +[Users] Table is corrupt. (1) Truncate the table (truncate Users or '#{grndb_path} recover --force-truncate #{@database_path}') and (2) load data again. + MESSAGE + end + + def test_corrupt_data_column + groonga("table_create", "Data", "TABLE_NO_KEY") + groonga("column_create", "Data", "text", "COLUMN_SCALAR", "Text") + groonga do |external_process| + external_process.input.puts("load --table Data") + external_process.input.puts("[") + data = "a" * 10000000 + 100.times do |i| + external_process.input.puts("{\"text\": \"#{data}\"},") + external_process.input.flush + end + external_process.input.puts("{\"text\": \"x\"}") + external_process.input.puts("]") + end + FileUtils.rm("#{@database_path}.0000101.001") + error = assert_raise(CommandRunner::Error) do + grndb("check") + end + assert_equal(<<-MESSAGE, error.error_output) +[Data.text] Data column is corrupt. (1) Truncate the column (truncate Data.text or '#{grndb_path} recover --force-truncate #{@database_path}') and (2) load data again. + MESSAGE + end + sub_test_case "--target" do def test_nonexistent_table groonga("table_create", "Users", "TABLE_HASH_KEY", "ShortText") -------------- next part -------------- HTML����������������������������...ダウンロード