You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by vj...@apache.org on 2022/08/03 17:57:01 UTC
[phoenix] branch 5.1 updated: PHOENIX-6758 During HBase 2 upgrade Phoenix Self healing task fails to create server side connection before reading SYSTEM.TASK (#1478)
This is an automated email from the ASF dual-hosted git repository.
vjasani pushed a commit to branch 5.1
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/5.1 by this push:
new 5363c94c62 PHOENIX-6758 During HBase 2 upgrade Phoenix Self healing task fails to create server side connection before reading SYSTEM.TASK (#1478)
5363c94c62 is described below
commit 5363c94c6280daa6966c83b676481e358c9d7410
Author: Viraj Jasani <vj...@apache.org>
AuthorDate: Wed Aug 3 10:56:56 2022 -0700
PHOENIX-6758 During HBase 2 upgrade Phoenix Self healing task fails to create server side connection before reading SYSTEM.TASK (#1478)
Signed-off-by: Andrew Purtell <ap...@apache.org>
Signed-off-by: Kadir Ozdemir <ko...@apache.org>
Signed-off-by: Geoffrey Jacoby <gj...@apache.org>
---
.../phoenix/query/AdminUtilWithFallback.java | 123 +++++++++++++++++++++
.../phoenix/query/ConnectionQueryServicesImpl.java | 13 ++-
2 files changed, 131 insertions(+), 5 deletions(-)
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/AdminUtilWithFallback.java b/phoenix-core/src/main/java/org/apache/phoenix/query/AdminUtilWithFallback.java
new file mode 100644
index 0000000000..0402910df1
--- /dev/null
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/AdminUtilWithFallback.java
@@ -0,0 +1,123 @@
+/*
+ * 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.phoenix.query;
+
+import java.io.IOException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.hadoop.hbase.TableName;
+import org.apache.hadoop.hbase.client.Admin;
+import org.apache.hadoop.hbase.client.TableState;
+import org.apache.hadoop.hbase.exceptions.DeserializationException;
+import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException;
+import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.ZooKeeperProtos;
+import org.apache.hadoop.hbase.zookeeper.ZKUtil;
+import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
+import org.apache.hadoop.hbase.zookeeper.ZNodePaths;
+import org.apache.zookeeper.KeeperException;
+
+/**
+ * Admin utility class specifically useful for running Admin APIs in the middle of the
+ * rolling upgrade from HBase 1.x to 2.x versions. Some Admin APIs fail to retrieve
+ * table state details from meta table if master is running on 1.x version and coprocs are
+ * running on 2.x version. Hence, as a fallback, server side coproc can directly perform
+ * zookeeper look-up to retrieve table state data. The fallback use-cases would not be
+ * encountered for fully upgraded 2.x cluster.
+ */
+public class AdminUtilWithFallback {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AdminUtilWithFallback.class);
+
+ public static boolean tableExists(Admin admin, TableName tableName)
+ throws IOException, InterruptedException {
+ try {
+ return admin.tableExists(tableName);
+ } catch (IOException e) {
+ if (e instanceof NoSuchColumnFamilyException || (e.getCause() != null
+ && e.getCause() instanceof NoSuchColumnFamilyException)) {
+ LOG.warn("Admin API to retrieve table existence failed due to missing CF in meta."
+ + " This should happen only when HBase master is running on 1.x and"
+ + " current regionserver is on 2.x. Falling back to retrieve info from ZK.", e);
+ return getTableStateFromZk(tableName, admin) != null;
+ }
+ throw e;
+ }
+ }
+
+ private static ZooKeeperProtos.DeprecatedTableState.State getTableState(ZKWatcher zkw,
+ TableName tableName) throws KeeperException, InterruptedException {
+ String znode =
+ ZNodePaths.joinZNode(zkw.getZNodePaths().tableZNode, tableName.getNameAsString());
+ byte[] data = ZKUtil.getData(zkw, znode);
+ if (data != null && data.length > 0) {
+ try {
+ ProtobufUtil.expectPBMagicPrefix(data);
+ ZooKeeperProtos.DeprecatedTableState.Builder builder =
+ ZooKeeperProtos.DeprecatedTableState.newBuilder();
+ int magicLen = ProtobufUtil.lengthOfPBMagic();
+ ProtobufUtil.mergeFrom(builder, data, magicLen, data.length - magicLen);
+ return builder.getState();
+ } catch (IOException ioe) {
+ KeeperException ke = new KeeperException.DataInconsistencyException();
+ ke.initCause(ioe);
+ throw ke;
+ } catch (DeserializationException de) {
+ throw ZKUtil.convert(de);
+ }
+ } else {
+ return null;
+ }
+ }
+
+ private static TableState.State getTableStateFromZk(TableName tableName, Admin admin)
+ throws IOException, InterruptedException {
+ try (ZKWatcher zkWatcher = new ZKWatcher(admin.getConfiguration(), "phoenix-admin-fallback",
+ null)) {
+ ZooKeeperProtos.DeprecatedTableState.State state =
+ getTableState(zkWatcher, tableName);
+ if (state == null) {
+ return null;
+ }
+ TableState.State tableState;
+ switch (state) {
+ case ENABLED:
+ tableState = TableState.State.ENABLED;
+ break;
+ case DISABLED:
+ tableState = TableState.State.DISABLED;
+ break;
+ case DISABLING:
+ tableState = TableState.State.DISABLING;
+ break;
+ case ENABLING:
+ tableState = TableState.State.ENABLING;
+ break;
+ default:
+ throw new IOException("ZK state inconsistent");
+ }
+ return tableState;
+ } catch (KeeperException e) {
+ throw new IOException(e);
+ }
+ }
+
+}
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index 68fe9bda71..5234695077 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -514,12 +514,12 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
@Override
public Table getTableIfExists(byte[] tableName) throws SQLException {
try (Admin admin = getAdmin()) {
- if (!admin.tableExists(TableName.valueOf(tableName))) {
+ if (!AdminUtilWithFallback.tableExists(admin, TableName.valueOf(tableName))) {
throw new TableNotFoundException(
SchemaUtil.getSchemaNameFromFullName(tableName),
SchemaUtil.getTableNameFromFullName(tableName));
}
- } catch (IOException e) {
+ } catch (IOException | InterruptedException e) {
throw new SQLException(e);
}
return getTable(tableName);
@@ -1350,7 +1350,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
// if the NS does not exist, we will error as expected, or
// if the NS does exist and tables are already mapped, the check will exit gracefully
}
- if (admin.tableExists(SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, false))) {
+ if (AdminUtilWithFallback.tableExists(admin,
+ SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, false))) {
// SYSTEM.CATALOG exists, so at this point, we have 3 cases:
// 1) If server-side namespace mapping is disabled, drop the SYSTEM namespace if it was created
// above and throw Inconsistent namespace mapping exception
@@ -1374,7 +1375,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
// Thrown so we can force an upgrade which will just migrate SYSTEM tables to the SYSTEM namespace
throw new UpgradeRequiredException(MIN_SYSTEM_TABLE_TIMESTAMP);
}
- } else if (admin.tableExists(SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, true))) {
+ } else if (AdminUtilWithFallback.tableExists(admin,
+ SchemaUtil.getPhysicalTableName(SYSTEM_CATALOG_NAME_BYTES, true))) {
// If SYSTEM:CATALOG exists, but client-side namespace mapping for SYSTEM tables is disabled, throw an exception
throw new SQLExceptionInfo.Builder(
SQLExceptionCode.INCONSISTENT_NAMESPACE_MAPPING_PROPERTIES)
@@ -4499,7 +4501,8 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
.getPhysicalName(PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES, this.getProps()).getName();
metatable = getTable(mappedSystemTable);
if (tableNames.contains(PhoenixDatabaseMetaData.SYSTEM_CATALOG_HBASE_TABLE_NAME)) {
- if (!admin.tableExists(TableName.valueOf(mappedSystemTable))) {
+ if (!AdminUtilWithFallback.tableExists(admin,
+ TableName.valueOf(mappedSystemTable))) {
LOGGER.info("Migrating SYSTEM.CATALOG table to SYSTEM namespace.");
// Actual migration of SYSCAT table
UpgradeUtil.mapTableToNamespace(admin, metatable,