From 2149277bf3669e9bffbaa05db1d6f5ceff6c0a07 Mon Sep 17 00:00:00 2001 From: Michael Stack Date: Mon, 29 Nov 2010 19:41:02 +0000 Subject: [PATCH] HBASE-3267 close_region shell command breaks region git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1040243 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 1 + .../hadoop/hbase/client/HBaseAdmin.java | 49 +++++++++++++++++-- .../hadoop/hbase/ipc/HMasterInterface.java | 34 ++++++++++++- .../hbase/master/AssignmentManager.java | 13 +++-- .../apache/hadoop/hbase/master/HMaster.java | 37 ++++++++++++-- src/main/ruby/hbase/admin.rb | 40 ++++++++++----- src/main/ruby/shell.rb | 8 +-- .../ruby/shell/commands/{zk.rb => assign.rb} | 13 +++-- .../{disable_region.rb => balance_switch.rb} | 12 ++--- .../{enable_region.rb => balancer.rb} | 13 ++--- src/main/ruby/shell/commands/close_region.rb | 8 ++- src/main/ruby/shell/commands/move.rb | 48 ++++++++++++++++++ src/main/ruby/shell/commands/unassign.rb | 43 ++++++++++++++++ 13 files changed, 270 insertions(+), 49 deletions(-) rename src/main/ruby/shell/commands/{zk.rb => assign.rb} (73%) rename src/main/ruby/shell/commands/{disable_region.rb => balance_switch.rb} (81%) rename src/main/ruby/shell/commands/{enable_region.rb => balancer.rb} (79%) create mode 100644 src/main/ruby/shell/commands/move.rb create mode 100644 src/main/ruby/shell/commands/unassign.rb diff --git a/CHANGES.txt b/CHANGES.txt index 026b0fc4534..681be5ad588 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -714,6 +714,7 @@ Release 0.90.0 - Unreleased HBASE-3275 [rest] No gzip/deflate content encoding support HBASE-3261 NPE out of HRS.run at startup when clock is out of sync HBASE-3277 HBase Shell zk_dump command broken + HBASE-3267 close_region shell command breaks region IMPROVEMENTS diff --git a/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index 564467af731..24754e850fc 100644 --- a/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -751,7 +751,8 @@ public class HBaseAdmin implements Abortable { } /** - * Close a region. For expert-admins. + * Close a region. For expert-admins. Runs close on the regionserver. The + * master will not be informed of the close. * @param regionname region name to close * @param hostAndPort If supplied, we'll use this location rather than * the one currently in .META. @@ -763,7 +764,8 @@ public class HBaseAdmin implements Abortable { } /** - * Close a region. For expert-admins. + * Close a region. For expert-admins Runs close on the regionserver. The + * master will not be informed of the close. * @param regionname region name to close * @param hostAndPort If supplied, we'll use this location rather than * the one currently in .META. @@ -801,7 +803,8 @@ public class HBaseAdmin implements Abortable { private void closeRegion(final HServerAddress hsa, final HRegionInfo hri) throws IOException { HRegionInterface rs = this.connection.getHRegionConnection(hsa); - rs.closeRegion(hri); + // Close the region without updating zk state. + rs.closeRegion(hri, false); } /** @@ -956,8 +959,14 @@ public class HBaseAdmin implements Abortable { /** * Move the region r to dest. - * @param encodedRegionName The encoded region name. - * @param destServerName The servername of the destination regionserver + * @param encodedRegionName The encoded region name; i.e. the hash that makes + * up the region name suffix: e.g. if regionname is + * TestTable,0094429456,1289497600452.527db22f95c8a9e0116f0cc13c680396., + * then the encoded region name is: 527db22f95c8a9e0116f0cc13c680396. + * @param destServerName The servername of the destination regionserver. If + * passed the empty byte array we'll assign to a random server. A server name + * is made of host, port and startcode. Here is an example: + * host187.example.com,60020,1289493121758. * @throws UnknownRegionException Thrown if we can't find a region named * encodedRegionName * @throws ZooKeeperConnectionException @@ -968,6 +977,36 @@ public class HBaseAdmin implements Abortable { getMaster().move(encodedRegionName, destServerName); } + /** + * @param regionName Region name to assign. + * @param force True to force assign. + * @throws MasterNotRunningException + * @throws ZooKeeperConnectionException + * @throws IOException + */ + public void assign(final byte [] regionName, final boolean force) + throws MasterNotRunningException, ZooKeeperConnectionException, IOException { + getMaster().assign(regionName, force); + } + + /** + * Unassign a region from current hosting regionserver. Region will then be + * assigned to a regionserver chosen at random. Region could be reassigned + * back to the same server. Use {@link #move(byte[], byte[])} if you want + * to control the region movement. + * @param regionName Region to unassign. Will clear any existing RegionPlan + * if one found. + * @param force If true, force unassign (Will remove region from + * regions-in-transition too if present). + * @throws MasterNotRunningException + * @throws ZooKeeperConnectionException + * @throws IOException + */ + public void unassign(final byte [] regionName, final boolean force) + throws MasterNotRunningException, ZooKeeperConnectionException, IOException { + getMaster().unassign(regionName, force); + } + /** * Turn the load balancer on or off. * @param b If true, enable balancer. If false, disable balancer. diff --git a/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java b/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java index bacf8b16eeb..a4f09f364ee 100644 --- a/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java +++ b/src/main/java/org/apache/hadoop/hbase/ipc/HMasterInterface.java @@ -135,14 +135,44 @@ public interface HMasterInterface extends HBaseRPCProtocolVersion { /** * Move the region r to dest. - * @param encodedRegionName The encoded region name. - * @param destServerName The servername of the destination regionserver + * @param encodedRegionName The encoded region name; i.e. the hash that makes + * up the region name suffix: e.g. if regionname is + * TestTable,0094429456,1289497600452.527db22f95c8a9e0116f0cc13c680396., + * then the encoded region name is: 527db22f95c8a9e0116f0cc13c680396. + * @param destServerName The servername of the destination regionserver. If + * passed the empty byte array we'll assign to a random server. A server name + * is made of host, port and startcode. Here is an example: + * host187.example.com,60020,1289493121758. * @throws UnknownRegionException Thrown if we can't find a region named * encodedRegionName */ public void move(final byte [] encodedRegionName, final byte [] destServerName) throws UnknownRegionException; + /** + * Assign a region to a server chosen at random. + * @param regionName Region to assign. Will use existing RegionPlan if one + * found. + * @param force If true, will force the assignment. + * @throws IOException + */ + public void assign(final byte [] regionName, final boolean force) + throws IOException; + + /** + * Unassign a region from current hosting regionserver. Region will then be + * assigned to a regionserver chosen at random. Region could be reassigned + * back to the same server. Use {@link #move(byte[], byte[])} if you want + * to control the region movement. + * @param regionName Region to unassign. Will clear any existing RegionPlan + * if one found. + * @param force If true, force unassign (Will remove region from + * regions-in-transition too if present). + * @throws IOException + */ + public void unassign(final byte [] regionName, final boolean force) + throws IOException; + /** * Run the balancer. Will run the balancer and if regions to move, it will * go ahead and do the reassignments. Can NOT run for various reasons. Check diff --git a/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java b/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java index 83223db0c3b..d22324f4f66 100644 --- a/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java +++ b/src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java @@ -1360,9 +1360,7 @@ public class AssignmentManager extends ZooKeeperListener { synchronized (this.regions) { this.regions.remove(hri); } - synchronized (this.regionPlans) { - this.regionPlans.remove(hri.getEncodedName()); - } + clearRegionPlan(hri.getEncodedName()); synchronized (this.servers) { for (List regions : this.servers.values()) { for (int i=0;i pair = + MetaReader.getRegion(this.catalogTracker, regionName); + if (pair == null) throw new UnknownRegionException(Bytes.toString(regionName)); + assignRegion(pair.getFirst()); + } + public void assignRegion(HRegionInfo hri) { assignmentManager.assign(hri, true); } + @Override + public void unassign(final byte [] regionName, final boolean force) + throws IOException { + Pair pair = + MetaReader.getRegion(this.catalogTracker, regionName); + if (pair == null) throw new UnknownRegionException(Bytes.toString(regionName)); + HRegionInfo hri = pair.getFirst(); + if (force) this.assignmentManager.clearRegionFromTransition(hri); + this.assignmentManager.unassign(hri, force); + } + /** * Utility for constructing an instance of the passed HMaster class. * @param masterClass diff --git a/src/main/ruby/hbase/admin.rb b/src/main/ruby/hbase/admin.rb index ca19ea311b4..799d1df66d3 100644 --- a/src/main/ruby/hbase/admin.rb +++ b/src/main/ruby/hbase/admin.rb @@ -25,6 +25,7 @@ java_import org.apache.zookeeper.ZooKeeperMain java_import org.apache.hadoop.hbase.HColumnDescriptor java_import org.apache.hadoop.hbase.HTableDescriptor java_import org.apache.hadoop.hbase.HRegionInfo +java_import org.apache.hadoop.hbase.util.Bytes java_import org.apache.zookeeper.ZooKeeper # Wrapper for org.apache.hadoop.hbase.client.HBaseAdmin @@ -72,6 +73,20 @@ module Hbase @admin.split(table_or_region_name) end + #---------------------------------------------------------------------------------------------- + # Requests a cluster balance + # Returns true if balancer ran + def balancer() + @admin.balancer() + end + + #---------------------------------------------------------------------------------------------- + # Enable/disable balancer + # Returns previous balancer switch setting. + def balance_switch(enableDisable) + @admin.balanceSwitch(java.lang.Boolean::valueOf(enableDisable)) + end + #---------------------------------------------------------------------------------------------- # Enables a table def enable(table_name) @@ -150,15 +165,21 @@ module Hbase end #---------------------------------------------------------------------------------------------- - # Enables a region - def enable_region(region_name) - online(region_name, false) + # Assign a region + def assign(region_name, force) + @admin.assign(Bytes::toBytes(region_name), java.lang.Boolean::valueOf(force)) end #---------------------------------------------------------------------------------------------- - # Disables a region - def disable_region(region_name) - online(region_name, true) + # Unassign a region + def unassign(region_name, force) + @admin.unassign(Bytes::toBytes(region_name), java.lang.Boolean::valueOf(force)) + end + + #---------------------------------------------------------------------------------------------- + # Move a region + def move(encoded_region_name, server = nil) + @admin.move(encoded_region_name, server ? [server].to_java: nil) end #---------------------------------------------------------------------------------------------- @@ -364,12 +385,5 @@ module Hbase put.add(HConstants::CATALOG_FAMILY, HConstants::REGIONINFO_QUALIFIER, Writables.getBytes(hri)) meta.put(put) end - #---------------------------------------------------------------------------------------------- - # Invoke a ZooKeeper maintenance command - def zk(args) - line = args.join(' ') - line = 'help' if line.empty? - @zk_main.executeLine(line) - end end end diff --git a/src/main/ruby/shell.rb b/src/main/ruby/shell.rb index 7ff36510f5e..90272023e9f 100644 --- a/src/main/ruby/shell.rb +++ b/src/main/ruby/shell.rb @@ -248,14 +248,16 @@ Shell.load_command_group( :full_name => 'HBASE SURGERY TOOLS', :comment => "WARNING: Above commands are for 'experts'-only as misuse can damage an install", :commands => %w[ + assign + balancer + balance_switch close_region compact - disable_region - enable_region flush major_compact + move split - zk + unassign zk_dump ] ) diff --git a/src/main/ruby/shell/commands/zk.rb b/src/main/ruby/shell/commands/assign.rb similarity index 73% rename from src/main/ruby/shell/commands/zk.rb rename to src/main/ruby/shell/commands/assign.rb index fc8f084c4a6..2fe4a7f7db4 100644 --- a/src/main/ruby/shell/commands/zk.rb +++ b/src/main/ruby/shell/commands/assign.rb @@ -20,16 +20,19 @@ module Shell module Commands - class Zk < Command + class Assign < Command def help return <<-EOF -Low level ZooKeeper surgery tools. Type "zk 'help'" for more -information (Yes, you must quote 'help'). +Assign a region. Add 'true' to force assign of a region. Use with caution. +If region already assigned, this command will just go ahead and reassign +the region anyways. For experts only. EOF end - def command(*args) - admin.zk(args) + def command(region_name, force = 'false') + format_simple_command do + admin.assign(region_name, force) + end end end end diff --git a/src/main/ruby/shell/commands/disable_region.rb b/src/main/ruby/shell/commands/balance_switch.rb similarity index 81% rename from src/main/ruby/shell/commands/disable_region.rb rename to src/main/ruby/shell/commands/balance_switch.rb index a5ccf76d34c..0453f162663 100644 --- a/src/main/ruby/shell/commands/disable_region.rb +++ b/src/main/ruby/shell/commands/balance_switch.rb @@ -20,18 +20,18 @@ module Shell module Commands - class DisableRegion < Command + class BalanceSwitch < Command def help return <<-EOF -Disable a single region. For example: - - hbase> disable_region 'REGIONNAME' +Enable/Disable balancer. Returns previous balancer state. EOF end - def command(region_name) + def command(enableDisable) format_simple_command do - admin.disable_region(region_name) + formatter.row([ + admin.balance_switch(enableDisable)? "true" : "false" + ]) end end end diff --git a/src/main/ruby/shell/commands/enable_region.rb b/src/main/ruby/shell/commands/balancer.rb similarity index 79% rename from src/main/ruby/shell/commands/enable_region.rb rename to src/main/ruby/shell/commands/balancer.rb index a58f7fcfc82..013980c5baf 100644 --- a/src/main/ruby/shell/commands/enable_region.rb +++ b/src/main/ruby/shell/commands/balancer.rb @@ -20,18 +20,19 @@ module Shell module Commands - class EnableRegion < Command + class Balancer < Command def help return <<-EOF -Enable a single region. For example: - - hbase> enable_region 'REGIONNAME' +Trigger the cluster balancer. Returns true if balancer ran. Otherwise +false (Will not run if regions in transition). EOF end - def command(region_name) + def command() format_simple_command do - admin.enable_region(region_name) + formatter.row([ + admin.balancer()? "true": "false" + ]) end end end diff --git a/src/main/ruby/shell/commands/close_region.rb b/src/main/ruby/shell/commands/close_region.rb index d70823957e7..412c0fb7a15 100644 --- a/src/main/ruby/shell/commands/close_region.rb +++ b/src/main/ruby/shell/commands/close_region.rb @@ -23,8 +23,12 @@ module Shell class CloseRegion < Command def help return <<-EOF -Close a single region. Optionally specify regionserver. -Examples: +Close a single region. Optionally specify regionserver. Connects to the +regionserver and runs close on hosting regionserver. The close is done +without the master's involvement (It will not know of the close). Once +closed, region will stay closed. Use assign to reopen/reassign. Use +unassign or move to assign the region elsewhere on cluster. Use with +caution. For experts only. Examples: hbase> close_region 'REGIONNAME' hbase> close_region 'REGIONNAME', 'REGIONSERVER_IP:PORT' diff --git a/src/main/ruby/shell/commands/move.rb b/src/main/ruby/shell/commands/move.rb new file mode 100644 index 00000000000..0e3db8fe472 --- /dev/null +++ b/src/main/ruby/shell/commands/move.rb @@ -0,0 +1,48 @@ +# +# Copyright 2010 The Apache Software Foundation +# +# 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 Move < Command + def help + return <<-EOF +Move a region. Optionally specify target regionserver else we choose one +at random. NOTE: You pass the encoded region name, not the region name so +this command is a little different to the others. The encoded region name +is the hash suffix on region names: e.g. if the region name were +TestTable,0094429456,1289497600452.527db22f95c8a9e0116f0cc13c680396. then +the encoded region name portion is 527db22f95c8a9e0116f0cc13c680396 +A server name is its host, port plus startcode. For example: +host187.example.com,60020,1289493121758 +Examples: + + hbase> move 'ENCODED_REGIONNAME' + hbase> move 'ENCODED_REGIONNAME', 'SERVER_NAME' +EOF + end + + def command(encoded_region_name, server_name = nil) + format_simple_command do + admin.move(encoded_region_name, server_name) + end + end + end + end +end diff --git a/src/main/ruby/shell/commands/unassign.rb b/src/main/ruby/shell/commands/unassign.rb new file mode 100644 index 00000000000..0095dd6098e --- /dev/null +++ b/src/main/ruby/shell/commands/unassign.rb @@ -0,0 +1,43 @@ +# +# Copyright 2010 The Apache Software Foundation +# +# 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 Unassign < Command + def help + return <<-EOF +Unassign a region. Unassign will close region in current location and then +reopen it again. Pass 'true' to force the unassignment ('force' will clear +all in-memory state in master before the reassign). Use with caution. For +expert use only. Examples: + + hbase> unassign 'REGIONNAME' + hbase> unassign 'REGIONNAME', true +EOF + end + + def command(region_name, force = 'false') + format_simple_command do + admin.unassign(region_name, force) + end + end + end + end +end