diff --git ql/src/java/org/apache/hadoop/hive/ql/Driver.java ql/src/java/org/apache/hadoop/hive/ql/Driver.java index 7147a9a..2163e9b 100644 --- ql/src/java/org/apache/hadoop/hive/ql/Driver.java +++ ql/src/java/org/apache/hadoop/hive/ql/Driver.java @@ -146,6 +146,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; @@ -486,6 +488,7 @@ public void run() { // validate the plan sem.validate(); + acidInQuery = sem.hasAcidInQuery(); perfLogger.PerfLogEnd(CLASS_NAME, PerfLogger.ANALYZE); // get the output schema @@ -1001,12 +1004,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 af1ee20..36c1259 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/BaseSemanticAnalyzer.java @@ -102,6 +102,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; @@ -1078,6 +1081,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 ba1945f..f8a5dcd 100644 --- ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java +++ ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java @@ -10595,6 +10595,7 @@ public void validate() throws SemanticException { tbl = p.getTable(); } if (tbl != null && AcidUtils.isAcidTable(tbl)) { + acidInQuery = true; checkAcidTxnManager(tbl); } } @@ -10657,6 +10658,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 5ed3c44..f4debfe 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));