You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ya...@apache.org on 2020/11/25 18:25:24 UTC

[phoenix] branch master updated: PHOENIX-5920 Skip SYSTEM TABLE checks while creating phoenix connection if client has set the DoNotUpgrade config

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

yanxinyi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/phoenix.git


The following commit(s) were added to refs/heads/master by this push:
     new 457a67c  PHOENIX-5920 Skip SYSTEM TABLE checks while creating phoenix connection if client has set the DoNotUpgrade config
457a67c is described below

commit 457a67c4907bdc459801a90fe02c794529e336a2
Author: Neha <ne...@salesforce.com>
AuthorDate: Thu Nov 19 20:47:39 2020 -0800

    PHOENIX-5920 Skip SYSTEM TABLE checks while creating phoenix connection if client has set the DoNotUpgrade config
    
    Signed-off-by: Xinyi Yan <ya...@apache.org>
---
 .../apache/phoenix/end2end/BasePermissionsIT.java  |  2 +-
 .../SystemTablesCreationOnConnectionIT.java        | 40 ++++++++++++++-
 .../phoenix/query/ConnectionQueryServicesImpl.java | 57 +++++++++++-----------
 3 files changed, 69 insertions(+), 30 deletions(-)

diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BasePermissionsIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BasePermissionsIT.java
index 6d36dfc..44f383d 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/BasePermissionsIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/BasePermissionsIT.java
@@ -967,7 +967,7 @@ public abstract class BasePermissionsIT extends BaseTest {
             // NS is disabled, CQSI tries creating SYSCAT, Two cases here
             // 1. First client ever --> Gets ADE, runs client server compatibility check again and gets TableNotFoundException since SYSCAT doesn't exist
             // 2. Any other client --> Gets ADE, runs client server compatibility check again and gets AccessDeniedException since it doesn't have EXEC perms
-            verifyDenied(getConnectionAction(), TableNotFoundException.class, regularUser1);
+            verifyDenied(getConnectionAction(), org.apache.hadoop.hbase.TableNotFoundException.class, regularUser1);
         }
 
         // Phoenix Client caches connection per user
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemTablesCreationOnConnectionIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemTablesCreationOnConnectionIT.java
index 627d7b2..f09db94 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemTablesCreationOnConnectionIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/SystemTablesCreationOnConnectionIT.java
@@ -65,6 +65,7 @@ import org.apache.phoenix.util.ReadOnlyProps;
 import org.apache.phoenix.util.UpgradeUtil;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
@@ -206,7 +207,9 @@ public class SystemTablesCreationOnConnectionIT {
 
     /********************* Testing SYSTEM.CATALOG/SYSTEM:CATALOG creation/upgrade behavior for subsequent connections *********************/
 
-
+    // We are ignoring this test because we aren't testing SYSCAT timestamp anymore if
+    // "DoNotUpgrade" config is set to true
+    @Ignore
     // Conditions: server-side namespace mapping is enabled, the first connection to the server will
     // create all namespace mapped SYSTEM tables i.e. SYSTEM:.*, the SYSTEM:CATALOG timestamp at
     // creation is purposefully set to be < MetaDataProtocol.MIN_SYSTEM_TABLE_TIMESTAMP.
@@ -503,6 +506,41 @@ public class SystemTablesCreationOnConnectionIT {
         }
     }
 
+    // Conditions: doNotUpgrade config should be set and HMaster should be stopped
+    // Expected: Even if HMaster is stopped we should be able to get phoenix
+    // connection, knowing that all system tables exists already.
+    @Test
+    public void testDoNotUpgradePropSet() throws Exception {
+        String tableName = "HBASE_SYNTH_TEST";
+        startMiniClusterWithToggleNamespaceMapping(Boolean.FALSE.toString());
+        Properties propsDoNotUpgradePropSet = new Properties();
+        // Create a dummy connection to make sure we have all system tables in place
+        try (Connection con1 = DriverManager.getConnection(getJdbcUrl(), propsDoNotUpgradePropSet);
+             Statement stmt1 = con1.createStatement()) {
+            String ddl = "CREATE TABLE " + tableName + " (PK1 VARCHAR not null, " +
+                    "PK2 VARCHAR not null, COL1 varchar, COL2 varchar "
+                    + "CONSTRAINT pk PRIMARY KEY(PK1,PK2))";
+            stmt1.execute(ddl);
+            stmt1.execute(
+                    "UPSERT INTO " + tableName + " values ('pk1','pk2','c1','c2')");
+            con1.commit();
+            // Stop HMaster to check if we can create connection without active HMaster
+            testUtil.getMiniHBaseCluster().getMaster().stopMaster();
+            // Set doNotUpgradeProperty to true
+            UpgradeUtil.doNotUpgradeOnFirstConnection(propsDoNotUpgradePropSet);
+            try (Connection con2 = DriverManager.getConnection(getJdbcUrl(), propsDoNotUpgradePropSet);
+                 Statement stmt2 = con2.createStatement();
+                 ResultSet rs = stmt2.executeQuery("select * from " + tableName)) {
+                assertTrue(rs.next());
+                assertEquals("pk1", rs.getString(1));
+                assertEquals("pk2", rs.getString(2));
+                assertFalse(rs.next());
+            }
+        } finally {
+            testUtil.getMiniHBaseCluster().startMaster();
+        }
+    }
+
     /**
      * Return all created HBase tables
      * @return Set of HBase table name strings
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 2ac7ae5..bc26e39 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
@@ -1346,6 +1346,21 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                         + IS_NAMESPACE_MAPPING_ENABLED + " enabled")
                       .build().buildException();
                 }
+                // If DoNotUpgrade config is set only check namespace mapping and
+                // Client-server compatibility for system tables.
+                if(isDoNotUpgradePropSet) {
+                    try {
+                        checkClientServerCompatibility(SchemaUtil.getPhysicalName(
+                                SYSTEM_CATALOG_NAME_BYTES, this.getProps()).getName());
+                    } catch (SQLException possibleCompatException) {
+                        if(possibleCompatException.getCause()
+                                instanceof org.apache.hadoop.hbase.TableNotFoundException) {
+                            throw new UpgradeRequiredException(MIN_SYSTEM_TABLE_TIMESTAMP);
+                        }
+                        throw possibleCompatException;
+                    }
+                    return null;
+                }
             }
 
             try {
@@ -1581,19 +1596,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
         long systemCatalogTimestamp = Long.MAX_VALUE;
         Table ht = null;
         try {
-            List<HRegionLocation> locations = this
-                    .getAllTableRegions(metaTable);
-            Set<HRegionLocation> serverMap = Sets.newHashSetWithExpectedSize(locations.size());
-            TreeMap<byte[], HRegionLocation> regionMap = Maps.newTreeMap(Bytes.BYTES_COMPARATOR);
-            List<byte[]> regionKeys = Lists.newArrayListWithExpectedSize(locations.size());
-            for (HRegionLocation entry : locations) {
-                if (!serverMap.contains(entry)) {
-                    regionKeys.add(entry.getRegion().getStartKey());
-                    regionMap.put(entry.getRegion().getRegionName(), entry);
-                    serverMap.add(entry);
-                }
-            }
-
             ht = this.getTable(metaTable);
             final byte[] tablekey = PhoenixDatabaseMetaData.SYSTEM_CATALOG_NAME_BYTES;
             Map<byte[], GetVersionResponse> results;
@@ -1631,7 +1633,6 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                 MetaDataUtil.ClientServerCompatibility compatibility = MetaDataUtil.areClientAndServerCompatible(serverJarVersion);
                 if (!compatibility.getIsCompatible()) {
                     if (compatibility.getErrorCode() == SQLExceptionCode.OUTDATED_JARS.getErrorCode()) {
-                        HRegionLocation name = regionMap.get(result.getKey());
                         errorMessage.append("Newer Phoenix clients can't communicate with older "
                                 + "Phoenix servers. Client version: "
                                 + MetaDataProtocol.CURRENT_CLIENT_VERSION
@@ -1639,9 +1640,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                                 + getServerVersion(serverJarVersion)
                                 + " The following servers require an updated "
                                 + QueryConstants.DEFAULT_COPROCESS_JAR_NAME
-                                + " to be put in the classpath of HBase: ");
-                        errorMessage.append(name);
-                        errorMessage.append(';');
+                                + " to be put in the classpath of HBase.");
                     } else if (compatibility.getErrorCode() == SQLExceptionCode.INCOMPATIBLE_CLIENT_SERVER_JAR.getErrorCode()) {
                         errorMessage.append("Major version of client is less than that of the server. Client version: "
                                 + MetaDataProtocol.CURRENT_CLIENT_VERSION
@@ -3271,21 +3270,23 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices implement
                                     }
                                     return null;
                                 } catch (UpgradeRequiredException e) {
-                                    // This will occur in 3 cases:
-                                    // 1. SYSTEM.CATALOG does not exist and we don't want to allow the user to create it i.e.
-                                    //    !isAutoUpgradeEnabled or isDoNotUpgradePropSet is set
-                                    // 2. SYSTEM.CATALOG exists and its timestamp < MIN_SYSTEM_TABLE_TIMESTAMP
-                                    // 3. SYSTEM.CATALOG exists, but client and server-side namespace mapping is enabled so
-                                    //    we need to migrate SYSTEM tables to the SYSTEM namespace
+                                    // This will occur in 2 cases:
+                                    // 1. when SYSTEM.CATALOG doesn't exists
+                                    // 2. when SYSTEM.CATALOG exists, but client and
+                                    // server-side namespace mapping is enabled so
+                                    // we need to migrate SYSTEM tables to the SYSTEM namespace
                                     setUpgradeRequired();
                                 }
 
                                 if (!ConnectionQueryServicesImpl.this.upgradeRequired.get()) {
-                                    createOtherSystemTables(metaConnection);
-                                    // In case namespace mapping is enabled and system table to system namespace mapping is also enabled,
-                                    // create an entry for the SYSTEM namespace in the SYSCAT table, so that GRANT/REVOKE commands can work
-                                    // with SYSTEM Namespace
-                                    createSchemaIfNotExistsSystemNSMappingEnabled(metaConnection);
+                                    if(!isDoNotUpgradePropSet) {
+                                        createOtherSystemTables(metaConnection);
+                                        // In case namespace mapping is enabled and system table to
+                                        // system namespace mapping is also enabled, create an entry
+                                        // for the SYSTEM namespace in the SYSCAT table, so that
+                                        // GRANT/REVOKE commands can work with SYSTEM Namespace
+                                        createSchemaIfNotExistsSystemNSMappingEnabled(metaConnection);
+                                    }
                                 } else if (isAutoUpgradeEnabled && !isDoNotUpgradePropSet) {
                                     // Upgrade is required and we are allowed to automatically upgrade
                                     upgradeSystemTables(url, props);