diff --git ql/src/java/org/apache/hadoop/hive/ql/Driver.java ql/src/java/org/apache/hadoop/hive/ql/Driver.java index fe780ce..b2bc71e 100644 --- ql/src/java/org/apache/hadoop/hive/ql/Driver.java +++ ql/src/java/org/apache/hadoop/hive/ql/Driver.java @@ -147,6 +147,8 @@ // A list of FileSinkOperators writing in an ACID compliant manner private Set acidSinks; + // whether any ACID table is involved in a query + private boolean acidInQuery; // A limit on the number of threads that can be launched private int maxthreads; @@ -462,6 +464,7 @@ public void run() { // validate the plan sem.validate(); + acidInQuery = sem.hasAcidInQuery(); perfLogger.PerfLogEnd(CLASS_NAME, PerfLogger.ANALYZE); // get the output schema @@ -1052,12 +1055,12 @@ private int acquireLocksAndOpenTxn(boolean startTxnImplicitly) { For multi-stmt txns this is not sufficient and will be managed via WriteSet tracking in the lock manager.*/ txnMgr.acquireLocks(plan, ctx, userFromUGI); - if(initiatingTransaction || readOnlyQueryInAutoCommit) { + if(initiatingTransaction || (readOnlyQueryInAutoCommit && acidInQuery)) { //For multi-stmt txns we should record the snapshot when txn starts but // don't update it after that until txn completes. Thus the check for {@code initiatingTransaction} //For autoCommit=true, Read-only statements, txn is implicit, i.e. lock in the snapshot //for each statement. - recordValidTxns();//todo: we should only need to do this for RO query if it has ACID resources in it. + recordValidTxns(); } return 0; diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java index fbe93f9..7730031 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java @@ -103,6 +103,9 @@ * back and set it once we actually start running the query. */ protected Set acidFileSinks = new HashSet(); + + // whether any ACID table is involved in a query + protected boolean acidInQuery; public static int HIVE_COLUMN_ORDER_ASC = 1; public static int HIVE_COLUMN_ORDER_DESC = 0; @@ -1079,6 +1082,10 @@ public QueryProperties getQueryProperties() { public Set getAcidFileSinks() { return acidFileSinks; } + + public boolean hasAcidInQuery() { + return acidInQuery; + } /** * Construct list bucketing context. diff --git ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java index a6c4bdc..36b0c2c 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -10631,6 +10631,7 @@ public void validate() throws SemanticException { tbl = p.getTable(); } if (tbl != null && AcidUtils.isAcidTable(tbl)) { + acidInQuery = true; checkAcidTxnManager(tbl); } } @@ -10707,6 +10708,7 @@ public void validate() throws SemanticException { } if (tbl != null && AcidUtils.isAcidTable(tbl)) { + acidInQuery = true; checkAcidTxnManager(tbl); } } diff --git ql/src/test/org/apache/hadoop/hive/ql/TestTxnCommands2.java ql/src/test/org/apache/hadoop/hive/ql/TestTxnCommands2.java index 1b28877..a16a788 100644 --- ql/src/test/org/apache/hadoop/hive/ql/TestTxnCommands2.java +++ ql/src/test/org/apache/hadoop/hive/ql/TestTxnCommands2.java @@ -23,6 +23,7 @@ import org.apache.hadoop.fs.FileUtil; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hive.common.FileUtils; +import org.apache.hadoop.hive.common.ValidTxnList; import org.apache.hadoop.hive.conf.HiveConf; import org.apache.hadoop.hive.metastore.HouseKeeperService; import org.apache.hadoop.hive.metastore.api.CompactionRequest; @@ -401,6 +402,19 @@ public void testNonAcidToAcidConversionAndMajorCompaction() throws Exception { } @Test + public void testValidTxnsBookkeeping() throws Exception { + // 1. Run a query against a non-ACID table, and we shouldn't have txn logged in conf + runStatementOnDriver("select * from " + Table.NONACIDORCTBL); + String value = hiveConf.get(ValidTxnList.VALID_TXNS_KEY); + Assert.assertNull("The entry should be null for query that doesn't involve ACID tables", value); + + // 2. Run a query against an ACID table, and we should have txn logged in conf + runStatementOnDriver("select * from " + Table.ACIDTBL); + value = hiveConf.get(ValidTxnList.VALID_TXNS_KEY); + Assert.assertNotNull("The entry shouldn't be null for query that involves ACID tables", value); + } + + @Test public void testUpdateMixedCase() throws Exception { int[][] tableData = {{1,2},{3,3},{5,3}}; runStatementOnDriver("insert into " + Table.ACIDTBL + "(a,b) " + makeValuesClause(tableData));