This is an automated email from the ASF dual-hosted git repository.
zhangduo pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-3 by this push:
new a2de0b4635d HBASE-29950 Add a shell command for reopen table regions
(#7832)
a2de0b4635d is described below
commit a2de0b4635d4d0dd03d12357ab7d406abb7f4990
Author: Xiao Liu <[email protected]>
AuthorDate: Thu Mar 19 17:14:57 2026 +0800
HBASE-29950 Add a shell command for reopen table regions (#7832)
Signed-off-by: Duo Zhang <[email protected]>
(cherry picked from commit 88ffeae34f086f24b9aeb66155cd04add381ae79)
---
hbase-shell/src/main/ruby/hbase/admin.rb | 28 +++++++++
hbase-shell/src/main/ruby/shell.rb | 1 +
.../src/main/ruby/shell/commands/reopen_regions.rb | 37 ++++++++++++
.../test/ruby/hbase/reopen_regions_test_cluster.rb | 66 ++++++++++++++++++++++
4 files changed, 132 insertions(+)
diff --git a/hbase-shell/src/main/ruby/hbase/admin.rb
b/hbase-shell/src/main/ruby/hbase/admin.rb
index dd726dad50f..6dff5bf4504 100644
--- a/hbase-shell/src/main/ruby/hbase/admin.rb
+++ b/hbase-shell/src/main/ruby/hbase/admin.rb
@@ -615,6 +615,34 @@ module Hbase
@admin.move(encoded_region_name.to_java_bytes, server ?
server.to_java_bytes : nil)
end
+
#----------------------------------------------------------------------------------------------
+ # Reopen regions of a table
+ def reopen_regions(table_name, regions = nil)
+ table_name_obj = TableName.valueOf(table_name)
+ if regions.nil? || regions.empty?
+ @admin.reopenTableRegions(table_name_obj)
+ else
+ # Get all regions of the table
+ all_regions = @admin.getRegions(table_name_obj)
+ target_regions = java.util.ArrayList.new
+
+ regions.each do |r|
+ # r could be encoded name or full name
+ found = false
+ all_regions.each do |region_info|
+ if region_info.getEncodedName == r ||
region_info.getRegionNameAsString == r
+ target_regions.add(region_info)
+ found = true
+ break
+ end
+ end
+ raise ArgumentError, "Region #{r} not found in table #{table_name}"
unless found
+ end
+
+ @admin.reopenTableRegions(table_name_obj, target_regions)
+ end
+ end
+
#----------------------------------------------------------------------------------------------
# Merge multiple regions
def merge_region(regions, force)
diff --git a/hbase-shell/src/main/ruby/shell.rb
b/hbase-shell/src/main/ruby/shell.rb
index c408bf06b22..07da8a48dbd 100644
--- a/hbase-shell/src/main/ruby/shell.rb
+++ b/hbase-shell/src/main/ruby/shell.rb
@@ -451,6 +451,7 @@ Shell.load_command_group(
normalizer_enabled
is_in_maintenance_mode
clear_slowlog_responses
+ reopen_regions
close_region
compact
compaction_switch
diff --git a/hbase-shell/src/main/ruby/shell/commands/reopen_regions.rb
b/hbase-shell/src/main/ruby/shell/commands/reopen_regions.rb
new file mode 100644
index 00000000000..1f7e6906b5d
--- /dev/null
+++ b/hbase-shell/src/main/ruby/shell/commands/reopen_regions.rb
@@ -0,0 +1,37 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+module Shell
+ module Commands
+ class ReopenRegions < Command
+ def help
+ <<-EOF
+Reopen all regions of a table or specific regions of a table.
+Examples:
+ hbase> reopen_regions 'TABLE_NAME'
+ hbase> reopen_regions 'TABLE_NAME', ['REGION_NAME1', 'REGION_NAME2']
+EOF
+ end
+
+ def command(table_name, regions = nil)
+ admin.reopen_regions(table_name, regions)
+ end
+ end
+ end
+end
diff --git a/hbase-shell/src/test/ruby/hbase/reopen_regions_test_cluster.rb
b/hbase-shell/src/test/ruby/hbase/reopen_regions_test_cluster.rb
new file mode 100644
index 00000000000..6a1eada5267
--- /dev/null
+++ b/hbase-shell/src/test/ruby/hbase/reopen_regions_test_cluster.rb
@@ -0,0 +1,66 @@
+#
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'hbase_shell'
+require 'stringio'
+require 'hbase_constants'
+require 'hbase/hbase'
+require 'hbase/table'
+
+module Hbase
+ class ReopenRegionsTest < Test::Unit::TestCase
+ include TestHelpers
+
+ def setup
+ setup_hbase
+ # Create test table if it does not exist
+ @test_name = "hbase_reopen_regions_test_table"
+ create_test_table(@test_name)
+ end
+
+ def teardown
+ shutdown
+ end
+
+ define_test "reopen_regions should work for all regions" do
+ assert_nothing_raised do
+ command(:reopen_regions, @test_name)
+ end
+ end
+
+ define_test "reopen_regions should work for specific regions" do
+ # Get Java Admin to fetch regions
+ java_admin = admin.instance_variable_get(:@admin)
+ regions =
java_admin.getRegions(org.apache.hadoop.hbase.TableName.valueOf(@test_name))
+
+ assert(regions.size > 0, "Test table should have regions")
+ region_encoded_name = regions.get(0).getEncodedName
+
+ assert_nothing_raised do
+ command(:reopen_regions, @test_name, [region_encoded_name])
+ end
+ end
+
+ define_test "reopen_regions should raise error for non-existent region" do
+ assert_raise(ArgumentError) do
+ command(:reopen_regions, @test_name, ['non-existent-region'])
+ end
+ end
+ end
+end