From e325286fd1658103bbe9fbff4e8033aac946fe2c Mon Sep 17 00:00:00 2001 From: Guangxu Cheng Date: Mon, 26 Mar 2018 11:07:32 +0800 Subject: [PATCH] HBASE-20243 [Shell] Add shell command to create a new table by cloning the existent table --- .../java/org/apache/hadoop/hbase/client/Admin.java | 11 ++++++ .../org/apache/hadoop/hbase/client/HBaseAdmin.java | 15 ++++++++ hbase-shell/src/main/ruby/hbase/admin.rb | 7 ++++ hbase-shell/src/main/ruby/shell.rb | 1 + hbase-shell/src/main/ruby/shell/commands.rb | 2 ++ .../main/ruby/shell/commands/clone_table_schema.rb | 41 ++++++++++++++++++++++ 6 files changed, 77 insertions(+) create mode 100644 hbase-shell/src/main/ruby/shell/commands/clone_table_schema.rb diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java index b8546fa453..7d97414651 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/Admin.java @@ -2718,4 +2718,15 @@ public interface Admin extends Abortable, Closeable { * @return List of servers that are not cleared */ List clearDeadServers(final List servers) throws IOException; + + /** + * Create a new table by cloning the existent table schema. + * + * @param tableName name of the table to be cloned + * @param newTableName name of the new table where the table will be created + * @param preserveSplits True if the splits should be preserved + * @throws IOException if a remote or network exception occurs + */ + void cloneTableSchema(final TableName tableName, final TableName newTableName, + final boolean preserveSplits) throws IOException; } diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java index 86859847be..172db5b647 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/client/HBaseAdmin.java @@ -4227,4 +4227,19 @@ public class HBaseAdmin implements Admin { } }); } + + @Override + public void cloneTableSchema(final TableName tableName, final TableName newTableName, + final boolean preserveSplits) throws IOException { + checkTableExists(tableName); + if (tableExists(newTableName)) { + throw new TableExistsException(newTableName); + } + TableDescriptor htd = TableDescriptorBuilder.copy(newTableName, getTableDescriptor(tableName)); + if (preserveSplits) { + createTable(htd, getTableSplits(tableName)); + } else { + createTable(htd); + } + } } diff --git a/hbase-shell/src/main/ruby/hbase/admin.rb b/hbase-shell/src/main/ruby/hbase/admin.rb index f35dcb0832..241f2ef285 100644 --- a/hbase-shell/src/main/ruby/hbase/admin.rb +++ b/hbase-shell/src/main/ruby/hbase/admin.rb @@ -1298,5 +1298,12 @@ module Hbase def list_liveservers @admin.getClusterStatus.getServers.to_a end + + #---------------------------------------------------------------------------------------------- + # create a new table by cloning the existent table schema. + def clone_table_schema(table_name, new_table_name, preserve_splits) + @admin.cloneTableSchema(TableName.valueOf(table_name), + TableName.valueOf(new_table_name), java.lang.Boolean::valueOf(preserve_splits)) + end end end diff --git a/hbase-shell/src/main/ruby/shell.rb b/hbase-shell/src/main/ruby/shell.rb index 5e563dfea5..b4b5d19820 100644 --- a/hbase-shell/src/main/ruby/shell.rb +++ b/hbase-shell/src/main/ruby/shell.rb @@ -286,6 +286,7 @@ Shell.load_command_group( get_table locate_region list_regions + clone_table_schema ], aliases: { 'describe' => ['desc'] diff --git a/hbase-shell/src/main/ruby/shell/commands.rb b/hbase-shell/src/main/ruby/shell/commands.rb index d7730cf891..0f036b54cd 100644 --- a/hbase-shell/src/main/ruby/shell/commands.rb +++ b/hbase-shell/src/main/ruby/shell/commands.rb @@ -136,6 +136,8 @@ module Shell end end if cause.is_a?(org.apache.hadoop.hbase.TableExistsException) + strs = cause.to_s.split(' ') + raise "Table already exists: #{strs[0]}!" if strs.size == 1 raise "Table already exists: #{args.first}!" end # To be safe, here only AccessDeniedException is considered. In future diff --git a/hbase-shell/src/main/ruby/shell/commands/clone_table_schema.rb b/hbase-shell/src/main/ruby/shell/commands/clone_table_schema.rb new file mode 100644 index 0000000000..e9609ab021 --- /dev/null +++ b/hbase-shell/src/main/ruby/shell/commands/clone_table_schema.rb @@ -0,0 +1,41 @@ +# +# 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 CloneTableSchema < Command + def help + return <<-EOF +Create a new table by cloning the existent table schema. +There're no copies of data involved. +Just copy the table descriptor and split keys. + +Passing 'false' as the optional third parameter will +not preserve split keys. +Examples: + hbase> clone_table 'table_name', 'new_table_name' + hbase> clone_table 'table_name', 'new_table_name', false +EOF + end + + def command(table_name, new_table_name, preserve_splits = true) + admin.clone_table_schema(table_name, new_table_name, preserve_splits) + end + end + end +end -- 2.13