[Groonga-commit] groonga/groonga at 9a50d57 [master] grndb check: add corrupt object check

アーカイブの一覧に戻る

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����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る