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 abd12c9a82..3b8600f4c6 100644 --- a/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java +++ b/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java @@ -2766,6 +2766,8 @@ private static void populateLlapDaemonVarsSet(Set llapDaemonVarsSetLocal HIVE_TXN_READ_LOCKS("hive.txn.read.locks", true, "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."), + HIVE_LOCKS_PARTITION_THRESHOLD("hive.locks.max.partitions", -1, + "Locks the entire table if number of partition locks exceeds user-defined threshold. Disabled by default."), 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" + 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 5f6f401e31..93059069f5 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 @@ -79,6 +79,7 @@ import org.apache.hadoop.hive.ql.lockmgr.HiveTxnManager; import org.apache.hadoop.hive.ql.lockmgr.LockException; import org.apache.hadoop.hive.ql.metadata.HiveStorageHandler; +import org.apache.hadoop.hive.ql.metadata.Partition; import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.ql.parse.ASTNode; import org.apache.hadoop.hive.ql.parse.HiveParser; @@ -100,6 +101,7 @@ import javax.annotation.concurrent.Immutable; import java.nio.charset.Charset; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -2888,17 +2890,20 @@ private static boolean isLockableTable(Table t) { boolean sharedWrite = !conf.getBoolVar(HiveConf.ConfVars.TXN_WRITE_X_LOCK); boolean isMerge = operation == Context.Operation.MERGE; + // We don't want to acquire read locks during update or delete as we'll be acquiring write + // locks instead. Also, there's no need to lock temp tables since they're session wide + List readEntities = inputs.stream() + .filter(input -> !input.isDummy() + && input.needsLock() + && !input.isUpdateOrDelete() + && AcidUtils.needsLock(input) + && !skipReadLock) + .collect(Collectors.toList()); + + Set fullTableLock = getFullTableLock(readEntities, conf); + // For each source to read, get a shared_read lock - for (ReadEntity input : inputs) { - if (input.isDummy() - || !input.needsLock() - || input.isUpdateOrDelete() - || !AcidUtils.needsLock(input) - || skipReadLock) { - // We don't want to acquire read locks during update or delete as we'll be acquiring write - // locks instead. Also, there's no need to lock temp tables since they're session wide - continue; - } + for (ReadEntity input : readEntities) { LockComponentBuilder compBuilder = new LockComponentBuilder(); compBuilder.setSharedRead(); compBuilder.setOperationType(DataOperationType.SELECT); @@ -2911,6 +2916,9 @@ private static boolean isLockableTable(Table t) { case TABLE: t = input.getTable(); + if (!fullTableLock.contains(t)) { + continue; + } compBuilder.setDbName(t.getDbName()); compBuilder.setTableName(t.getTableName()); break; @@ -2919,6 +2927,9 @@ private static boolean isLockableTable(Table t) { case DUMMYPARTITION: compBuilder.setPartitionName(input.getPartition().getName()); t = input.getPartition().getTable(); + if (fullTableLock.contains(t)) { + continue; + } compBuilder.setDbName(t.getDbName()); compBuilder.setTableName(t.getTableName()); break; @@ -3034,12 +3045,13 @@ Seems much cleaner if each stmt is identified as a particular HiveOperation (whi break; case DDL_SHARED: compBuilder.setSharedRead(); - if (!output.isTxnAnalyze()) { + if (output.isTxnAnalyze()) { // Analyze needs txn components to be present, otherwise an aborted analyze write ID // might be rolled under the watermark by compactor while stats written by it are // still present. - compBuilder.setOperationType(DataOperationType.NO_TXN); + continue; } + compBuilder.setOperationType(DataOperationType.NO_TXN); break; case UPDATE: @@ -3072,6 +3084,22 @@ Seems much cleaner if each stmt is identified as a particular HiveOperation (whi return lockComponents; } + private static Set
getFullTableLock(List readEntities, HiveConf conf) { + int partLocksThreshold = conf.getIntVar(HiveConf.ConfVars.HIVE_LOCKS_PARTITION_THRESHOLD); + + Map partLocksPerTable = readEntities.stream() + .filter(input -> input.getType() == Entity.Type.PARTITION) + .map(Entity::getPartition) + .collect(Collectors.groupingBy(Partition::getTable, Collectors.counting())); + + return readEntities.stream() + .filter(input -> input.getType() == Entity.Type.TABLE) + .map(Entity::getTable) + .filter(t -> !partLocksPerTable.containsKey(t) + || (partLocksThreshold > 0 && partLocksThreshold <= partLocksPerTable.get(t))) + .collect(Collectors.toSet()); + } + /** * Safety check to make sure a file take from one acid table is not added into another acid table * since the ROW__IDs embedded as part a write to one table won't make sense in different 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 8a15b7cc5d..30685078eb 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 @@ -735,11 +735,9 @@ public void testCheckExpectedLocks2() throws Exception { driver.compileAndRespond("select * from tab_acid inner join tab_not_acid on a = na", true); txnMgr.acquireLocks(driver.getPlan(), ctx, "T1"); List locks = getLocks(txnMgr); - Assert.assertEquals("Unexpected lock count", 6, locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", null, locks); + Assert.assertEquals("Unexpected lock count", 4, locks.size()); 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.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", null, locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", "np=blah", locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", "np=doh", locks); @@ -748,11 +746,9 @@ public void testCheckExpectedLocks2() throws Exception { driver.compileAndRespond("insert into tab_not_acid partition(np='doh') values(5,6)", true); ((DbTxnManager)txnMgr2).acquireLocks(driver.getPlan(), ctx, "T2", false); locks = getLocks(txnMgr2); - Assert.assertEquals("Unexpected lock count", 7, locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", null, locks); + Assert.assertEquals("Unexpected lock count", 5, locks.size()); 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.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", null, locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", "np=blah", locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", "np=doh", locks); checkLock(LockType.EXCLUSIVE, LockState.WAITING, "default", "tab_not_acid", "np=doh", locks); @@ -765,11 +761,9 @@ public void testCheckExpectedLocks2() throws Exception { 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", 8, locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", null, locks); + Assert.assertEquals("Unexpected lock count", 6, locks.size()); 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.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", null, locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", "np=blah", locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", "np=doh", locks); checkLock(LockType.EXCLUSIVE, LockState.WAITING, "default", "tab_not_acid", "np=doh", locks); @@ -798,8 +792,7 @@ public void testCheckExpectedReadLocksForNonAcidTables() throws Exception { driver.compileAndRespond("select * from tab_acid inner join tab_not_acid on a = na", true); txnMgr1.acquireLocks(driver.getPlan(), ctx, "T1"); List locks = getLocks(txnMgr1); - Assert.assertEquals("Unexpected lock count", 3, locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", null, locks); + Assert.assertEquals("Unexpected lock count", 2, locks.size()); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "p=bar", locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "p=foo", locks); @@ -808,8 +801,7 @@ public void testCheckExpectedReadLocksForNonAcidTables() throws Exception { driver.compileAndRespond("insert into tab_not_acid partition(np='doh') values(5,6)", true); ((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); + Assert.assertEquals("Unexpected lock count", 3, locks.size()); 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); @@ -819,8 +811,7 @@ public void testCheckExpectedReadLocksForNonAcidTables() throws Exception { 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); + Assert.assertEquals("Unexpected lock count", 4, locks.size()); 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); @@ -1111,7 +1102,7 @@ public void testWriteSetTracking4() throws Exception { "clustered by (a) into 2 buckets stored as orc TBLPROPERTIES ('transactional'='true')"); txnMgr.openTxn(ctx, "Long Running"); - driver.compileAndRespond("select a from TAB_PART where p = 'blah'", true); + driver.compileAndRespond("select a from TAB_PART where p = 'blah'", true); txnMgr.acquireLocks(driver.getPlan(), ctx, "Long Running"); List locks = getLocks(txnMgr); Assert.assertEquals("Unexpected lock count", 1, locks.size()); @@ -1189,9 +1180,9 @@ public void testWriteSetTracking4() throws Exception { locks = getLocks(txnMgr); Assert.assertEquals("Unexpected lock count", 0, locks.size()); - /** - * The last transaction will always remain in the transaction table, so we will open an other one, - * wait for the timeout period to exceed, then start the initiator that will clean + /* + The last transaction will always remain in the transaction table, so we will open an other one, + wait for the timeout period to exceed, then start the initiator that will clean */ txnMgr.openTxn(ctx, "Long Running"); Thread.sleep(txnHandler.getOpenTxnTimeOutMillis()); @@ -1377,7 +1368,6 @@ public void testWriteSetTracking7() throws Exception { txnHandler.addDynamicPartitions(adp); txnMgr2.commitTxn(); //txnid:idTxnUpdate3 - ((DbLockManager)txnMgr.getLockManager()).checkLock(locks.get(2).getLockid()); //retest WAITING locks (both have same ext id) locks = getLocks(txnMgr); Assert.assertEquals("Unexpected lock count", 2, locks.size()); checkLock(LockType.SHARED_WRITE, LockState.ACQUIRED, "default", "TAB1", "p=two", locks); @@ -1441,7 +1431,6 @@ public void testWriteSetTracking8() throws Exception { txnHandler.addDynamicPartitions(adp); txnMgr2.commitTxn(); //txnid:idTxnUpdate1 - ((DbLockManager)txnMgr.getLockManager()).checkLock(locks.get(2).getLockid()); //retest WAITING locks (both have same ext id) locks = getLocks(txnMgr); Assert.assertEquals("Unexpected lock count", 1, locks.size()); checkLock(LockType.SHARED_WRITE, LockState.ACQUIRED, "default", "TAB1", "p=two", locks); @@ -1505,7 +1494,6 @@ public void testWriteSetTracking9() throws Exception { txnHandler.addDynamicPartitions(adp); txnMgr2.commitTxn(); //txnid:idTxnUpdate1 - ((DbLockManager)txnMgr.getLockManager()).checkLock(locks.get(2).getLockid()); //retest WAITING locks (both have same ext id) locks = getLocks(txnMgr); Assert.assertEquals("Unexpected lock count", 1, locks.size()); checkLock(LockType.SHARED_WRITE, LockState.ACQUIRED, "default", "TAB1", "p=two", locks); @@ -1582,7 +1570,6 @@ public void testWriteSetTracking10() throws Exception { txnHandler.addDynamicPartitions(adp); txnMgr2.commitTxn(); //"Update tab2" - ((DbLockManager)txnMgr.getLockManager()).checkLock(locks.get(2).getLockid()); //retest WAITING locks (both have same ext id) locks = getLocks(txnMgr); Assert.assertEquals("Unexpected lock count", 1, locks.size()); checkLock(LockType.SHARED_WRITE, LockState.ACQUIRED, "default", "TAB1", "p=two", locks); @@ -1642,8 +1629,7 @@ public void testWriteSetTracking11() throws Exception { driver.compileAndRespond("delete from tab1 where p='two' and b=2", true); ((DbTxnManager)txnMgr).acquireLocks(driver.getPlan(), ctx, "T3", false); locks = getLocks(txnMgr); - Assert.assertEquals("Unexpected lock count", 5, locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "TAB1", null, locks); + Assert.assertEquals("Unexpected lock count", 4, locks.size()); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "TAB1", "p=one", locks); checkLock(LockType.SHARED_WRITE, LockState.ACQUIRED, "default", "TAB1", "p=two", locks); checkLock(LockType.SHARED_WRITE, LockState.ACQUIRED, "default", "TAB1", "p=one", locks); @@ -1657,10 +1643,8 @@ public void testWriteSetTracking11() throws Exception { txnHandler.addDynamicPartitions(adp); txnMgr2.commitTxn(); //"delete from tab1" txn - ((DbLockManager)txnMgr.getLockManager()).checkLock(locks.get(4).getLockid()); //retest WAITING locks (both have same ext id) locks = getLocks(txnMgr); - Assert.assertEquals("Unexpected lock count", 3, locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "TAB1", null, locks); + Assert.assertEquals("Unexpected lock count", 2, locks.size()); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "TAB1", "p=one", locks); checkLock(LockType.SHARED_WRITE, LockState.ACQUIRED, "default", "TAB1", "p=two", locks); //completion of txnid:txnIdSelect @@ -2666,8 +2650,7 @@ private void testFairness2(boolean zeroWaitRead) throws Exception { //tries to get X lock on T7.p=1 and gets Waiting state ((DbTxnManager) txnMgr2).acquireLocks(driver.getPlan(), ctx, "Fiddler", false); List locks = getLocks(); - Assert.assertEquals("Unexpected lock count", 4, locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", null, locks); + Assert.assertEquals("Unexpected lock count", 3, locks.size()); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", "p=1", locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", "p=2", locks); long extLockId = checkLock(LockType.EXCLUSIVE, LockState.WAITING, "default", "T7", "p=1", locks).getLockid(); @@ -2689,25 +2672,22 @@ private void testFairness2(boolean zeroWaitRead) throws Exception { ex.getMessage()); } locks = getLocks(); - Assert.assertEquals("Unexpected lock count", (zeroWaitRead ? 4 : 7), locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", null, locks); + Assert.assertEquals("Unexpected lock count", (zeroWaitRead ? 3 : 5), locks.size()); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", "p=1", locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", "p=2", locks); if (!zeroWaitRead) { - checkLock(LockType.SHARED_READ, LockState.WAITING, "default", "T7", null, locks); checkLock(LockType.SHARED_READ, LockState.WAITING, "default", "T7", "p=1", locks); checkLock(LockType.SHARED_READ, LockState.WAITING, "default", "T7", "p=2", locks); } checkLock(LockType.EXCLUSIVE, LockState.WAITING, "default", "T7", "p=1", locks); - txnMgr.commitTxn(); //release locks from "select a from T7" - to unblock hte drop partition - //retest the the "drop partiton" X lock - ((DbLockManager)txnMgr2.getLockManager()).checkLock(locks.get(zeroWaitRead ? 3 : 6).getLockid()); + txnMgr.commitTxn(); //release locks from "select a from T7" - to unblock the drop partition + //re-test the "drop partiton" X lock + ((DbLockManager)txnMgr2.getLockManager()).checkLock(locks.get(zeroWaitRead ? 2 : 4).getLockid()); locks = getLocks(); - Assert.assertEquals("Unexpected lock count", (zeroWaitRead ? 1 : 4), locks.size()); + Assert.assertEquals("Unexpected lock count", (zeroWaitRead ? 1 : 3), locks.size()); checkLock(LockType.EXCLUSIVE, LockState.ACQUIRED, "default", "T7", "p=1", locks); if (!zeroWaitRead) { - checkLock(LockType.SHARED_READ, LockState.WAITING, "default", "T7", null, locks); checkLock(LockType.SHARED_READ, LockState.WAITING, "default", "T7", "p=1", locks); checkLock(LockType.SHARED_READ, LockState.WAITING, "default", "T7", "p=2", locks); @@ -2715,8 +2695,7 @@ private void testFairness2(boolean zeroWaitRead) throws Exception { //re-test the locks ((DbLockManager) txnMgr2.getLockManager()).checkLock(locks.get(1).getLockid()); //S lock on T7 locks = getLocks(); - Assert.assertEquals("Unexpected lock count", 3, locks.size()); - checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", null, locks); + Assert.assertEquals("Unexpected lock count", 2, locks.size()); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", "p=1", locks); checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "T7", "p=2", locks); } @@ -2877,4 +2856,56 @@ public void testTruncate() throws Exception { Assert.assertEquals("Unexpected lock count", 1, locks.size()); checkLock(LockType.EXCLUSIVE, LockState.ACQUIRED, "default", "T", null, locks); } + + @Test + public void testAnalyze() throws Exception { + dropTable(new String[] {"tab_acid", "tab_not_acid"}); + + driver.run("create table tab_not_acid (key string, value string) partitioned by (ds string, hr string) " + + "stored as textfile"); + driver.run("insert into tab_not_acid partition (ds='2008-04-08', hr='11') values ('238', 'val_238')"); + driver.run("analyze table tab_not_acid PARTITION (ds, hr) compute statistics"); + + driver.run("create table tab_acid (key string, value string) partitioned by (ds string, hr string) " + + "stored as orc TBLPROPERTIES ('transactional'='true')"); + driver.run("insert into tab_acid PARTITION (ds, hr) select * from tab_not_acid"); + driver.run("analyze table tab_acid PARTITION (ds, hr) compute statistics"); + + driver.compileAndRespond("analyze table tab_not_acid PARTITION(ds, hr) compute statistics", true); + txnMgr.acquireLocks(driver.getPlan(), ctx, "dummy"); + + List locks = getLocks(); + Assert.assertEquals("Unexpected lock count", 1, locks.size()); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", "ds=2008-04-08/hr=11", locks); + txnMgr.commitTxn(); + + driver.compileAndRespond("analyze table tab_acid PARTITION(ds, hr) compute statistics"); + txnMgr.acquireLocks(driver.getPlan(), ctx, "dummy"); + + locks = getLocks(); + Assert.assertEquals("Unexpected lock count", 1, locks.size()); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", "ds=2008-04-08/hr=11", locks); + } + + @Test + public void testFullTableReadLock() throws Exception { + dropTable(new String[] {"tab_acid", "tab_not_acid"}); + conf.setIntVar(HiveConf.ConfVars.HIVE_LOCKS_PARTITION_THRESHOLD, 2); + + driver.run("create table if not exists tab_acid (a int, b int) partitioned by (p string) " + + "stored as orc TBLPROPERTIES ('transactional'='true')"); + driver.run("create table if not exists tab_not_acid (na int, nb int) partitioned by (np string) " + + "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')"); + + driver.compileAndRespond("select * from tab_acid inner join tab_not_acid on a = na", true); + txnMgr.acquireLocks(driver.getPlan(), ctx, "T1"); + List locks = getLocks(txnMgr); + Assert.assertEquals("Unexpected lock count", 2, locks.size()); + + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_acid", null, locks); + checkLock(LockType.SHARED_READ, LockState.ACQUIRED, "default", "tab_not_acid", null, locks); + } + }