This is an automated email from the ASF dual-hosted git repository. caiconghui pushed a commit to branch writeLock in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
commit b499469d7af3dd95ec89a240b28974f2664916fd Author: caiconghui <[email protected]> AuthorDate: Tue Sep 14 15:29:53 2021 +0800 add ut --- .../java/org/apache/doris/catalog/Database.java | 4 ++ .../apache/doris/common/util/MetaLockUtils.java | 13 +++-- .../doris/transaction/GlobalTransactionMgr.java | 2 +- .../org/apache/doris/catalog/DatabaseTest.java | 21 +++++++- .../java/org/apache/doris/catalog/TableTest.java | 34 ++++++++++++- .../doris/common/util/MetaLockUtilsTest.java | 59 +++++++++++++++++++++- 6 files changed, 125 insertions(+), 8 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java index 6d97454..a370013 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java @@ -166,6 +166,10 @@ public class Database extends MetaObject implements Writable { } } + public boolean isWriteLockHeldByCurrentThread() { + return this.rwLock.writeLock().isHeldByCurrentThread(); + } + public boolean writeLockIfExist() { if (!isDropped) { this.rwLock.writeLock().lock(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/util/MetaLockUtils.java b/fe/fe-core/src/main/java/org/apache/doris/common/util/MetaLockUtils.java index de5a3c2..42346a9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/util/MetaLockUtils.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/util/MetaLockUtils.java @@ -74,13 +74,20 @@ public class MetaLockUtils { } } - public static boolean tryWriteLockTables(List<Table> tableList, long timeout, TimeUnit unit) throws MetaNotFoundException { + public static boolean tryWriteLockTablesOrMetaException(List<Table> tableList, long timeout, TimeUnit unit) throws MetaNotFoundException { for (int i = 0; i < tableList.size(); i++) { - if (!tableList.get(i).tryWriteLockOrMetaException(timeout, unit)) { + try { + if (!tableList.get(i).tryWriteLockOrMetaException(timeout, unit)) { + for (int j = i - 1; j >= 0; j--) { + tableList.get(j).writeUnlock(); + } + return false; + } + } catch (MetaNotFoundException e) { for (int j = i - 1; j >= 0; j--) { tableList.get(j).writeUnlock(); } - return false; + throw e; } } return true; diff --git a/fe/fe-core/src/main/java/org/apache/doris/transaction/GlobalTransactionMgr.java b/fe/fe-core/src/main/java/org/apache/doris/transaction/GlobalTransactionMgr.java index e3416d2..1953898 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/transaction/GlobalTransactionMgr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/transaction/GlobalTransactionMgr.java @@ -211,7 +211,7 @@ public class GlobalTransactionMgr implements Writable { throws UserException { StopWatch stopWatch = new StopWatch(); stopWatch.start(); - if (!MetaLockUtils.tryWriteLockTables(tableList, timeoutMillis, TimeUnit.MILLISECONDS)) { + if (!MetaLockUtils.tryWriteLockTablesOrMetaException(tableList, timeoutMillis, TimeUnit.MILLISECONDS)) { throw new UserException("get tableList write lock timeout, tableList=(" + StringUtils.join(tableList, ",") + ")"); } try { diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/DatabaseTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/DatabaseTest.java index 161d202..05a8fb6 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/catalog/DatabaseTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/DatabaseTest.java @@ -17,7 +17,9 @@ package org.apache.doris.catalog; +import org.apache.doris.alter.AlterCancelException; import org.apache.doris.catalog.MaterializedIndex.IndexState; +import org.apache.doris.common.DdlException; import org.apache.doris.common.ExceptionChecker; import org.apache.doris.common.FeConstants; import org.apache.doris.common.MetaNotFoundException; @@ -93,10 +95,27 @@ public class DatabaseTest { db.writeLock(); try { - Assert.assertTrue(db.tryWriteLock(0, TimeUnit.SECONDS)); + Assert.assertTrue(db.tryWriteLock(1000, TimeUnit.SECONDS)); + db.writeUnlock(); } finally { db.writeUnlock(); } + + db.markDropped(); + Assert.assertFalse(db.writeLockIfExist()); + Assert.assertFalse(db.isWriteLockHeldByCurrentThread()); + db.unmarkDropped(); + Assert.assertTrue(db.writeLockIfExist()); + Assert.assertTrue(db.isWriteLockHeldByCurrentThread()); + db.writeUnlock(); + } + + @Test + public void lockTestWithException() { + db.markDropped(); + ExceptionChecker.expectThrowsWithMsg(DdlException.class, + "errCode = 2, detailMessage = unknown db, dbName=dbTest", () -> db.writeLockOrDdlException()); + db.unmarkDropped(); } @Test diff --git a/fe/fe-core/src/test/java/org/apache/doris/catalog/TableTest.java b/fe/fe-core/src/test/java/org/apache/doris/catalog/TableTest.java index 7187384..6b0aa03 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/catalog/TableTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/TableTest.java @@ -17,7 +17,11 @@ package org.apache.doris.catalog; +import org.apache.doris.alter.AlterCancelException; +import org.apache.doris.common.DdlException; +import org.apache.doris.common.ExceptionChecker; import org.apache.doris.common.FeConstants; +import org.apache.doris.common.MetaNotFoundException; import org.apache.doris.common.jmockit.Deencapsulation; import org.apache.doris.thrift.TStorageType; @@ -51,6 +55,7 @@ public class TableTest { fakeCatalog = new FakeCatalog(); catalog = Deencapsulation.newInstance(Catalog.class); table = new Table(Table.TableType.OLAP); + table.setName("test"); FakeCatalog.setCatalog(catalog); FakeCatalog.setMetaVersion(FeConstants.meta_version); } @@ -64,14 +69,41 @@ public class TableTest { table.readUnlock(); } + Assert.assertFalse(table.isWriteLockHeldByCurrentThread()); table.writeLock(); try { - Assert.assertTrue(table.tryWriteLock(0, TimeUnit.SECONDS)); + Assert.assertTrue(table.tryWriteLock(1000, TimeUnit.SECONDS)); + Assert.assertTrue(table.isWriteLockHeldByCurrentThread()); + table.writeUnlock(); } finally { table.writeUnlock(); + Assert.assertFalse(table.isWriteLockHeldByCurrentThread()); } + + Assert.assertFalse(table.isWriteLockHeldByCurrentThread()); + table.markDropped(); + Assert.assertFalse(table.writeLockIfExist()); + Assert.assertFalse(table.isWriteLockHeldByCurrentThread()); + table.unmarkDropped(); + Assert.assertTrue(table.writeLockIfExist()); + Assert.assertTrue(table.writeLockIfExist()); + Assert.assertTrue(table.isWriteLockHeldByCurrentThread()); + table.writeUnlock(); } + @Test + public void lockTestWithException() { + table.markDropped(); + ExceptionChecker.expectThrowsWithMsg(DdlException.class, + "errCode = 2, detailMessage = unknown table, tableName=test", () -> table.writeLockOrDdlException()); + ExceptionChecker.expectThrowsWithMsg(MetaNotFoundException.class, + "errCode = 7, detailMessage = unknown table, tableName=test", () -> table.writeLockOrMetaException()); + ExceptionChecker.expectThrowsWithMsg(AlterCancelException.class, + "errCode = 2, detailMessage = unknown table, tableName=test", () -> table.writeLockOrAlterCancelException()); + ExceptionChecker.expectThrowsWithMsg(MetaNotFoundException.class, + "errCode = 7, detailMessage = unknown table, tableName=test", () -> table.tryWriteLockOrMetaException(1000, TimeUnit.MILLISECONDS)); + table.unmarkDropped(); + } @Test public void testSerialization() throws Exception { diff --git a/fe/fe-core/src/test/java/org/apache/doris/common/util/MetaLockUtilsTest.java b/fe/fe-core/src/test/java/org/apache/doris/common/util/MetaLockUtilsTest.java index 7ce2d0a..7abe526 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/common/util/MetaLockUtilsTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/common/util/MetaLockUtilsTest.java @@ -22,13 +22,18 @@ import org.apache.doris.catalog.Database; import org.apache.doris.catalog.Table; import org.apache.doris.common.MetaNotFoundException; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import java.util.List; import java.util.concurrent.TimeUnit; public class MetaLockUtilsTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Test public void testReadLockDatabases() { List<Database> databaseList = Lists.newArrayList(new Database(), new Database()); @@ -64,14 +69,64 @@ public class MetaLockUtilsTest { MetaLockUtils.writeUnlockTables(tableList); Assert.assertFalse(tableList.get(0).isWriteLockHeldByCurrentThread()); Assert.assertFalse(tableList.get(1).isWriteLockHeldByCurrentThread()); - Assert.assertTrue(MetaLockUtils.tryWriteLockTables(tableList, 1, TimeUnit.MILLISECONDS)); + Assert.assertTrue(MetaLockUtils.tryWriteLockTablesOrMetaException(tableList, 1, TimeUnit.MILLISECONDS)); Assert.assertTrue(tableList.get(0).isWriteLockHeldByCurrentThread()); Assert.assertTrue(tableList.get(1).isWriteLockHeldByCurrentThread()); MetaLockUtils.writeUnlockTables(tableList); tableList.get(1).readLock(); - Assert.assertFalse(MetaLockUtils.tryWriteLockTables(tableList, 1, TimeUnit.MILLISECONDS)); + Assert.assertFalse(MetaLockUtils.tryWriteLockTablesOrMetaException(tableList, 1, TimeUnit.MILLISECONDS)); Assert.assertFalse(tableList.get(0).isWriteLockHeldByCurrentThread()); Assert.assertFalse(tableList.get(1).isWriteLockHeldByCurrentThread()); tableList.get(1).readUnlock(); } + + @Test + public void testWriteLockTablesWithMetaNotFoundException() throws MetaNotFoundException { + List<Table> tableList = Lists.newArrayList(); + Table table1 = new Table(Table.TableType.OLAP); + Table table2 = new Table(Table.TableType.OLAP); + table2.setName("test2"); + tableList.add(table1); + tableList.add(table2); + MetaLockUtils.writeLockTablesOrMetaException(tableList); + Assert.assertTrue(table1.isWriteLockHeldByCurrentThread()); + Assert.assertTrue(table2.isWriteLockHeldByCurrentThread()); + MetaLockUtils.writeUnlockTables(tableList); + Assert.assertFalse(table1.isWriteLockHeldByCurrentThread()); + Assert.assertFalse(table2.isWriteLockHeldByCurrentThread()); + table2.markDropped(); + expectedException.expect(MetaNotFoundException.class); + expectedException.expectMessage("errCode = 7, detailMessage = unknown table, tableName=test2"); + try { + MetaLockUtils.writeLockTablesOrMetaException(tableList); + } finally { + Assert.assertFalse(table1.isWriteLockHeldByCurrentThread()); + Assert.assertFalse(table2.isWriteLockHeldByCurrentThread()); + } + } + + @Test + public void testTryWriteLockTablesWithMetaNotFoundException() throws MetaNotFoundException { + List<Table> tableList = Lists.newArrayList(); + Table table1 = new Table(Table.TableType.OLAP); + Table table2 = new Table(Table.TableType.OLAP); + table2.setName("test2"); + tableList.add(table1); + tableList.add(table2); + MetaLockUtils.tryWriteLockTablesOrMetaException(tableList, 1000, TimeUnit.MILLISECONDS); + Assert.assertTrue(table1.isWriteLockHeldByCurrentThread()); + Assert.assertTrue(table2.isWriteLockHeldByCurrentThread()); + MetaLockUtils.writeUnlockTables(tableList); + Assert.assertFalse(table1.isWriteLockHeldByCurrentThread()); + Assert.assertFalse(table2.isWriteLockHeldByCurrentThread()); + table2.markDropped(); + expectedException.expect(MetaNotFoundException.class); + expectedException.expectMessage("errCode = 7, detailMessage = unknown table, tableName=test2"); + try { + MetaLockUtils.tryWriteLockTablesOrMetaException(tableList, 1000, TimeUnit.MILLISECONDS); + } finally { + Assert.assertFalse(table1.isWriteLockHeldByCurrentThread()); + Assert.assertFalse(table2.isWriteLockHeldByCurrentThread()); + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
