You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by bh...@apache.org on 2021/07/08 04:19:56 UTC

[hbase] branch branch-1 updated: HBASE-26070: Rewrite 1.7.0 faulty table descriptors at bootstrap (#3463)

This is an automated email from the ASF dual-hosted git repository.

bharathv pushed a commit to branch branch-1
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-1 by this push:
     new 5ece9cef HBASE-26070: Rewrite 1.7.0 faulty table descriptors at bootstrap (#3463)
5ece9cef is described below

commit 5ece9cefeae096ad5565957e6fc35298ab8416de
Author: Bharath Vissapragada <bh...@apache.org>
AuthorDate: Wed Jul 7 21:19:31 2021 -0700

    HBASE-26070: Rewrite 1.7.0 faulty table descriptors at bootstrap (#3463)
    
    This patch rewrites incorrectly serialized table descriptors and states
    from HBASE-26021 into PBs prior to the incompatible change. The patch
    does this as a part of the active HMaster bootstrap.
    
    This approach is _not_ fool proof as it does not handle all the edge cases
    and may break certain rolling upgrade semantics. However it does provide a way
    out for tables created with 1.7.0 PB definitions and an upgrade path for 1.7.1.
    Easiest way is to shutdown the 1.7.0 cluster, reboot with 1.7.1 binaries and
    everything should work cleanly. However, rolling upgrade could potentially be
    broken as 1.7.0 client may not be compatible with 1.7.1 server.
    
    As noted in the jira, it is not possible that any one upgraded to 1.7.0 yet
    because they will run into HBASE-26021, however new clusters may have been
    created with 1.7.0 and hence they need an upgrade path.
    
    Tested locally:
    
    - Created a mix of enabled/disabled tables created with 1.7.0
    - Upgraded the cluster without this patch, noticed deserialization errors
    - Upgraded the cluster with patch and table metadata has been re-serialized
      in correct format and table states are preserved.
    
    Signed-off-by: Reid Chan <re...@apache.org>
---
 .../hadoop/hbase/DeprecatedTableDescriptor.java    |   77 +
 .../org/apache/hadoop/hbase/HTableDescriptor.java  |    8 +-
 hbase-protocol/pom.xml                             |    1 +
 .../generated/HBase170CompatibilityProtos.java     | 1642 ++++++++++++++++++++
 ...Base-1.7-TableSerialization-Compatibility.proto |   56 +
 .../org/apache/hadoop/hbase/master/HMaster.java    |    9 +
 .../hadoop/hbase/util/FSTableDescriptors.java      |   77 +-
 7 files changed, 1855 insertions(+), 15 deletions(-)

diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/DeprecatedTableDescriptor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/DeprecatedTableDescriptor.java
new file mode 100644
index 0000000..b239ffa
--- /dev/null
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/DeprecatedTableDescriptor.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+package org.apache.hadoop.hbase;
+
+import com.google.protobuf.InvalidProtocolBufferException;
+import org.apache.hadoop.hbase.classification.InterfaceAudience;
+import org.apache.hadoop.hbase.exceptions.DeserializationException;
+import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
+import org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor;
+import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.Table;
+import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.Table.State;
+
+/**
+ * Only used for HBase 1.7.0 compatibility sakes.
+ */
+@InterfaceAudience.Private
+public final class DeprecatedTableDescriptor {
+
+  private HTableDescriptor hTableDescriptor;
+  private Table tableState;
+
+  private DeprecatedTableDescriptor(HTableDescriptor hTableDescriptor, Table tableState) {
+    this.hTableDescriptor = hTableDescriptor;
+    this.tableState = tableState;
+  }
+
+  public HTableDescriptor getHTableDescriptor() {
+    return hTableDescriptor;
+  }
+
+  public Table getTableState() {
+    return tableState;
+  }
+
+  /**
+   * Utility method to parse bytes serialized as incompatible TableDescriptors.
+   * @param bytes A pb serialized {@link TableDescriptor} instance with pb magic prefix
+   */
+  public static DeprecatedTableDescriptor parseFrom(final byte [] bytes)
+      throws DeserializationException {
+    if (!ProtobufUtil.isPBMagicPrefix(bytes)) {
+      throw new DeserializationException("Expected PB encoded TableDescriptor");
+    }
+    int pblen = ProtobufUtil.lengthOfPBMagic();
+    TableDescriptor.Builder builder = TableDescriptor.newBuilder();
+    TableDescriptor ts;
+    try {
+      ts = builder.mergeFrom(bytes, pblen, bytes.length - pblen).build();
+    } catch (InvalidProtocolBufferException e) {
+      throw new DeserializationException(e);
+    }
+    return convert(ts);
+  }
+
+  private static DeprecatedTableDescriptor convert(TableDescriptor proto) {
+    HTableDescriptor hTableDescriptor = HTableDescriptor.convert(proto.getSchema());
+    State state = State.valueOf(proto.getState().getNumber());
+    Table tableState = Table.newBuilder().setState(state).build();
+    return new DeprecatedTableDescriptor(hTableDescriptor, tableState);
+  }
+}
diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java
index ca39b98..3bdd7d3 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/HTableDescriptor.java
@@ -1707,12 +1707,16 @@ public class HTableDescriptor implements WritableComparable<HTableDescriptor> {
     try {
       ProtobufUtil.mergeFrom(builder, bytes, pblen, bytes.length - pblen);
       ts = builder.build();
-    } catch (IOException e) {
+      return convert(ts);
+    } catch (IOException | IllegalArgumentException e) {
+      // Deserialization may not fail but can return garbage that fails eventual validations and
+      // hence IAE.
       throw new DeserializationException(e);
     }
-    return convert(ts);
   }
 
+
+
   /**
    * @return Convert the current {@link HTableDescriptor} into a pb TableSchema instance.
    */
diff --git a/hbase-protocol/pom.xml b/hbase-protocol/pom.xml
index 9c9dbda..7e40dec 100644
--- a/hbase-protocol/pom.xml
+++ b/hbase-protocol/pom.xml
@@ -182,6 +182,7 @@
                           <include>FS.proto</include>
                           <include>Filter.proto</include>
                           <include>HBase.proto</include>
+                          <include>HBase-1.7-TableSerialization-Compatibility.proto</include>
                           <include>HFile.proto</include>
                           <include>LoadBalancer.proto</include>
                           <include>MapReduce.proto</include>
diff --git a/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/HBase170CompatibilityProtos.java b/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/HBase170CompatibilityProtos.java
new file mode 100644
index 0000000..e09f8a6
--- /dev/null
+++ b/hbase-protocol/src/main/java/org/apache/hadoop/hbase/protobuf/generated/HBase170CompatibilityProtos.java
@@ -0,0 +1,1642 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: HBase-1.7-TableSerialization-Compatibility.proto
+
+package org.apache.hadoop.hbase.protobuf.generated;
+
+public final class HBase170CompatibilityProtos {
+  private HBase170CompatibilityProtos() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+  }
+  public interface TableStateOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .hbase.pb.TableState.State state = 1;
+    /**
+     * <code>required .hbase.pb.TableState.State state = 1;</code>
+     *
+     * <pre>
+     * This is the table's state.
+     * </pre>
+     */
+    boolean hasState();
+    /**
+     * <code>required .hbase.pb.TableState.State state = 1;</code>
+     *
+     * <pre>
+     * This is the table's state.
+     * </pre>
+     */
+    org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State getState();
+
+    // required .hbase.pb.TableName table = 2;
+    /**
+     * <code>required .hbase.pb.TableName table = 2;</code>
+     */
+    boolean hasTable();
+    /**
+     * <code>required .hbase.pb.TableName table = 2;</code>
+     */
+    org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName getTable();
+    /**
+     * <code>required .hbase.pb.TableName table = 2;</code>
+     */
+    org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableNameOrBuilder getTableOrBuilder();
+
+    // optional uint64 timestamp = 3;
+    /**
+     * <code>optional uint64 timestamp = 3;</code>
+     */
+    boolean hasTimestamp();
+    /**
+     * <code>optional uint64 timestamp = 3;</code>
+     */
+    long getTimestamp();
+  }
+  /**
+   * Protobuf type {@code hbase.pb.TableState}
+   *
+   * <pre>
+   ** Denotes state of the table 
+   * </pre>
+   */
+  public static final class TableState extends
+      com.google.protobuf.GeneratedMessage
+      implements TableStateOrBuilder {
+    // Use TableState.newBuilder() to construct.
+    private TableState(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private TableState(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final TableState defaultInstance;
+    public static TableState getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public TableState getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private TableState(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 8: {
+              int rawValue = input.readEnum();
+              org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State value = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.valueOf(rawValue);
+              if (value == null) {
+                unknownFields.mergeVarintField(1, rawValue);
+              } else {
+                bitField0_ |= 0x00000001;
+                state_ = value;
+              }
+              break;
+            }
+            case 18: {
+              org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000002) == 0x00000002)) {
+                subBuilder = table_.toBuilder();
+              }
+              table_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(table_);
+                table_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000002;
+              break;
+            }
+            case 24: {
+              bitField0_ |= 0x00000004;
+              timestamp_ = input.readUInt64();
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableState_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableState_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.class, org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<TableState> PARSER =
+        new com.google.protobuf.AbstractParser<TableState>() {
+      public TableState parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new TableState(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<TableState> getParserForType() {
+      return PARSER;
+    }
+
+    /**
+     * Protobuf enum {@code hbase.pb.TableState.State}
+     *
+     * <pre>
+     * Table's current state
+     * </pre>
+     */
+    public enum State
+        implements com.google.protobuf.ProtocolMessageEnum {
+      /**
+       * <code>ENABLED = 0;</code>
+       */
+      ENABLED(0, 0),
+      /**
+       * <code>DISABLED = 1;</code>
+       */
+      DISABLED(1, 1),
+      /**
+       * <code>DISABLING = 2;</code>
+       */
+      DISABLING(2, 2),
+      /**
+       * <code>ENABLING = 3;</code>
+       */
+      ENABLING(3, 3),
+      ;
+
+      /**
+       * <code>ENABLED = 0;</code>
+       */
+      public static final int ENABLED_VALUE = 0;
+      /**
+       * <code>DISABLED = 1;</code>
+       */
+      public static final int DISABLED_VALUE = 1;
+      /**
+       * <code>DISABLING = 2;</code>
+       */
+      public static final int DISABLING_VALUE = 2;
+      /**
+       * <code>ENABLING = 3;</code>
+       */
+      public static final int ENABLING_VALUE = 3;
+
+
+      public final int getNumber() { return value; }
+
+      public static State valueOf(int value) {
+        switch (value) {
+          case 0: return ENABLED;
+          case 1: return DISABLED;
+          case 2: return DISABLING;
+          case 3: return ENABLING;
+          default: return null;
+        }
+      }
+
+      public static com.google.protobuf.Internal.EnumLiteMap<State>
+          internalGetValueMap() {
+        return internalValueMap;
+      }
+      private static com.google.protobuf.Internal.EnumLiteMap<State>
+          internalValueMap =
+            new com.google.protobuf.Internal.EnumLiteMap<State>() {
+              public State findValueByNumber(int number) {
+                return State.valueOf(number);
+              }
+            };
+
+      public final com.google.protobuf.Descriptors.EnumValueDescriptor
+          getValueDescriptor() {
+        return getDescriptor().getValues().get(index);
+      }
+      public final com.google.protobuf.Descriptors.EnumDescriptor
+          getDescriptorForType() {
+        return getDescriptor();
+      }
+      public static final com.google.protobuf.Descriptors.EnumDescriptor
+          getDescriptor() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.getDescriptor().getEnumTypes().get(0);
+      }
+
+      private static final State[] VALUES = values();
+
+      public static State valueOf(
+          com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+        if (desc.getType() != getDescriptor()) {
+          throw new java.lang.IllegalArgumentException(
+            "EnumValueDescriptor is not for this type.");
+        }
+        return VALUES[desc.getIndex()];
+      }
+
+      private final int index;
+      private final int value;
+
+      private State(int index, int value) {
+        this.index = index;
+        this.value = value;
+      }
+
+      // @@protoc_insertion_point(enum_scope:hbase.pb.TableState.State)
+    }
+
+    private int bitField0_;
+    // required .hbase.pb.TableState.State state = 1;
+    public static final int STATE_FIELD_NUMBER = 1;
+    private org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State state_;
+    /**
+     * <code>required .hbase.pb.TableState.State state = 1;</code>
+     *
+     * <pre>
+     * This is the table's state.
+     * </pre>
+     */
+    public boolean hasState() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .hbase.pb.TableState.State state = 1;</code>
+     *
+     * <pre>
+     * This is the table's state.
+     * </pre>
+     */
+    public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State getState() {
+      return state_;
+    }
+
+    // required .hbase.pb.TableName table = 2;
+    public static final int TABLE_FIELD_NUMBER = 2;
+    private org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName table_;
+    /**
+     * <code>required .hbase.pb.TableName table = 2;</code>
+     */
+    public boolean hasTable() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>required .hbase.pb.TableName table = 2;</code>
+     */
+    public org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName getTable() {
+      return table_;
+    }
+    /**
+     * <code>required .hbase.pb.TableName table = 2;</code>
+     */
+    public org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableNameOrBuilder getTableOrBuilder() {
+      return table_;
+    }
+
+    // optional uint64 timestamp = 3;
+    public static final int TIMESTAMP_FIELD_NUMBER = 3;
+    private long timestamp_;
+    /**
+     * <code>optional uint64 timestamp = 3;</code>
+     */
+    public boolean hasTimestamp() {
+      return ((bitField0_ & 0x00000004) == 0x00000004);
+    }
+    /**
+     * <code>optional uint64 timestamp = 3;</code>
+     */
+    public long getTimestamp() {
+      return timestamp_;
+    }
+
+    private void initFields() {
+      state_ = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.ENABLED;
+      table_ = org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.getDefaultInstance();
+      timestamp_ = 0L;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasState()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasTable()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getTable().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeEnum(1, state_.getNumber());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeMessage(2, table_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        output.writeUInt64(3, timestamp_);
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(1, state_.getNumber());
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, table_);
+      }
+      if (((bitField0_ & 0x00000004) == 0x00000004)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt64Size(3, timestamp_);
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState)) {
+        return super.equals(obj);
+      }
+      org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState other = (org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState) obj;
+
+      boolean result = true;
+      result = result && (hasState() == other.hasState());
+      if (hasState()) {
+        result = result &&
+            (getState() == other.getState());
+      }
+      result = result && (hasTable() == other.hasTable());
+      if (hasTable()) {
+        result = result && getTable()
+            .equals(other.getTable());
+      }
+      result = result && (hasTimestamp() == other.hasTimestamp());
+      if (hasTimestamp()) {
+        result = result && (getTimestamp()
+            == other.getTimestamp());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasState()) {
+        hash = (37 * hash) + STATE_FIELD_NUMBER;
+        hash = (53 * hash) + hashEnum(getState());
+      }
+      if (hasTable()) {
+        hash = (37 * hash) + TABLE_FIELD_NUMBER;
+        hash = (53 * hash) + getTable().hashCode();
+      }
+      if (hasTimestamp()) {
+        hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
+        hash = (53 * hash) + hashLong(getTimestamp());
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code hbase.pb.TableState}
+     *
+     * <pre>
+     ** Denotes state of the table 
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableStateOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableState_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableState_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.class, org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.Builder.class);
+      }
+
+      // Construct using org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getTableFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        state_ = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.ENABLED;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        if (tableBuilder_ == null) {
+          table_ = org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.getDefaultInstance();
+        } else {
+          tableBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        timestamp_ = 0L;
+        bitField0_ = (bitField0_ & ~0x00000004);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableState_descriptor;
+      }
+
+      public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState getDefaultInstanceForType() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.getDefaultInstance();
+      }
+
+      public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState build() {
+        org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState buildPartial() {
+        org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState result = new org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        result.state_ = state_;
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        if (tableBuilder_ == null) {
+          result.table_ = table_;
+        } else {
+          result.table_ = tableBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
+          to_bitField0_ |= 0x00000004;
+        }
+        result.timestamp_ = timestamp_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState) {
+          return mergeFrom((org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState other) {
+        if (other == org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.getDefaultInstance()) return this;
+        if (other.hasState()) {
+          setState(other.getState());
+        }
+        if (other.hasTable()) {
+          mergeTable(other.getTable());
+        }
+        if (other.hasTimestamp()) {
+          setTimestamp(other.getTimestamp());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasState()) {
+          
+          return false;
+        }
+        if (!hasTable()) {
+          
+          return false;
+        }
+        if (!getTable().isInitialized()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .hbase.pb.TableState.State state = 1;
+      private org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State state_ = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.ENABLED;
+      /**
+       * <code>required .hbase.pb.TableState.State state = 1;</code>
+       *
+       * <pre>
+       * This is the table's state.
+       * </pre>
+       */
+      public boolean hasState() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .hbase.pb.TableState.State state = 1;</code>
+       *
+       * <pre>
+       * This is the table's state.
+       * </pre>
+       */
+      public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State getState() {
+        return state_;
+      }
+      /**
+       * <code>required .hbase.pb.TableState.State state = 1;</code>
+       *
+       * <pre>
+       * This is the table's state.
+       * </pre>
+       */
+      public Builder setState(org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        bitField0_ |= 0x00000001;
+        state_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableState.State state = 1;</code>
+       *
+       * <pre>
+       * This is the table's state.
+       * </pre>
+       */
+      public Builder clearState() {
+        bitField0_ = (bitField0_ & ~0x00000001);
+        state_ = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.ENABLED;
+        onChanged();
+        return this;
+      }
+
+      // required .hbase.pb.TableName table = 2;
+      private org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName table_ = org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName, org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.Builder, org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableNameOrBuilder> tableBuilder_;
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      public boolean hasTable() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      public org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName getTable() {
+        if (tableBuilder_ == null) {
+          return table_;
+        } else {
+          return tableBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      public Builder setTable(org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName value) {
+        if (tableBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          table_ = value;
+          onChanged();
+        } else {
+          tableBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      public Builder setTable(
+          org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.Builder builderForValue) {
+        if (tableBuilder_ == null) {
+          table_ = builderForValue.build();
+          onChanged();
+        } else {
+          tableBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      public Builder mergeTable(org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName value) {
+        if (tableBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) == 0x00000002) &&
+              table_ != org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.getDefaultInstance()) {
+            table_ =
+              org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.newBuilder(table_).mergeFrom(value).buildPartial();
+          } else {
+            table_ = value;
+          }
+          onChanged();
+        } else {
+          tableBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000002;
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      public Builder clearTable() {
+        if (tableBuilder_ == null) {
+          table_ = org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.getDefaultInstance();
+          onChanged();
+        } else {
+          tableBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      public org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.Builder getTableBuilder() {
+        bitField0_ |= 0x00000002;
+        onChanged();
+        return getTableFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      public org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableNameOrBuilder getTableOrBuilder() {
+        if (tableBuilder_ != null) {
+          return tableBuilder_.getMessageOrBuilder();
+        } else {
+          return table_;
+        }
+      }
+      /**
+       * <code>required .hbase.pb.TableName table = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName, org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.Builder, org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableNameOrBuilder> 
+          getTableFieldBuilder() {
+        if (tableBuilder_ == null) {
+          tableBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName, org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableName.Builder, org.apache.hadoop.hbase.protobuf.generated.TableProtos.TableNameOrBuilder>(
+                  table_,
+                  getParentForChildren(),
+                  isClean());
+          table_ = null;
+        }
+        return tableBuilder_;
+      }
+
+      // optional uint64 timestamp = 3;
+      private long timestamp_ ;
+      /**
+       * <code>optional uint64 timestamp = 3;</code>
+       */
+      public boolean hasTimestamp() {
+        return ((bitField0_ & 0x00000004) == 0x00000004);
+      }
+      /**
+       * <code>optional uint64 timestamp = 3;</code>
+       */
+      public long getTimestamp() {
+        return timestamp_;
+      }
+      /**
+       * <code>optional uint64 timestamp = 3;</code>
+       */
+      public Builder setTimestamp(long value) {
+        bitField0_ |= 0x00000004;
+        timestamp_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional uint64 timestamp = 3;</code>
+       */
+      public Builder clearTimestamp() {
+        bitField0_ = (bitField0_ & ~0x00000004);
+        timestamp_ = 0L;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:hbase.pb.TableState)
+    }
+
+    static {
+      defaultInstance = new TableState(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:hbase.pb.TableState)
+  }
+
+  public interface TableDescriptorOrBuilder
+      extends com.google.protobuf.MessageOrBuilder {
+
+    // required .hbase.pb.TableSchema schema = 1;
+    /**
+     * <code>required .hbase.pb.TableSchema schema = 1;</code>
+     */
+    boolean hasSchema();
+    /**
+     * <code>required .hbase.pb.TableSchema schema = 1;</code>
+     */
+    org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema getSchema();
+    /**
+     * <code>required .hbase.pb.TableSchema schema = 1;</code>
+     */
+    org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchemaOrBuilder getSchemaOrBuilder();
+
+    // optional .hbase.pb.TableState.State state = 2 [default = ENABLED];
+    /**
+     * <code>optional .hbase.pb.TableState.State state = 2 [default = ENABLED];</code>
+     */
+    boolean hasState();
+    /**
+     * <code>optional .hbase.pb.TableState.State state = 2 [default = ENABLED];</code>
+     */
+    org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State getState();
+  }
+  /**
+   * Protobuf type {@code hbase.pb.TableDescriptor}
+   *
+   * <pre>
+   ** On HDFS representation of table state. 
+   * </pre>
+   */
+  public static final class TableDescriptor extends
+      com.google.protobuf.GeneratedMessage
+      implements TableDescriptorOrBuilder {
+    // Use TableDescriptor.newBuilder() to construct.
+    private TableDescriptor(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
+      super(builder);
+      this.unknownFields = builder.getUnknownFields();
+    }
+    private TableDescriptor(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
+
+    private static final TableDescriptor defaultInstance;
+    public static TableDescriptor getDefaultInstance() {
+      return defaultInstance;
+    }
+
+    public TableDescriptor getDefaultInstanceForType() {
+      return defaultInstance;
+    }
+
+    private final com.google.protobuf.UnknownFieldSet unknownFields;
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+        getUnknownFields() {
+      return this.unknownFields;
+    }
+    private TableDescriptor(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      initFields();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(input, unknownFields,
+                                     extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+            case 10: {
+              org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) == 0x00000001)) {
+                subBuilder = schema_.toBuilder();
+              }
+              schema_ = input.readMessage(org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.PARSER, extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(schema_);
+                schema_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 16: {
+              int rawValue = input.readEnum();
+              org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State value = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.valueOf(rawValue);
+              if (value == null) {
+                unknownFields.mergeVarintField(2, rawValue);
+              } else {
+                bitField0_ |= 0x00000002;
+                state_ = value;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e.getMessage()).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableDescriptor_descriptor;
+    }
+
+    protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableDescriptor_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor.class, org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor.Builder.class);
+    }
+
+    public static com.google.protobuf.Parser<TableDescriptor> PARSER =
+        new com.google.protobuf.AbstractParser<TableDescriptor>() {
+      public TableDescriptor parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new TableDescriptor(input, extensionRegistry);
+      }
+    };
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<TableDescriptor> getParserForType() {
+      return PARSER;
+    }
+
+    private int bitField0_;
+    // required .hbase.pb.TableSchema schema = 1;
+    public static final int SCHEMA_FIELD_NUMBER = 1;
+    private org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema schema_;
+    /**
+     * <code>required .hbase.pb.TableSchema schema = 1;</code>
+     */
+    public boolean hasSchema() {
+      return ((bitField0_ & 0x00000001) == 0x00000001);
+    }
+    /**
+     * <code>required .hbase.pb.TableSchema schema = 1;</code>
+     */
+    public org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema getSchema() {
+      return schema_;
+    }
+    /**
+     * <code>required .hbase.pb.TableSchema schema = 1;</code>
+     */
+    public org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchemaOrBuilder getSchemaOrBuilder() {
+      return schema_;
+    }
+
+    // optional .hbase.pb.TableState.State state = 2 [default = ENABLED];
+    public static final int STATE_FIELD_NUMBER = 2;
+    private org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State state_;
+    /**
+     * <code>optional .hbase.pb.TableState.State state = 2 [default = ENABLED];</code>
+     */
+    public boolean hasState() {
+      return ((bitField0_ & 0x00000002) == 0x00000002);
+    }
+    /**
+     * <code>optional .hbase.pb.TableState.State state = 2 [default = ENABLED];</code>
+     */
+    public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State getState() {
+      return state_;
+    }
+
+    private void initFields() {
+      schema_ = org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.getDefaultInstance();
+      state_ = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.ENABLED;
+    }
+    private byte memoizedIsInitialized = -1;
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized != -1) return isInitialized == 1;
+
+      if (!hasSchema()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!getSchema().isInitialized()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        output.writeMessage(1, schema_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        output.writeEnum(2, state_.getNumber());
+      }
+      getUnknownFields().writeTo(output);
+    }
+
+    private int memoizedSerializedSize = -1;
+    public int getSerializedSize() {
+      int size = memoizedSerializedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (((bitField0_ & 0x00000001) == 0x00000001)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, schema_);
+      }
+      if (((bitField0_ & 0x00000002) == 0x00000002)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(2, state_.getNumber());
+      }
+      size += getUnknownFields().getSerializedSize();
+      memoizedSerializedSize = size;
+      return size;
+    }
+
+    private static final long serialVersionUID = 0L;
+    @java.lang.Override
+    protected java.lang.Object writeReplace()
+        throws java.io.ObjectStreamException {
+      return super.writeReplace();
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor)) {
+        return super.equals(obj);
+      }
+      org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor other = (org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor) obj;
+
+      boolean result = true;
+      result = result && (hasSchema() == other.hasSchema());
+      if (hasSchema()) {
+        result = result && getSchema()
+            .equals(other.getSchema());
+      }
+      result = result && (hasState() == other.hasState());
+      if (hasState()) {
+        result = result &&
+            (getState() == other.getState());
+      }
+      result = result &&
+          getUnknownFields().equals(other.getUnknownFields());
+      return result;
+    }
+
+    private int memoizedHashCode = 0;
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptorForType().hashCode();
+      if (hasSchema()) {
+        hash = (37 * hash) + SCHEMA_FIELD_NUMBER;
+        hash = (53 * hash) + getSchema().hashCode();
+      }
+      if (hasState()) {
+        hash = (37 * hash) + STATE_FIELD_NUMBER;
+        hash = (53 * hash) + hashEnum(getState());
+      }
+      hash = (29 * hash) + getUnknownFields().hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseDelimitedFrom(input, extensionRegistry);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input);
+    }
+    public static org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return PARSER.parseFrom(input, extensionRegistry);
+    }
+
+    public static Builder newBuilder() { return Builder.create(); }
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder(org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor prototype) {
+      return newBuilder().mergeFrom(prototype);
+    }
+    public Builder toBuilder() { return newBuilder(this); }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code hbase.pb.TableDescriptor}
+     *
+     * <pre>
+     ** On HDFS representation of table state. 
+     * </pre>
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessage.Builder<Builder>
+       implements org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptorOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableDescriptor_descriptor;
+      }
+
+      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableDescriptor_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor.class, org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor.Builder.class);
+      }
+
+      // Construct using org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
+          getSchemaFieldBuilder();
+        }
+      }
+      private static Builder create() {
+        return new Builder();
+      }
+
+      public Builder clear() {
+        super.clear();
+        if (schemaBuilder_ == null) {
+          schema_ = org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.getDefaultInstance();
+        } else {
+          schemaBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        state_ = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.ENABLED;
+        bitField0_ = (bitField0_ & ~0x00000002);
+        return this;
+      }
+
+      public Builder clone() {
+        return create().mergeFrom(buildPartial());
+      }
+
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.internal_static_hbase_pb_TableDescriptor_descriptor;
+      }
+
+      public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor getDefaultInstanceForType() {
+        return org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor.getDefaultInstance();
+      }
+
+      public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor build() {
+        org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor buildPartial() {
+        org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor result = new org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
+          to_bitField0_ |= 0x00000001;
+        }
+        if (schemaBuilder_ == null) {
+          result.schema_ = schema_;
+        } else {
+          result.schema_ = schemaBuilder_.build();
+        }
+        if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
+          to_bitField0_ |= 0x00000002;
+        }
+        result.state_ = state_;
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor) {
+          return mergeFrom((org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor other) {
+        if (other == org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor.getDefaultInstance()) return this;
+        if (other.hasSchema()) {
+          mergeSchema(other.getSchema());
+        }
+        if (other.hasState()) {
+          setState(other.getState());
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        if (!hasSchema()) {
+          
+          return false;
+        }
+        if (!getSchema().isInitialized()) {
+          
+          return false;
+        }
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableDescriptor) e.getUnfinishedMessage();
+          throw e;
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      // required .hbase.pb.TableSchema schema = 1;
+      private org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema schema_ = org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.getDefaultInstance();
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema, org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.Builder, org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchemaOrBuilder> schemaBuilder_;
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      public boolean hasSchema() {
+        return ((bitField0_ & 0x00000001) == 0x00000001);
+      }
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      public org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema getSchema() {
+        if (schemaBuilder_ == null) {
+          return schema_;
+        } else {
+          return schemaBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      public Builder setSchema(org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema value) {
+        if (schemaBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          schema_ = value;
+          onChanged();
+        } else {
+          schemaBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      public Builder setSchema(
+          org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.Builder builderForValue) {
+        if (schemaBuilder_ == null) {
+          schema_ = builderForValue.build();
+          onChanged();
+        } else {
+          schemaBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      public Builder mergeSchema(org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema value) {
+        if (schemaBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) == 0x00000001) &&
+              schema_ != org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.getDefaultInstance()) {
+            schema_ =
+              org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.newBuilder(schema_).mergeFrom(value).buildPartial();
+          } else {
+            schema_ = value;
+          }
+          onChanged();
+        } else {
+          schemaBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      public Builder clearSchema() {
+        if (schemaBuilder_ == null) {
+          schema_ = org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.getDefaultInstance();
+          onChanged();
+        } else {
+          schemaBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      public org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.Builder getSchemaBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getSchemaFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      public org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchemaOrBuilder getSchemaOrBuilder() {
+        if (schemaBuilder_ != null) {
+          return schemaBuilder_.getMessageOrBuilder();
+        } else {
+          return schema_;
+        }
+      }
+      /**
+       * <code>required .hbase.pb.TableSchema schema = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilder<
+          org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema, org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.Builder, org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchemaOrBuilder> 
+          getSchemaFieldBuilder() {
+        if (schemaBuilder_ == null) {
+          schemaBuilder_ = new com.google.protobuf.SingleFieldBuilder<
+              org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema, org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchema.Builder, org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.TableSchemaOrBuilder>(
+                  schema_,
+                  getParentForChildren(),
+                  isClean());
+          schema_ = null;
+        }
+        return schemaBuilder_;
+      }
+
+      // optional .hbase.pb.TableState.State state = 2 [default = ENABLED];
+      private org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State state_ = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.ENABLED;
+      /**
+       * <code>optional .hbase.pb.TableState.State state = 2 [default = ENABLED];</code>
+       */
+      public boolean hasState() {
+        return ((bitField0_ & 0x00000002) == 0x00000002);
+      }
+      /**
+       * <code>optional .hbase.pb.TableState.State state = 2 [default = ENABLED];</code>
+       */
+      public org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State getState() {
+        return state_;
+      }
+      /**
+       * <code>optional .hbase.pb.TableState.State state = 2 [default = ENABLED];</code>
+       */
+      public Builder setState(org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        bitField0_ |= 0x00000002;
+        state_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional .hbase.pb.TableState.State state = 2 [default = ENABLED];</code>
+       */
+      public Builder clearState() {
+        bitField0_ = (bitField0_ & ~0x00000002);
+        state_ = org.apache.hadoop.hbase.protobuf.generated.HBase170CompatibilityProtos.TableState.State.ENABLED;
+        onChanged();
+        return this;
+      }
+
+      // @@protoc_insertion_point(builder_scope:hbase.pb.TableDescriptor)
+    }
+
+    static {
+      defaultInstance = new TableDescriptor(true);
+      defaultInstance.initFields();
+    }
+
+    // @@protoc_insertion_point(class_scope:hbase.pb.TableDescriptor)
+  }
+
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_hbase_pb_TableState_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_hbase_pb_TableState_fieldAccessorTable;
+  private static com.google.protobuf.Descriptors.Descriptor
+    internal_static_hbase_pb_TableDescriptor_descriptor;
+  private static
+    com.google.protobuf.GeneratedMessage.FieldAccessorTable
+      internal_static_hbase_pb_TableDescriptor_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n0HBase-1.7-TableSerialization-Compatibi" +
+      "lity.proto\022\010hbase.pb\032\013HBase.proto\032\013Table" +
+      ".proto\"\257\001\n\nTableState\022)\n\005state\030\001 \002(\0162\032.h" +
+      "base.pb.TableState.State\022\"\n\005table\030\002 \002(\0132" +
+      "\023.hbase.pb.TableName\022\021\n\ttimestamp\030\003 \001(\004\"" +
+      "?\n\005State\022\013\n\007ENABLED\020\000\022\014\n\010DISABLED\020\001\022\r\n\tD" +
+      "ISABLING\020\002\022\014\n\010ENABLING\020\003\"l\n\017TableDescrip" +
+      "tor\022%\n\006schema\030\001 \002(\0132\025.hbase.pb.TableSche" +
+      "ma\0222\n\005state\030\002 \001(\0162\032.hbase.pb.TableState." +
+      "State:\007ENABLEDBN\n*org.apache.hadoop.hbas",
+      "e.protobuf.generatedB\033HBase170Compatibil" +
+      "ityProtosH\001\240\001\001"
+    };
+    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
+      new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
+        public com.google.protobuf.ExtensionRegistry assignDescriptors(
+            com.google.protobuf.Descriptors.FileDescriptor root) {
+          descriptor = root;
+          internal_static_hbase_pb_TableState_descriptor =
+            getDescriptor().getMessageTypes().get(0);
+          internal_static_hbase_pb_TableState_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_hbase_pb_TableState_descriptor,
+              new java.lang.String[] { "State", "Table", "Timestamp", });
+          internal_static_hbase_pb_TableDescriptor_descriptor =
+            getDescriptor().getMessageTypes().get(1);
+          internal_static_hbase_pb_TableDescriptor_fieldAccessorTable = new
+            com.google.protobuf.GeneratedMessage.FieldAccessorTable(
+              internal_static_hbase_pb_TableDescriptor_descriptor,
+              new java.lang.String[] { "Schema", "State", });
+          return null;
+        }
+      };
+    com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.getDescriptor(),
+          org.apache.hadoop.hbase.protobuf.generated.TableProtos.getDescriptor(),
+        }, assigner);
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/hbase-protocol/src/main/protobuf/HBase-1.7-TableSerialization-Compatibility.proto b/hbase-protocol/src/main/protobuf/HBase-1.7-TableSerialization-Compatibility.proto
new file mode 100644
index 0000000..7886574
--- /dev/null
+++ b/hbase-protocol/src/main/protobuf/HBase-1.7-TableSerialization-Compatibility.proto
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+package hbase.pb;
+option java_package = "org.apache.hadoop.hbase.protobuf.generated";
+option java_outer_classname = "HBase170CompatibilityProtos";
+option java_generate_equals_and_hash = true;
+option optimize_for = SPEED;
+
+import "HBase.proto";
+import "Table.proto";
+
+/**
+  See HBASE-26021 for context. This exists because of an incompatible change committed to
+  HBase 1.7.0 release. This change was reverted in 1.7.1 but in order to provide an upgrade path
+  for the users who installed 1.7.0, we need to be able to read the serialized TableState
+  definitions from TableDescriptor objects and convert them in HBase 1.7.1 compatible definitions
+  for a smooth upgrade. Other than this use case, these proto definitions are not expected to be
+  used anywhere in the code.
+ */
+
+/** Denotes state of the table */
+message TableState {
+  // Table's current state
+  enum State {
+    ENABLED = 0;
+    DISABLED = 1;
+    DISABLING = 2;
+    ENABLING = 3;
+  }
+  // This is the table's state.
+  required State state = 1;
+  required TableName table = 2;
+  optional uint64 timestamp = 3;
+}
+
+/** On HDFS representation of table state. */
+message TableDescriptor {
+  required TableSchema schema = 1;
+  optional TableState.State state = 2 [ default = ENABLED ];
+}
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index e7c2f1a..2d052e3 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -163,6 +163,7 @@ import org.apache.hadoop.hbase.util.CommonFSUtils;
 import org.apache.hadoop.hbase.util.CompressionTest;
 import org.apache.hadoop.hbase.util.ConfigUtil;
 import org.apache.hadoop.hbase.util.EncryptionTest;
+import org.apache.hadoop.hbase.util.FSTableDescriptors;
 import org.apache.hadoop.hbase.util.HFileArchiveUtil;
 import org.apache.hadoop.hbase.util.HasThread;
 import org.apache.hadoop.hbase.util.ModifyRegionUtils;
@@ -760,12 +761,20 @@ public class HMaster extends HRegionServer implements MasterServices, Server {
      * below after we determine if cluster startup or failover.
      */
 
+    // Repair any table descriptors from 1.7.0, if any. See HBASE-26021 for context.
+    // This should be done before Master FS init as the system tables could be with faulty
+    // serialization.
+    if (tableDescriptors instanceof FSTableDescriptors) {
+      ((FSTableDescriptors)tableDescriptors).repairHBase170TableDescriptors(zooKeeper);
+    }
+
     status.setStatus("Initializing Master file system");
 
     this.masterActiveTime = System.currentTimeMillis();
     // TODO: Do this using Dependency Injection, using PicoContainer, Guice or Spring.
     this.fileSystemManager = new MasterFileSystem(this, this);
 
+
     // enable table descriptors cache
     this.tableDescriptors.setCacheOn();
     // set the META's descriptor to the correct replication
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
index b0592cf..e475635 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
@@ -30,6 +30,7 @@ import java.util.regex.Pattern;
 import org.apache.commons.lang.NotImplementedException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.DeprecatedTableDescriptor;
 import org.apache.hadoop.hbase.classification.InterfaceAudience;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FSDataInputStream;
@@ -45,6 +46,10 @@ import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.TableDescriptors;
 import org.apache.hadoop.hbase.TableInfoMissingException;
 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
+import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.Table;
+import org.apache.hadoop.hbase.zookeeper.ZKUtil;
+import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
+import org.apache.zookeeper.KeeperException;
 
 /**
  * Implementation of {@link TableDescriptors} that reads descriptors from the
@@ -500,16 +505,20 @@ public class FSTableDescriptors implements TableDescriptors {
    * @throws TableInfoMissingException if there is no descriptor
    */
   public static HTableDescriptor getTableDescriptorFromFs(FileSystem fs, Path tableDir,
-    boolean rewritePb)
-  throws IOException {
+    boolean rewritePb) throws IOException {
     FileStatus status = getTableInfoPath(fs, tableDir, false);
     if (status == null) {
       throw new TableInfoMissingException("No table descriptor file under " + tableDir);
     }
-    return readTableDescriptor(fs, status, rewritePb);
+    return readTableDescriptor(fs, status, rewritePb).first;
   }
 
-  private static HTableDescriptor readTableDescriptor(FileSystem fs, FileStatus status,
+  /**
+   * Reads the HTableDescriptor from FS. This handles any deprecated TableDescriptor objects from
+   * HBase 1.7.0's faulty serialization and rewrites them on fs. Returns the corresponding
+   * table's State so that caller can populate it back in ZK if needed.
+   */
+  private static Pair<HTableDescriptor, Table> readTableDescriptor(FileSystem fs, FileStatus status,
       boolean rewritePb) throws IOException {
     int len = Ints.checkedCast(status.getLen());
     byte [] content = new byte[len];
@@ -520,16 +529,23 @@ public class FSTableDescriptors implements TableDescriptors {
       fsDataInputStream.close();
     }
     HTableDescriptor htd = null;
+    // From deprecated TableDescriptor, if any. Null otherwise.
+    Table tableState = null;
     try {
       htd = HTableDescriptor.parseFrom(content);
     } catch (DeserializationException e) {
       // we have old HTableDescriptor here
       try {
-        HTableDescriptor ohtd = HTableDescriptor.parseFrom(content);
-        LOG.warn("Found old table descriptor, converting to new format for table " +
-          ohtd.getTableName());
-        htd = new HTableDescriptor(ohtd);
-        if (rewritePb) rewriteTableDescriptor(fs, status, htd);
+        DeprecatedTableDescriptor dtd = DeprecatedTableDescriptor.parseFrom(content);
+        htd = dtd.getHTableDescriptor();
+        tableState = dtd.getTableState();
+        LOG.warn("Found incompatible table descriptor from 1.7.0 version: "
+          + dtd.getHTableDescriptor().getTableName() + " state: " + tableState.getState().name());
+        if (rewritePb) {
+          LOG.warn("converting to new format for table " + htd.getTableName());
+          rewriteTableDescriptor(fs, status, htd);
+          rewritePb = false; // already rewritten
+        }
       } catch (DeserializationException e1) {
         throw new IOException("content=" + Bytes.toShort(content), e1);
       }
@@ -538,12 +554,11 @@ public class FSTableDescriptors implements TableDescriptors {
       // Convert the file over to be pb before leaving here.
       rewriteTableDescriptor(fs, status, htd);
     }
-    return htd;
+    return new Pair<>(htd, tableState);
   }
 
   private static void rewriteTableDescriptor(final FileSystem fs, final FileStatus status,
-    final HTableDescriptor td)
-  throws IOException {
+    final HTableDescriptor td) throws IOException {
     Path tableInfoDir = status.getPath().getParent();
     Path tableDir = tableInfoDir.getParent();
     writeTableDescriptor(fs, td, tableDir, status);
@@ -724,7 +739,7 @@ public class FSTableDescriptors implements TableDescriptors {
       LOG.debug("Current tableInfoPath = " + status.getPath());
       if (!forceCreation) {
         if (fs.exists(status.getPath()) && status.getLen() > 0) {
-          if (readTableDescriptor(fs, status, false).equals(htd)) {
+          if (readTableDescriptor(fs, status, false).first.equals(htd)) {
             LOG.debug("TableInfo already exists.. Skipping creation");
             return false;
           }
@@ -735,5 +750,41 @@ public class FSTableDescriptors implements TableDescriptors {
     return p != null;
   }
 
+  /**
+   * Reads all the table descriptors fs and populates any missing TableStates. Should be called once
+   * at HMaster bootstrap before calling any other FSDescriptors methods as they can potentially
+   * overwrite the descriptors states. Not thread safe.
+   */
+  public void repairHBase170TableDescriptors(final ZooKeeperWatcher zkw)
+      throws IOException, KeeperException {
+    LOG.info("Attempting to repair HBase 1.7.0 tables, if any.");
+    for (Path tableDir : FSUtils.getTableDirs(fs, rootdir)) {
+      FileStatus status = getTableInfoPath(fs, tableDir, false);
+      if (status == null) {
+        LOG.warn("No table descriptor file under " + tableDir);
+        continue;
+      }
+      // Read and rewrite the table descriptors from FS, if any.
+      Pair<HTableDescriptor, Table> result = readTableDescriptor(fs, status, true);
+      if (result.second == null) {
+        // No deprecated TableDescriptor
+        continue;
+      }
+      TableName tableName = result.first.getTableName();
+      Table tableState = result.second;
+      LOG.warn("Rewriting ZK Table state for table " + tableName);
+      // Tricky to plumb TSM here, so instead assume ZK based TSM as default and overwrite table
+      // state Znodes.
+      String znode = ZKUtil.joinZNode(zkw.tableZNode, tableName.getNameAsString());
+      if (ZKUtil.checkExists(zkw, znode) != -1) {
+        LOG.warn("Table state znode already exists for table: " + tableName + ". Ignoring.");
+        continue;
+      }
+      ZKUtil.createAndFailSilent(zkw, znode);
+      byte [] data = ProtobufUtil.prependPBMagic(tableState.toByteArray());
+      ZKUtil.setData(zkw, znode, data);
+      LOG.info("Repaired ZK table state for table: " + tableName);
+    }
+  }
 }