This is an automated email from the ASF dual-hosted git repository. pvary 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 2d444fa HIVE-20801: ACID: Allow DbTxnManager to ignore non-ACID table read locking (Gopal Vijayaraghavan, reviewed by Eugene Koifman, Ashutosh Chauhan, Denys Kuzmenko) 2d444fa is described below commit 2d444fafa2c2cc0d0f5aa45378536398c64e1f7b Author: Peter Vary <pv...@cloudera.com> AuthorDate: Fri Jan 24 10:05:05 2020 +0100 HIVE-20801: ACID: Allow DbTxnManager to ignore non-ACID table read locking (Gopal Vijayaraghavan, reviewed by Eugene Koifman, Ashutosh Chauhan, Denys Kuzmenko) --- .../java/org/apache/hadoop/hive/conf/HiveConf.java | 11 +++-- .../org/apache/hadoop/hive/ql/io/AcidUtils.java | 51 ++++++++++++--------- .../hadoop/hive/ql/lockmgr/TestDbTxnManager2.java | 52 ++++++++++++++++++++++ 3 files changed, 89 insertions(+), 25 deletions(-) diff --git a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java index b79515f..d8aabd8 100644 --- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java +++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java @@ -2644,12 +2644,17 @@ public class HiveConf extends Configuration { "In nonstrict mode, for non-ACID resources, INSERT will only acquire shared lock, which\n" + "allows two concurrent writes to the same partition but still lets lock manager prevent\n" + "DROP TABLE etc. when the table is being written to"), + HIVE_TXN_NONACID_READ_LOCKS("hive.txn.nonacid.read.locks", true, + "Flag to turn off the read locks for non-ACID tables, when set to false.\n" + + "Could be exercised to improve the performance of non-ACID tables in clusters where read locking " + + "is enabled globally to support ACID. Can cause issues with concurrent DDL operations, or slow S3 writes."), HIVE_TXN_READ_LOCKS("hive.txn.read.locks", true, - "flag to turn off the strict read lock when set to false"), + "Flag to turn off the read locks, when set to false. Although its not recommended, \n" + + "but in performance critical scenarios this option may be exercised."), TXN_OVERWRITE_X_LOCK("hive.txn.xlock.iow", true, "Ensures commands with OVERWRITE (such as INSERT OVERWRITE) acquire Exclusive locks for\n" + - "transactional tables. This ensures that inserts (w/o overwrite) running concurrently\n" + - "are not hidden by the INSERT OVERWRITE."), + "transactional tables. This ensures that inserts (w/o overwrite) running concurrently\n" + + "are not hidden by the INSERT OVERWRITE."), HIVE_TXN_STATS_ENABLED("hive.txn.stats.enabled", true, "Whether Hive supports transactional stats (accurate stats for transactional tables)"), diff --git a/ql/src/java/org/apache/hadoop/hive/ql/io/AcidUtils.java b/ql/src/java/org/apache/hadoop/hive/ql/io/AcidUtils.java index ed68e0f..2f5ec52 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/io/AcidUtils.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/io/AcidUtils.java @@ -2845,8 +2845,10 @@ public class AcidUtils { public static List<LockComponent> makeLockComponents(Set<WriteEntity> outputs, Set<ReadEntity> inputs, HiveConf conf) { List<LockComponent> lockComponents = new ArrayList<>(); - // For each source to read, get a shared lock boolean skipReadLock = !conf.getBoolVar(ConfVars.HIVE_TXN_READ_LOCKS); + boolean skipNonAcidReadLock = !conf.getBoolVar(ConfVars.HIVE_TXN_NONACID_READ_LOCKS); + + // For each source to read, get a shared lock for (ReadEntity input : inputs) { if (input.isDummy() || !input.needsLock() @@ -2863,33 +2865,38 @@ public class AcidUtils { Table t = null; switch (input.getType()) { - case DATABASE: - compBuilder.setDbName(input.getDatabase().getName()); - break; - - case TABLE: - t = input.getTable(); - compBuilder.setDbName(t.getDbName()); - compBuilder.setTableName(t.getTableName()); - break; - - case PARTITION: - case DUMMYPARTITION: - compBuilder.setPartitionName(input.getPartition().getName()); - t = input.getPartition().getTable(); - compBuilder.setDbName(t.getDbName()); - compBuilder.setTableName(t.getTableName()); - break; - - default: - // This is a file or something we don't hold locks for. + case DATABASE: + compBuilder.setDbName(input.getDatabase().getName()); + break; + + case TABLE: + t = input.getTable(); + compBuilder.setDbName(t.getDbName()); + compBuilder.setTableName(t.getTableName()); + break; + + case PARTITION: + case DUMMYPARTITION: + compBuilder.setPartitionName(input.getPartition().getName()); + t = input.getPartition().getTable(); + compBuilder.setDbName(t.getDbName()); + compBuilder.setTableName(t.getTableName()); + break; + + default: + // This is a file or something we don't hold locks for. + continue; + } + if (skipNonAcidReadLock && !AcidUtils.isTransactionalTable(t)) { + // skip read-locks for non-transactional tables + // read-locks don't protect non-transactional tables data consistency continue; } if (t != null) { compBuilder.setIsTransactional(AcidUtils.isTransactionalTable(t)); } LockComponent comp = compBuilder.build(); - LOG.debug("Adding lock component to lock request " + comp.toString()); + LOG.debug("Adding lock component to lock request {} ", comp); lockComponents.add(comp); } // For each source to write to, get the appropriate lock type. If it's diff --git a/ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestDbTxnManager2.java b/ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestDbTxnManager2.java index 50859d1..48e9afc 100644 --- a/ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestDbTxnManager2.java +++ b/ql/src/test/org/apache/hadoop/hive/ql/lockmgr/TestDbTxnManager2.java @@ -711,6 +711,58 @@ public class TestDbTxnManager2 { conf.setBoolVar(HiveConf.ConfVars.HIVE_TXN_STRICT_LOCKING_MODE, true); } + /** + * Check to make sure we acquire proper locks for queries involving non-strict locking + */ + @Test + public void checkExpectedReadLocksForNonAcidTables() throws Exception { + dropTable(new String[] {"tab_acid", "tab_not_acid"}); + driver.run("create table if not exists tab_acid (a int, b int) partitioned by (p string) " + + "clustered by (a) into 2 buckets stored as orc TBLPROPERTIES ('transactional'='true')"); + driver.run("create table if not exists tab_not_acid (na int, nb int) partitioned by (np string) " + + "clustered by (na) into 2 buckets stored as orc TBLPROPERTIES ('transactional'='false')"); + driver.run("insert into tab_acid partition(p) (a,b,p) values(1,2,'foo'),(3,4,'bar')"); + driver.run("insert into tab_not_acid partition(np) (na,nb,np) values(1,2,'blah'),(3,4,'doh')"); + + // Test non-acid read-locking mode - the read locks are only obtained for the ACID side + conf.setBoolVar(HiveConf.ConfVars.HIVE_TXN_NONACID_READ_LOCKS, false); + + HiveTxnManager txnMgr1 = TxnManagerFactory.getTxnManagerFactory().getTxnManager(conf); + txnMgr1.openTxn(ctx, "T1"); + driver.compileAndRespond("select * from tab_acid inner join tab_not_acid on a = na", true); + txnMgr1.acquireLocks(driver.getPlan(), ctx, "T1"); + List<ShowLocksResponseElement> locks = getLocks(txnMgr1); + Assert.assertEquals("Unexpected lock count", 3, locks.size()); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", null, locks); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "p=bar", locks); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "p=foo", locks); + + HiveTxnManager txnMgr2 = TxnManagerFactory.getTxnManagerFactory().getTxnManager(conf); + txnMgr2.openTxn(ctx, "T2"); + driver.compileAndRespond("insert into tab_not_acid partition(np='doh') values(5,6)", true); + LockState ls = ((DbTxnManager)txnMgr2).acquireLocks(driver.getPlan(), ctx, "T2", false); + locks = getLocks(txnMgr2); + Assert.assertEquals("Unexpected lock count", 4, locks.size()); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", null, locks); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "p=bar", locks); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "p=foo", locks); + checkLock(LockType.EXCLUSIVE, LockState.ACQUIRED, "default", "tab_not_acid", "np=doh", locks); + + HiveTxnManager txnMgr3 = TxnManagerFactory.getTxnManagerFactory().getTxnManager(conf); + txnMgr3.openTxn(ctx, "T3"); + driver.compileAndRespond("insert into tab_not_acid partition(np='blah') values(7,8)", true); + ((DbTxnManager)txnMgr3).acquireLocks(driver.getPlan(), ctx, "T3", false); + locks = getLocks(txnMgr3); + Assert.assertEquals("Unexpected lock count", 5, locks.size()); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", null, locks); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "p=bar", locks); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "p=foo", locks); + checkLock(LockType.EXCLUSIVE, LockState.ACQUIRED, "default", "tab_not_acid", "np=blah", locks); + + conf.setBoolVar(HiveConf.ConfVars.HIVE_TXN_NONACID_READ_LOCKS, + HiveConf.ConfVars.HIVE_TXN_NONACID_READ_LOCKS.defaultBoolVal); + } + @Test public void testLockingOnInsertIntoNonNativeTables() throws Exception { dropTable(new String[] {"tab_not_acid"});