001/** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 */ 019package org.apache.hadoop.hbase.tool; 020 021import java.io.IOException; 022import java.util.List; 023 024import org.apache.hadoop.hbase.HBaseInterfaceAudience; 025import org.apache.hadoop.hbase.client.Admin; 026import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 027import org.apache.hadoop.hbase.client.Connection; 028import org.apache.hadoop.hbase.client.ConnectionFactory; 029import org.apache.hadoop.hbase.client.TableDescriptor; 030import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding; 031import org.apache.hadoop.hbase.util.AbstractHBaseTool; 032import org.apache.hadoop.hbase.util.Bytes; 033import org.apache.yetus.audience.InterfaceAudience; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine; 038 039@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS) 040public class DataBlockEncodingValidator extends AbstractHBaseTool { 041 042 private static final Logger LOG = LoggerFactory.getLogger(DataBlockEncodingValidator.class); 043 private static final byte[] DATA_BLOCK_ENCODING = Bytes.toBytes("DATA_BLOCK_ENCODING"); 044 045 /** 046 * Check DataBlockEncodings of column families are compatible. 047 * 048 * @return number of column families with incompatible DataBlockEncoding 049 * @throws IOException if a remote or network exception occurs 050 */ 051 private int validateDBE() throws IOException { 052 int incompatibilities = 0; 053 054 LOG.info("Validating Data Block Encodings"); 055 056 try (Connection connection = ConnectionFactory.createConnection(getConf()); 057 Admin admin = connection.getAdmin()) { 058 List<TableDescriptor> tableDescriptors = admin.listTableDescriptors(); 059 String encoding = ""; 060 061 for (TableDescriptor td : tableDescriptors) { 062 ColumnFamilyDescriptor[] columnFamilies = td.getColumnFamilies(); 063 for (ColumnFamilyDescriptor cfd : columnFamilies) { 064 try { 065 encoding = Bytes.toString(cfd.getValue(DATA_BLOCK_ENCODING)); 066 // IllegalArgumentException will be thrown if encoding is incompatible with 2.0 067 DataBlockEncoding.valueOf(encoding); 068 } catch (IllegalArgumentException e) { 069 incompatibilities++; 070 LOG.warn("Incompatible DataBlockEncoding for table: {}, cf: {}, encoding: {}", 071 td.getTableName().getNameAsString(), cfd.getNameAsString(), encoding); 072 } 073 } 074 } 075 } 076 077 if (incompatibilities > 0) { 078 LOG.warn("There are {} column families with incompatible Data Block Encodings. Do not " 079 + "upgrade until these encodings are converted to a supported one. " 080 + "Check https://s.apache.org/prefixtree for instructions.", incompatibilities); 081 } else { 082 LOG.info("The used Data Block Encodings are compatible with HBase 2.0."); 083 } 084 085 return incompatibilities; 086 } 087 088 @Override 089 protected void printUsage() { 090 String header = "hbase " + PreUpgradeValidator.TOOL_NAME + " " + 091 PreUpgradeValidator.VALIDATE_DBE_NAME; 092 printUsage(header, null, ""); 093 } 094 095 @Override 096 protected void addOptions() { 097 } 098 099 @Override 100 protected void processOptions(CommandLine cmd) { 101 } 102 103 @Override 104 protected int doWork() throws Exception { 105 return (validateDBE() == 0) ? EXIT_SUCCESS : EXIT_FAILURE; 106 } 107}