From dda9ae02959a9c27bb805e83749adf4a2d3d38bd Mon Sep 17 00:00:00 2001 From: Guangxu Cheng Date: Wed, 31 May 2017 13:30:07 +0800 Subject: [PATCH] HBASE-18129 truncate_preserve fails when the truncate method doesn't exist on the master Signed-off-by: tedyu --- hbase-shell/src/main/ruby/hbase/admin.rb | 20 +++++++++++++++++-- hbase-shell/src/test/ruby/hbase/admin_test.rb | 17 ++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/hbase-shell/src/main/ruby/hbase/admin.rb b/hbase-shell/src/main/ruby/hbase/admin.rb index 749b2e8e4d9..6a9458be2d1 100644 --- a/hbase-shell/src/main/ruby/hbase/admin.rb +++ b/hbase-shell/src/main/ruby/hbase/admin.rb @@ -35,6 +35,7 @@ module Hbase @connection = connection # Java Admin instance @admin = @connection.getAdmin + @conf = @connection.getConfiguration end def close @@ -515,14 +516,15 @@ module Hbase #---------------------------------------------------------------------------------------------- # Truncates table while maintaing region boundaries (deletes all records by recreating the table) - def truncate_preserve(table_name_str) + def truncate_preserve(table_name_str, conf = @conf) puts "Truncating '#{table_name_str}' table (it may take a while):" table_name = TableName.valueOf(table_name_str) locator = @connection.getRegionLocator(table_name) begin splits = locator.getAllRegionLocations(). - map{|i| Bytes.toString(i.getRegionInfo().getStartKey)}. + map{|i| Bytes.toStringBinary(i.getRegionInfo().getStartKey)}. delete_if{|k| k == ""}.to_java :String + splits = org.apache.hadoop.hbase.util.Bytes.toBinaryByteArrays(splits) ensure locator.close() end @@ -533,6 +535,10 @@ module Hbase begin puts 'Truncating table...' + #just for test + unless conf.getBoolean("hbase.client.truncatetable.support", true) + raise UnsupportedMethodException.new('truncateTable') + end @admin.truncateTable(table_name, true) rescue => e # Handle the compatibility case, where the truncate method doesn't exists on the Master @@ -551,6 +557,16 @@ module Hbase end end + class UnsupportedMethodException < StandardError + def initialize(name) + @method_name = name + end + + def cause + return org.apache.hadoop.hbase.DoNotRetryIOException.new("#@method_name is not support") + end + end + #---------------------------------------------------------------------------------------------- # Check the status of alter command (number of regions reopened) def alter_status(table_name) diff --git a/hbase-shell/src/test/ruby/hbase/admin_test.rb b/hbase-shell/src/test/ruby/hbase/admin_test.rb index de2891bd85a..18842170085 100644 --- a/hbase-shell/src/test/ruby/hbase/admin_test.rb +++ b/hbase-shell/src/test/ruby/hbase/admin_test.rb @@ -272,6 +272,23 @@ module Hbase output = capture_stdout { command(:truncate, @test_name) } assert(!output.empty?) end + + define_test "truncate_preserve should maintain the previous region boundaries" do + drop_test_table(@create_test_name) + admin.create(@create_test_name, 'a', {NUMREGIONS => 10, SPLITALGO => 'HexStringSplit'}) + splits = table(@create_test_name)._get_splits_internal() + command(:truncate_preserve, @create_test_name) + assert_equal(splits, table(@create_test_name)._get_splits_internal()) + end + + define_test "truncate_preserve should be fine when truncateTable method doesn't support" do + drop_test_table(@create_test_name) + admin.create(@create_test_name, 'a', {NUMREGIONS => 10, SPLITALGO => 'HexStringSplit'}) + splits = table(@create_test_name)._get_splits_internal() + $TEST_CLUSTER.getConfiguration.setBoolean("hbase.client.truncatetable.support", false) + admin.truncate_preserve(@create_test_name, $TEST_CLUSTER.getConfiguration) + assert_equal(splits, table(@create_test_name)._get_splits_internal()) + end end # Simple administration methods tests