Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HBASE-23046 Remove compatibility case from truncate command #638

Merged
merged 2 commits into from Sep 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
81 changes: 14 additions & 67 deletions hbase-shell/src/main/ruby/hbase/admin.rb
Expand Up @@ -576,83 +576,30 @@ def snapshot_cleanup_enabled?
def truncate(table_name_str)
puts "Truncating '#{table_name_str}' table (it may take a while):"
table_name = TableName.valueOf(table_name_str)
table_description = @admin.getDescriptor(table_name)
raise ArgumentError, "Table #{table_name_str} is not enabled. Enable it first." unless
enabled?(table_name_str)
puts 'Disabling table...'
@admin.disableTable(table_name)

begin
puts 'Truncating table...'
@admin.truncateTable(table_name, false)
rescue => e
# Handle the compatibility case, where the truncate method doesn't exists on the Master
raise e unless e.respond_to?(:cause) && !e.cause.nil?
rootCause = e.cause
if rootCause.is_a?(org.apache.hadoop.hbase.DoNotRetryIOException)
# Handle the compatibility case, where the truncate method doesn't exists on the Master
puts 'Dropping table...'
@admin.deleteTable(table_name)

puts 'Creating table...'
@admin.createTable(table_description)
else
raise e
end
if enabled?(table_name_str)
puts 'Disabling table...'
disable(table_name_str)
end

puts 'Truncating table...'
@admin.truncateTable(table_name, false)
end

#----------------------------------------------------------------------------------------------
# Truncates table while maintaing region boundaries (deletes all records by recreating the table)
def truncate_preserve(table_name_str, conf = @conf)
# Truncates table while maintaining region boundaries
# (deletes all records by recreating the table)
def truncate_preserve(table_name_str)
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.toStringBinary(i.getRegion.getStartKey) }
.delete_if { |k| k == '' }.to_java :String
splits = org.apache.hadoop.hbase.util.Bytes.toBinaryByteArrays(splits)
ensure
locator.close
end

table_description = @admin.getDescriptor(table_name)
puts 'Disabling table...'
disable(table_name_str)

begin
puts 'Truncating table...'
# just for test
unless conf.getBoolean('hbase.client.truncatetable.support', true)
raise UnsupportedMethodException, 'truncateTable'
end
@admin.truncateTable(table_name, true)
rescue => e
# Handle the compatibility case, where the truncate method doesn't exists on the Master
raise e unless e.respond_to?(:cause) && !e.cause.nil?
rootCause = e.cause
if rootCause.is_a?(org.apache.hadoop.hbase.DoNotRetryIOException)
# Handle the compatibility case, where the truncate method doesn't exists on the Master
puts 'Dropping table...'
@admin.deleteTable(table_name)

puts 'Creating table with region boundaries...'
@admin.createTable(table_description, splits)
else
raise e
end
end
end

class UnsupportedMethodException < StandardError
def initialize(name)
@method_name = name
if enabled?(table_name_str)
puts 'Disabling table...'
disable(table_name_str)
end

def cause
org.apache.hadoop.hbase.DoNotRetryIOException.new("#{@method_name} is not support")
end
puts 'Truncating table...'
@admin.truncateTable(table_name, true)
end

#----------------------------------------------------------------------------------------------
Expand Down
36 changes: 18 additions & 18 deletions hbase-shell/src/test/ruby/hbase/admin_test.rb
Expand Up @@ -362,53 +362,53 @@ def teardown

#-------------------------------------------------------------------------------

define_test "truncate should empty a table" do
table(@test_name).put(1, "x:a", 1)
table(@test_name).put(2, "x:a", 2)
define_test 'truncate should empty a table' do
table(@test_name).put(1, 'x:a', 1)
table(@test_name).put(2, 'x:a', 2)
assert_equal(2, table(@test_name)._count_internal)
# This is hacky. Need to get the configuration into admin instance
command(:truncate, @test_name)
assert_equal(0, table(@test_name)._count_internal)
end

define_test "truncate should yield log records" do
define_test 'truncate should yield log records' do
output = capture_stdout { command(:truncate, @test_name) }
assert(!output.empty?)
end

define_test 'truncate should work on disabled table' do
table(@test_name).put(1, 'x:a', 1)
table(@test_name).put(2, 'x:a', 2)
assert_equal(2, table(@test_name)._count_internal)
command(:disable, @test_name)
command(:truncate, @test_name)
assert_equal(0, table(@test_name)._count_internal)
end

#-------------------------------------------------------------------------------

define_test "truncate_preserve should empty a table" do
table(@test_name).put(1, "x:a", 1)
table(@test_name).put(2, "x:a", 2)
define_test 'truncate_preserve should empty a table' do
table(@test_name).put(1, 'x:a', 1)
table(@test_name).put(2, 'x:a', 2)
assert_equal(2, table(@test_name)._count_internal)
# This is hacky. Need to get the configuration into admin instance
command(:truncate_preserve, @test_name)
assert_equal(0, table(@test_name)._count_internal)
end

define_test "truncate_preserve should yield log records" do
define_test 'truncate_preserve should yield log records' do
output = capture_stdout { command(:truncate_preserve, @test_name) }
assert(!output.empty?)
end

define_test "truncate_preserve should maintain the previous region boundaries" do
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

#-------------------------------------------------------------------------------

define_test "list_regions should fail for disabled table" do
Expand Down