This is an automated email from the ASF dual-hosted git repository.
prasanthj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new acec83f HIVE-21254: Pre-upgrade tool should handle exceptions and
skip db/tables (Prasanth Jayachandran reviewed by Jason Dere, Eugene Koifman,
Ashutosh Chauhan)
acec83f is described below
commit acec83f3b7718250e6317ec5890a5ad7a014f10e
Author: Prasanth Jayachandran <[email protected]>
AuthorDate: Tue Feb 19 23:06:21 2019 -0800
HIVE-21254: Pre-upgrade tool should handle exceptions and skip db/tables
(Prasanth Jayachandran reviewed by Jason Dere, Eugene Koifman, Ashutosh Chauhan)
---
.../hadoop/hive/upgrade/acid/PreUpgradeTool.java | 93 ++++++++---
.../hive/upgrade/acid/TestPreUpgradeTool.java | 172 ++++++++++++++++-----
2 files changed, 207 insertions(+), 58 deletions(-)
diff --git
a/upgrade-acid/pre-upgrade/src/main/java/org/apache/hadoop/hive/upgrade/acid/PreUpgradeTool.java
b/upgrade-acid/pre-upgrade/src/main/java/org/apache/hadoop/hive/upgrade/acid/PreUpgradeTool.java
index 04782a6..0e3e3e2 100644
---
a/upgrade-acid/pre-upgrade/src/main/java/org/apache/hadoop/hive/upgrade/acid/PreUpgradeTool.java
+++
b/upgrade-acid/pre-upgrade/src/main/java/org/apache/hadoop/hive/upgrade/acid/PreUpgradeTool.java
@@ -25,6 +25,7 @@ import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.hadoop.fs.ContentSummary;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
@@ -54,6 +55,7 @@ import org.apache.hadoop.hive.ql.io.orc.OrcFile;
import org.apache.hadoop.hive.ql.io.orc.Reader;
import org.apache.hadoop.hive.serde.serdeConstants;
import org.apache.hadoop.hive.shims.HadoopShims;
+import org.apache.hadoop.security.AccessControlException;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hive.common.util.HiveVersionInfo;
import org.apache.thrift.TException;
@@ -223,39 +225,74 @@ public class PreUpgradeTool {
boolean isAcidEnabled = isAcidEnabled(conf);
IMetaStoreClient hms = getHMS(conf);
LOG.debug("Looking for databases");
- List<String> databases = hms.getAllDatabases();//TException
- LOG.debug("Found " + databases.size() + " databases to process");
+ String exceptionMsg = null;
+ List<String> databases;
List<String> compactions = new ArrayList<>();
final CompactionMetaInfo compactionMetaInfo = new CompactionMetaInfo();
ValidTxnList txns = null;
Hive db = null;
- if(execute) {
- db = Hive.get(conf);
- }
+ try {
+ databases = hms.getAllDatabases();//TException
+ LOG.debug("Found " + databases.size() + " databases to process");
+ if (execute) {
+ db = Hive.get(conf);
+ }
- for(String dbName : databases) {
- List<String> tables = hms.getAllTables(dbName);
- LOG.debug("found " + tables.size() + " tables in " + dbName);
- for(String tableName : tables) {
- Table t = hms.getTable(dbName, tableName);
- LOG.debug("processing table " + Warehouse.getQualifiedName(t));
- if(isAcidEnabled) {
- //if acid is off, there can't be any acid tables - nothing to compact
- if(txns == null) {
+ for (String dbName : databases) {
+ try {
+ List<String> tables = hms.getAllTables(dbName);
+ LOG.debug("found " + tables.size() + " tables in " + dbName);
+ for (String tableName : tables) {
+ try {
+ Table t = hms.getTable(dbName, tableName);
+ LOG.debug("processing table " + Warehouse.getQualifiedName(t));
+ if (isAcidEnabled) {
+ //if acid is off, there can't be any acid tables - nothing to
compact
+ if (txns == null) {
/*
This API changed from 2.x to 3.0. so this won't even compile with
3.0
but it doesn't need to since we only run this preUpgrade
*/
- TxnStore txnHandler = TxnUtils.getTxnStore(conf);
- txns =
TxnUtils.createValidCompactTxnList(txnHandler.getOpenTxnsInfo());
+ TxnStore txnHandler = TxnUtils.getTxnStore(conf);
+ txns =
TxnUtils.createValidCompactTxnList(txnHandler.getOpenTxnsInfo());
+ }
+ List<String> compactionCommands =
+ getCompactionCommands(t, conf, hms, compactionMetaInfo,
execute, db, txns);
+ compactions.addAll(compactionCommands);
+ }
+ /*todo: handle renaming files somewhere*/
+ } catch (Exception e) {
+ if (isAccessControlException(e)) {
+ // this could be external table with 0 permission for hive user
+ exceptionMsg = "Unable to access " + dbName + "." + tableName
+ ". Pre-upgrade tool requires read-access " +
+ "to databases and tables to determine if a table has to be
compacted. " +
+ "Set " +
HiveConf.ConfVars.HIVE_METASTORE_AUTHORIZATION_AUTH_READS.varname + " config to
" +
+ "false to allow read-access to databases and tables and
retry the pre-upgrade tool again..";
+ }
+ throw e;
+ }
}
- List<String> compactionCommands =
- getCompactionCommands(t, conf, hms, compactionMetaInfo, execute,
db, txns);
- compactions.addAll(compactionCommands);
+ } catch (Exception e) {
+ if (exceptionMsg == null && isAccessControlException(e)) {
+ // we may not have access to read all tables from this db
+ exceptionMsg = "Unable to access " + dbName + ". Pre-upgrade tool
requires read-access " +
+ "to databases and tables to determine if a table has to be
compacted. " +
+ "Set " +
HiveConf.ConfVars.HIVE_METASTORE_AUTHORIZATION_AUTH_READS.varname + " config to
" +
+ "false to allow read-access to databases and tables and retry
the pre-upgrade tool again..";
+ }
+ throw e;
}
- /*todo: handle renaming files somewhere*/
}
+ } catch (Exception e) {
+ if (exceptionMsg == null && isAccessControlException(e)) {
+ exceptionMsg = "Unable to get databases. Pre-upgrade tool requires
read-access " +
+ "to databases and tables to determine if a table has to be
compacted. " +
+ "Set " +
HiveConf.ConfVars.HIVE_METASTORE_AUTHORIZATION_AUTH_READS.varname + " config to
" +
+ "false to allow read-access to databases and tables and retry the
pre-upgrade tool again..";
+ }
+ throw new HiveException(exceptionMsg, e);
}
+
makeCompactionScript(compactions, scriptLocation, compactionMetaInfo);
if(execute) {
@@ -306,6 +343,22 @@ public class PreUpgradeTool {
}
}
+ private boolean isAccessControlException(final Exception e) {
+ // hadoop security AccessControlException
+ if ((e instanceof MetaException && e.getCause() instanceof
AccessControlException) ||
+ ExceptionUtils.getRootCause(e) instanceof AccessControlException) {
+ return true;
+ }
+
+ // java security AccessControlException
+ if ((e instanceof MetaException && e.getCause() instanceof
java.security.AccessControlException) ||
+ ExceptionUtils.getRootCause(e) instanceof
java.security.AccessControlException) {
+ return true;
+ }
+
+ // metastore in some cases sets the AccessControlException as message
instead of wrapping the exception
+ return e instanceof MetaException &&
e.getMessage().startsWith("java.security.AccessControlException: Permission
denied");
+ }
/**
* Generates a set compaction commands to run on pre Hive 3 cluster
diff --git
a/upgrade-acid/pre-upgrade/src/test/java/org/apache/hadoop/hive/upgrade/acid/TestPreUpgradeTool.java
b/upgrade-acid/pre-upgrade/src/test/java/org/apache/hadoop/hive/upgrade/acid/TestPreUpgradeTool.java
index fe4b08b..90230d5d 100644
---
a/upgrade-acid/pre-upgrade/src/test/java/org/apache/hadoop/hive/upgrade/acid/TestPreUpgradeTool.java
+++
b/upgrade-acid/pre-upgrade/src/test/java/org/apache/hadoop/hive/upgrade/acid/TestPreUpgradeTool.java
@@ -34,6 +34,7 @@ import org.apache.hadoop.hive.ql.exec.mr.MapRedTask;
import org.apache.hadoop.hive.ql.io.AcidUtils;
import org.apache.hadoop.hive.ql.io.HiveInputFormat;
import org.apache.hadoop.hive.ql.metadata.Hive;
+import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.metadata.Table;
import org.apache.hadoop.hive.ql.processors.CommandProcessorResponse;
import org.apache.hadoop.hive.ql.session.SessionState;
@@ -46,8 +47,13 @@ import org.junit.Test;
import org.junit.rules.TestName;
import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
public class TestPreUpgradeTool {
@@ -72,41 +78,45 @@ public class TestPreUpgradeTool {
runStatementOnDriver("drop table if exists TFlat");
runStatementOnDriver("drop table if exists TFlatText");
- runStatementOnDriver("create table TAcid (a int, b int) clustered by (b)
into 2 buckets stored as orc TBLPROPERTIES ('transactional'='true')");
- runStatementOnDriver("create table TAcidPart (a int, b int) partitioned by
(p tinyint) clustered by (b) into 2 buckets stored" +
- " as orc TBLPROPERTIES ('transactional'='true')");
- //on 2.x these are guaranteed to not be acid
- runStatementOnDriver("create table TFlat (a int, b int) stored as orc
tblproperties('transactional'='false')");
- runStatementOnDriver("create table TFlatText (a int, b int) stored as
textfile tblproperties('transactional'='false')");
+ try {
+ runStatementOnDriver(
+ "create table TAcid (a int, b int) clustered by (b) into 2 buckets
stored as orc TBLPROPERTIES ('transactional'='true')");
+ runStatementOnDriver(
+ "create table TAcidPart (a int, b int) partitioned by (p tinyint)
clustered by (b) into 2 buckets stored" +
+ " as orc TBLPROPERTIES ('transactional'='true')");
+ //on 2.x these are guaranteed to not be acid
+ runStatementOnDriver("create table TFlat (a int, b int) stored as orc
tblproperties('transactional'='false')");
+ runStatementOnDriver(
+ "create table TFlatText (a int, b int) stored as textfile
tblproperties('transactional'='false')");
- //this needs major compaction
- runStatementOnDriver("insert into TAcid" + makeValuesClause(data));
- runStatementOnDriver("update TAcid set a = 1 where b = 2");
+ //this needs major compaction
+ runStatementOnDriver("insert into TAcid" + makeValuesClause(data));
+ runStatementOnDriver("update TAcid set a = 1 where b = 2");
- //this table needs to be converted to CRUD Acid
- runStatementOnDriver("insert into TFlat" + makeValuesClause(data));
+ //this table needs to be converted to CRUD Acid
+ runStatementOnDriver("insert into TFlat" + makeValuesClause(data));
- //this table needs to be converted to MM
- runStatementOnDriver("insert into TFlatText" + makeValuesClause(data));
+ //this table needs to be converted to MM
+ runStatementOnDriver("insert into TFlatText" + makeValuesClause(data));
- //p=10 needs major compaction
- runStatementOnDriver("insert into TAcidPart partition(p)" +
makeValuesClause(dataPart));
- runStatementOnDriver("update TAcidPart set a = 1 where b = 2 and p = 10");
+ //p=10 needs major compaction
+ runStatementOnDriver("insert into TAcidPart partition(p)" +
makeValuesClause(dataPart));
+ runStatementOnDriver("update TAcidPart set a = 1 where b = 2 and p =
10");
- //todo: add partitioned table that needs conversion to MM/Acid
+ //todo: add partitioned table that needs conversion to MM/Acid
- //todo: rename files case
- String[] args = {"-location", getTestDataDir(), "-execute"};
- PreUpgradeTool.callback = new PreUpgradeTool.Callback() {
- @Override
- void onWaitForCompaction() throws MetaException {
- runWorker(hiveConf);
- }
- };
- PreUpgradeTool.pollIntervalMs = 1;
- PreUpgradeTool.hiveConf = hiveConf;
- PreUpgradeTool.main(args);
+ //todo: rename files case
+ String[] args = {"-location", getTestDataDir(), "-execute"};
+ PreUpgradeTool.callback = new PreUpgradeTool.Callback() {
+ @Override
+ void onWaitForCompaction() throws MetaException {
+ runWorker(hiveConf);
+ }
+ };
+ PreUpgradeTool.pollIntervalMs = 1;
+ PreUpgradeTool.hiveConf = hiveConf;
+ PreUpgradeTool.main(args);
/*
todo: parse
target/tmp/org.apache.hadoop.hive.upgrade.acid.TestPreUpgradeTool-1527286256834/compacts_1527286277624.sql
@@ -115,19 +125,99 @@ public class TestPreUpgradeTool {
ALTER TABLE default.tacidpart PARTITION(p=10Y) COMPACT 'major';
* */
- TxnStore txnHandler = TxnUtils.getTxnStore(hiveConf);
+ TxnStore txnHandler = TxnUtils.getTxnStore(hiveConf);
+
+ ShowCompactResponse resp = txnHandler.showCompact(new
ShowCompactRequest());
+ Assert.assertEquals(2, resp.getCompactsSize());
+ for (ShowCompactResponseElement e : resp.getCompacts()) {
+ Assert.assertEquals(e.toString(), TxnStore.CLEANING_RESPONSE,
e.getState());
+ }
- ShowCompactResponse resp = txnHandler.showCompact(new
ShowCompactRequest());
- Assert.assertEquals(2, resp.getCompactsSize());
- for(ShowCompactResponseElement e : resp.getCompacts()) {
- Assert.assertEquals(e.toString(), TxnStore.CLEANING_RESPONSE,
e.getState());
+ String[] args2 = {"-location", getTestDataDir()};
+ PreUpgradeTool.main(args2);
+ /*
+ * todo: parse compacts script - make sure there is nothing in it
+ * */
+ } finally {
+ runStatementOnDriver("drop table if exists TAcid");
+ runStatementOnDriver("drop table if exists TAcidPart");
+ runStatementOnDriver("drop table if exists TFlat");
+ runStatementOnDriver("drop table if exists TFlatText");
}
+ }
- String[] args2 = {"-location", getTestDataDir()};
- PreUpgradeTool.main(args2);
- /*
- * todo: parse compacts script - make sure there is nothing in it
- * */
+ @Test
+ public void testUpgradeExternalTableNoReadPermissionForDatabase() throws
Exception {
+ int[][] data = {{1,2}, {3, 4}, {5, 6}};
+
+ runStatementOnDriver("drop database if exists test cascade");
+ runStatementOnDriver("drop table if exists TExternal");
+
+ runStatementOnDriver("create database test");
+ runStatementOnDriver("create table test.TExternal (a int, b int) stored as
orc tblproperties" +
+ "('transactional'='false')");
+
+ //this needs major compaction
+ runStatementOnDriver("insert into test.TExternal" +
makeValuesClause(data));
+
+ String dbDir = getWarehouseDir() + "/test.db";
+ File dbPath = new File(dbDir);
+ try {
+ Set<PosixFilePermission> perms =
PosixFilePermissions.fromString("-w-------");
+ Files.setPosixFilePermissions(dbPath.toPath(), perms);
+ String[] args = {"-location", getTestDataDir(), "-execute"};
+ PreUpgradeTool.pollIntervalMs = 1;
+ PreUpgradeTool.hiveConf = hiveConf;
+ Exception expected = null;
+ try {
+ PreUpgradeTool.main(args);
+ } catch (Exception e) {
+ expected = e;
+ }
+
+ Assert.assertNotNull(expected);
+ Assert.assertTrue(expected instanceof HiveException);
+ Assert.assertTrue(expected.getMessage().contains("Pre-upgrade tool
requires " +
+ "read-access to databases and tables to determine if a table has to be
compacted."));
+ } finally {
+ Set<PosixFilePermission> perms =
PosixFilePermissions.fromString("rwxrw----");
+ Files.setPosixFilePermissions(dbPath.toPath(), perms);
+ }
+ }
+
+ @Test
+ public void testUpgradeExternalTableNoReadPermissionForTable() throws
Exception {
+ int[][] data = {{1,2}, {3, 4}, {5, 6}};
+ runStatementOnDriver("drop table if exists TExternal");
+
+ runStatementOnDriver("create table TExternal (a int, b int) stored as orc
tblproperties('transactional'='false')");
+
+ //this needs major compaction
+ runStatementOnDriver("insert into TExternal" + makeValuesClause(data));
+
+ String tableDir = getWarehouseDir() + "/texternal";
+ File tablePath = new File(tableDir);
+ try {
+ Set<PosixFilePermission> perms =
PosixFilePermissions.fromString("-w-------");
+ Files.setPosixFilePermissions(tablePath.toPath(), perms);
+ String[] args = {"-location", getTestDataDir(), "-execute"};
+ PreUpgradeTool.pollIntervalMs = 1;
+ PreUpgradeTool.hiveConf = hiveConf;
+ Exception expected = null;
+ try {
+ PreUpgradeTool.main(args);
+ } catch (Exception e) {
+ expected = e;
+ }
+
+ Assert.assertNotNull(expected);
+ Assert.assertTrue(expected instanceof HiveException);
+ Assert.assertTrue(expected.getMessage().contains("Pre-upgrade tool
requires" +
+ " read-access to databases and tables to determine if a table has to
be compacted."));
+ } finally {
+ Set<PosixFilePermission> perms =
PosixFilePermissions.fromString("rwxrw----");
+ Files.setPosixFilePermissions(tablePath.toPath(), perms);
+ }
}
private static void runWorker(HiveConf hiveConf) throws MetaException {
@@ -203,6 +293,12 @@ ALTER TABLE default.tacidpart PARTITION(p=10Y) COMPACT
'major';
hiveConf
.setVar(HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER,
"org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory");
+ hiveConf
+ .setVar(HiveConf.ConfVars.METASTORE_PRE_EVENT_LISTENERS,
+
"org.apache.hadoop.hive.ql.security.authorization.AuthorizationPreEventListener");
+ hiveConf
+ .setVar(HiveConf.ConfVars.HIVE_METASTORE_AUTHORIZATION_MANAGER,
+
"org.apache.hadoop.hive.ql.security.authorization.StorageBasedAuthorizationProvider");
hiveConf.setBoolVar(HiveConf.ConfVars.MERGE_CARDINALITY_VIOLATION_CHECK,
true);
hiveConf.setBoolVar(HiveConf.ConfVars.HIVESTATSCOLAUTOGATHER, false);
TxnDbUtil.setConfValues(hiveConf);