This is an automated email from the ASF dual-hosted git repository.

morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-doris.git


The following commit(s) were added to refs/heads/master by this push:
     new ecbd4bc  [fix](catalog) Fix bug that The MetaObject lock design of fe 
would cause some problems with consistent meta when catalog do replay operation 
(#6650)
ecbd4bc is described below

commit ecbd4bcae06c3c154139dce52995caab8c3a2ac7
Author: caiconghui <55968745+caicong...@users.noreply.github.com>
AuthorDate: Tue Feb 8 10:01:52 2022 +0800

    [fix](catalog) Fix bug that The MetaObject lock design of fe would cause 
some problems with consistent meta when catalog do replay operation (#6650)
    
    1. If the table or db has been dropped,we will get write lock failed or 
just skip or throw exception,
    2. and if we recover table or db, we must ensure that unmark dropped state 
after writing recover journal.
    3. db.dropTable corresponds to db.createTable, I don't move 
table.markDropped method to the db.dropTable,
        for that all meta added to db or catalog must after writing recover 
journal, so we must invoke markDropped
        and unmarkDropped method outside the dropTable and createTable method.
---
 .../main/java/org/apache/doris/alter/Alter.java    | 123 ++++++++------
 .../java/org/apache/doris/alter/AlterHandler.java  |   2 +-
 .../java/org/apache/doris/alter/AlterJobV2.java    |   2 +-
 .../doris/alter/MaterializedViewHandler.java       |  10 +-
 .../java/org/apache/doris/alter/RollupJob.java     |   5 +-
 .../java/org/apache/doris/alter/RollupJobV2.java   |   4 +-
 .../apache/doris/alter/SchemaChangeHandler.java    |   8 +-
 .../org/apache/doris/alter/SchemaChangeJob.java    |  15 +-
 .../org/apache/doris/alter/SchemaChangeJobV2.java  |   4 +-
 .../java/org/apache/doris/backup/RestoreJob.java   |  51 ++++--
 .../java/org/apache/doris/catalog/Catalog.java     | 176 +++++++++++++--------
 .../apache/doris/catalog/CatalogRecycleBin.java    |  36 +++--
 .../java/org/apache/doris/catalog/Database.java    |  64 +++++---
 .../main/java/org/apache/doris/catalog/Table.java  |  67 ++++++++
 .../org/apache/doris/catalog/TabletStatMgr.java    |   5 +-
 .../doris/clone/DynamicPartitionScheduler.java     |   4 +-
 .../org/apache/doris/clone/TabletSchedCtx.java     |  10 +-
 .../org/apache/doris/clone/TabletScheduler.java    |   9 +-
 .../apache/doris/common/util/MetaLockUtils.java    |  27 +++-
 .../doris/consistency/CheckConsistencyJob.java     |   8 +-
 .../org/apache/doris/http/rest/RowCountAction.java |   2 +-
 .../doris/http/rest/TableRowCountAction.java       |   4 +-
 .../doris/httpv2/rest/TableRowCountAction.java     |   2 +-
 .../apache/doris/journal/bdbje/BDBJEJournal.java   |   1 -
 .../java/org/apache/doris/load/LoadChecker.java    |   7 +-
 .../apache/doris/load/loadv2/BrokerLoadJob.java    |   2 +-
 .../org/apache/doris/load/loadv2/SparkLoadJob.java |   2 +-
 .../java/org/apache/doris/master/MasterImpl.java   |   6 +-
 .../org/apache/doris/master/ReportHandler.java     |  11 +-
 .../doris/transaction/DatabaseTransactionMgr.java  |  19 +--
 .../doris/transaction/GlobalTransactionMgr.java    |   2 +-
 .../org/apache/doris/catalog/DatabaseTest.java     |  21 ++-
 .../org/apache/doris/catalog/InfoSchemaDbTest.java |   3 +-
 .../java/org/apache/doris/catalog/TableTest.java   |  34 +++-
 .../doris/common/util/MetaLockUtilsTest.java       |  62 +++++++-
 35 files changed, 550 insertions(+), 258 deletions(-)

diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
index 85eaaaf..2667a0c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
@@ -57,6 +57,7 @@ import org.apache.doris.common.DdlException;
 import org.apache.doris.common.MetaNotFoundException;
 import org.apache.doris.common.UserException;
 import org.apache.doris.common.util.DynamicPartitionUtil;
+import org.apache.doris.common.util.MetaLockUtils;
 import org.apache.doris.common.util.PropertyAnalyzer;
 import org.apache.doris.persist.AlterViewInfo;
 import org.apache.doris.persist.BatchModifyPartitionsInfo;
@@ -77,6 +78,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 import java.util.Arrays;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
@@ -158,7 +160,7 @@ public class Alter {
         } else if (currentAlterOps.hasPartitionOp()) {
             Preconditions.checkState(alterClauses.size() == 1);
             AlterClause alterClause = alterClauses.get(0);
-            olapTable.writeLock();
+            olapTable.writeLockOrDdlException();
             try {
                 if (alterClause instanceof DropPartitionClause) {
                     if (!((DropPartitionClause) 
alterClause).isTempPartition()) {
@@ -217,7 +219,7 @@ public class Alter {
 
     private void processModifyTableComment(Database db, OlapTable tbl, 
AlterClause alterClause)
             throws DdlException {
-        tbl.writeLock();
+        tbl.writeLockOrDdlException();
         try {
             ModifyTableCommentClause clause = (ModifyTableCommentClause) 
alterClause;
             tbl.setComment(clause.getComment());
@@ -231,7 +233,7 @@ public class Alter {
 
     private void processModifyColumnComment(Database db, OlapTable tbl, 
List<AlterClause> alterClauses)
             throws DdlException {
-        tbl.writeLock();
+        tbl.writeLockOrDdlException();
         try {
             // check first
             Map<String, String> colToComment = Maps.newHashMap();
@@ -304,14 +306,15 @@ public class Alter {
     }
 
     public void processModifyEngine(Database db, Table externalTable, 
ModifyEngineClause clause) throws DdlException {
-        if (externalTable.getType() != TableType.MYSQL) {
-            throw new DdlException("Only support modify table engine from 
MySQL to ODBC");
+        externalTable.writeLockOrDdlException();
+        try {
+            if (externalTable.getType() != TableType.MYSQL) {
+                throw new DdlException("Only support modify table engine from 
MySQL to ODBC");
+            }
+            processModifyEngineInternal(db, externalTable, 
clause.getProperties(), false);
+        } finally {
+            externalTable.writeUnlock();
         }
-
-        processModifyEngineInternal(db, externalTable, clause.getProperties());
-        ModifyTableEngineOperationLog log = new 
ModifyTableEngineOperationLog(db.getId(),
-                externalTable.getId(), clause.getProperties());
-        Catalog.getCurrentCatalog().getEditLog().logModifyTableEngine(log);
         LOG.info("modify table {}'s engine from MySQL to ODBC", 
externalTable.getName());
     }
 
@@ -324,10 +327,15 @@ public class Alter {
         if (mysqlTable == null) {
             return;
         }
-        processModifyEngineInternal(db, mysqlTable, log.getProperties());
+        mysqlTable.writeLock();
+        try {
+            processModifyEngineInternal(db, mysqlTable, log.getProperties(), 
true);
+        } finally {
+            mysqlTable.writeUnlock();
+        }
     }
 
-    private void processModifyEngineInternal(Database db, Table externalTable, 
Map<String, String> prop) {
+    private void processModifyEngineInternal(Database db, Table externalTable, 
Map<String, String> prop, boolean isReplay) {
         MysqlTable mysqlTable = (MysqlTable) externalTable;
         Map<String, String> newProp = Maps.newHashMap(prop);
         newProp.put(OdbcTable.ODBC_HOST, mysqlTable.getHost());
@@ -346,8 +354,18 @@ public class Alter {
             LOG.warn("Should not happen", e);
             return;
         }
-        db.dropTable(mysqlTable.getName());
-        db.createTable(odbcTable);
+        odbcTable.writeLock();
+        try {
+            db.dropTable(mysqlTable.getName());
+            db.createTable(odbcTable);
+            if (!isReplay) {
+                ModifyTableEngineOperationLog log = new 
ModifyTableEngineOperationLog(db.getId(),
+                        externalTable.getId(), prop);
+                
Catalog.getCurrentCatalog().getEditLog().logModifyTableEngine(log);
+            }
+        } finally {
+            odbcTable.writeUnlock();
+        }
     }
 
     public void processAlterTable(AlterTableStmt stmt) throws UserException {
@@ -393,7 +411,7 @@ public class Alter {
                 ((SchemaChangeHandler) 
schemaChangeHandler).updatePartitionsInMemoryMeta(
                         db, tableName, partitionNames, properties);
                 OlapTable olapTable = (OlapTable) table;
-                olapTable.writeLock();
+                olapTable.writeLockOrDdlException();
                 try {
                     modifyPartitionsProperty(db, olapTable, partitionNames, 
properties);
                 } finally {
@@ -415,27 +433,31 @@ public class Alter {
         ReplaceTableClause clause = (ReplaceTableClause) alterClauses.get(0);
         String newTblName = clause.getTblName();
         boolean swapTable = clause.isSwapTable();
-        Table newTbl = db.getTableOrMetaException(newTblName, TableType.OLAP);
-        OlapTable olapNewTbl = (OlapTable) newTbl;
-        db.writeLock();
-        origTable.writeLock();
+        db.writeLockOrDdlException();
         try {
-            String oldTblName = origTable.getName();
-            // First, we need to check whether the table to be operated on can 
be renamed
-            olapNewTbl.checkAndSetName(oldTblName, true);
-            if (swapTable) {
-                origTable.checkAndSetName(newTblName, true);
+            Table newTbl = db.getTableOrMetaException(newTblName, 
TableType.OLAP);
+            OlapTable olapNewTbl = (OlapTable) newTbl;
+            List<Table> tableList = Lists.newArrayList(origTable, newTbl);
+            tableList.sort((Comparator.comparing(Table::getId)));
+            MetaLockUtils.writeLockTablesOrMetaException(tableList);
+            try {
+                String oldTblName = origTable.getName();
+                // First, we need to check whether the table to be operated on 
can be renamed
+                olapNewTbl.checkAndSetName(oldTblName, true);
+                if (swapTable) {
+                    origTable.checkAndSetName(newTblName, true);
+                }
+                replaceTableInternal(db, origTable, olapNewTbl, swapTable, 
false);
+                // write edit log
+                ReplaceTableOperationLog log = new 
ReplaceTableOperationLog(db.getId(), origTable.getId(), olapNewTbl.getId(), 
swapTable);
+                Catalog.getCurrentCatalog().getEditLog().logReplaceTable(log);
+                LOG.info("finish replacing table {} with table {}, is swap: 
{}", oldTblName, newTblName, swapTable);
+            } finally {
+                MetaLockUtils.writeUnlockTables(tableList);
             }
-            replaceTableInternal(db, origTable, olapNewTbl, swapTable, false);
-            // write edit log
-            ReplaceTableOperationLog log = new 
ReplaceTableOperationLog(db.getId(), origTable.getId(), olapNewTbl.getId(), 
swapTable);
-            Catalog.getCurrentCatalog().getEditLog().logReplaceTable(log);
-            LOG.info("finish replacing table {} with table {}, is swap: {}", 
oldTblName, newTblName, swapTable);
         } finally {
-            origTable.writeUnlock();
             db.writeUnlock();
         }
-
     }
 
     public void replayReplaceTable(ReplaceTableOperationLog log) throws 
MetaNotFoundException {
@@ -446,11 +468,15 @@ public class Alter {
         Database db = Catalog.getCurrentCatalog().getDbOrMetaException(dbId);
         OlapTable origTable = db.getTableOrMetaException(origTblId, 
TableType.OLAP);
         OlapTable newTbl = db.getTableOrMetaException(newTblId, 
TableType.OLAP);
-
+        List<Table> tableList = Lists.newArrayList(origTable, newTbl);
+        tableList.sort((Comparator.comparing(Table::getId)));
+        MetaLockUtils.writeLockTablesOrMetaException(tableList);
         try {
             replaceTableInternal(db, origTable, newTbl, log.isSwapTable(), 
true);
         } catch (DdlException e) {
             LOG.warn("should not happen", e);
+        } finally {
+            MetaLockUtils.writeUnlockTables(tableList);
         }
         LOG.info("finish replay replacing table {} with table {}, is swap: 
{}", origTblId, newTblId, log.isSwapTable());
     }
@@ -505,25 +531,28 @@ public class Alter {
     }
 
     private void modifyViewDef(Database db, View view, String inlineViewDef, 
long sqlMode, List<Column> newFullSchema) throws DdlException {
-        db.writeLock();
-        view.writeLock();
+        db.writeLockOrDdlException();
         try {
-            view.setInlineViewDefWithSqlMode(inlineViewDef, sqlMode);
+            view.writeLockOrDdlException();
             try {
-                view.init();
-            } catch (UserException e) {
-                throw new DdlException("failed to init view stmt", e);
+                view.setInlineViewDefWithSqlMode(inlineViewDef, sqlMode);
+                try {
+                    view.init();
+                } catch (UserException e) {
+                    throw new DdlException("failed to init view stmt", e);
+                }
+                view.setNewFullSchema(newFullSchema);
+                String viewName = view.getName();
+                db.dropTable(viewName);
+                db.createTable(view);
+
+                AlterViewInfo alterViewInfo = new AlterViewInfo(db.getId(), 
view.getId(), inlineViewDef, newFullSchema, sqlMode);
+                
Catalog.getCurrentCatalog().getEditLog().logModifyViewDef(alterViewInfo);
+                LOG.info("modify view[{}] definition to {}", viewName, 
inlineViewDef);
+            } finally {
+                view.writeUnlock();
             }
-            view.setNewFullSchema(newFullSchema);
-            String viewName = view.getName();
-            db.dropTable(viewName);
-            db.createTable(view);
-
-            AlterViewInfo alterViewInfo = new AlterViewInfo(db.getId(), 
view.getId(), inlineViewDef, newFullSchema, sqlMode);
-            
Catalog.getCurrentCatalog().getEditLog().logModifyViewDef(alterViewInfo);
-            LOG.info("modify view[{}] definition to {}", viewName, 
inlineViewDef);
         } finally {
-            view.writeUnlock();
             db.writeUnlock();
         }
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/AlterHandler.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/AlterHandler.java
index 2f825b2..9aefdbb 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/AlterHandler.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/AlterHandler.java
@@ -420,7 +420,7 @@ public abstract class AlterHandler extends MasterDaemon {
         Database db = 
Catalog.getCurrentCatalog().getDbOrMetaException(task.getDbId());
 
         OlapTable tbl = db.getTableOrMetaException(task.getTableId(), 
Table.TableType.OLAP);
-        tbl.writeLock();
+        tbl.writeLockOrMetaException();
         try {
             Partition partition = tbl.getPartition(task.getPartitionId());
             if (partition == null) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/AlterJobV2.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/AlterJobV2.java
index 6a31be1..c8c8815 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/AlterJobV2.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/AlterJobV2.java
@@ -194,7 +194,7 @@ public abstract class AlterJobV2 implements Writable {
             throw new AlterCancelException(e.getMessage());
         }
 
-        tbl.writeLock();
+        tbl.writeLockOrAlterCancelException();
         try {
             boolean isStable = tbl.isStable(Catalog.getCurrentSystemInfo(),
                     Catalog.getCurrentCatalog().getTabletScheduler(), 
db.getClusterName());
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java
index e46378b..af07dbb 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java
@@ -174,7 +174,7 @@ public class MaterializedViewHandler extends AlterHandler {
      */
     public void processCreateMaterializedView(CreateMaterializedViewStmt 
addMVClause, Database db, OlapTable olapTable)
             throws DdlException, AnalysisException {
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             olapTable.checkStableAndNormal(db.getClusterName());
             if (olapTable.existTempPartitions()) {
@@ -229,7 +229,7 @@ public class MaterializedViewHandler extends AlterHandler {
         Map<String, RollupJobV2> rollupNameJobMap = new LinkedHashMap<>();
         // save job id for log
         Set<Long> logJobIdSet = new HashSet<>();
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             if (olapTable.existTempPartitions()) {
                 throw new DdlException("Can not alter table when there are 
temp partitions in table");
@@ -711,7 +711,7 @@ public class MaterializedViewHandler extends AlterHandler {
 
     public void processBatchDropRollup(List<AlterClause> dropRollupClauses, 
Database db, OlapTable olapTable)
             throws DdlException, MetaNotFoundException {
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             if (olapTable.existTempPartitions()) {
                 throw new DdlException("Can not alter table when there are 
temp partitions in table");
@@ -747,7 +747,7 @@ public class MaterializedViewHandler extends AlterHandler {
 
     public void processDropMaterializedView(DropMaterializedViewStmt 
dropMaterializedViewStmt, Database db,
                                             OlapTable olapTable) throws 
DdlException, MetaNotFoundException {
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             // check table state
             if (olapTable.getState() != OlapTableState.NORMAL) {
@@ -884,7 +884,7 @@ public class MaterializedViewHandler extends AlterHandler {
         try {
             Database db = 
Catalog.getCurrentCatalog().getDbOrMetaException(dbId);
             OlapTable olapTable = db.getTableOrMetaException(tableId, 
Table.TableType.OLAP);
-            olapTable.writeLock();
+            olapTable.writeLockOrMetaException();
             try {
                 if (olapTable.getState() == olapTableState) {
                     return;
diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJob.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJob.java
index 9b83815..1ab6cd2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJob.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJob.java
@@ -643,7 +643,10 @@ public class RollupJob extends AlterJob {
             return -1;
         }
 
-        olapTable.writeLock();
+        if (!olapTable.writeLockIfExist()) {
+            LOG.warn("unknown table, tableName=" + olapTable.getName());
+            return -1;
+        }
         try {
             // if all previous transaction has finished, then check base and 
rollup replica num
             synchronized (this) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
index e344c8f..81a9f7e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/RollupJobV2.java
@@ -281,7 +281,7 @@ public class RollupJobV2 extends AlterJobV2 implements 
GsonPostProcessable {
 
         // create all rollup replicas success.
         // add rollup index to catalog
-        tbl.writeLock();
+        tbl.writeLockOrAlterCancelException();
         try {
             Preconditions.checkState(tbl.getState() == OlapTableState.ROLLUP);
             addRollupIndexToCatalog(tbl);
@@ -427,7 +427,7 @@ public class RollupJobV2 extends AlterJobV2 implements 
GsonPostProcessable {
          * all tasks are finished. check the integrity.
          * we just check whether all rollup replicas are healthy.
          */
-        tbl.writeLock();
+        tbl.writeLockOrAlterCancelException();
         try {
             Preconditions.checkState(tbl.getState() == OlapTableState.ROLLUP);
             for (Map.Entry<Long, MaterializedIndex> entry : 
this.partitionIdToRollupIndex.entrySet()) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
index 4abdf90..db90d30 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeHandler.java
@@ -1621,7 +1621,7 @@ public class SchemaChangeHandler extends AlterHandler {
     @Override
     public void process(List<AlterClause> alterClauses, String clusterName, 
Database db, OlapTable olapTable)
             throws UserException {
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             // index id -> index schema
             Map<Long, LinkedList<Column>> indexSchemaMap = new HashMap<>();
@@ -1723,7 +1723,7 @@ public class SchemaChangeHandler extends AlterHandler {
     @Override
     public void processExternalTable(List<AlterClause> alterClauses, Database 
db, Table externalTable)
             throws UserException {
-        externalTable.writeLock();
+        externalTable.writeLockOrDdlException();
         try {
             // copy the external table schema columns
             List<Column> newSchema = Lists.newArrayList();
@@ -1804,7 +1804,7 @@ public class SchemaChangeHandler extends AlterHandler {
             updatePartitionInMemoryMeta(db, olapTable.getName(), 
partition.getName(), isInMemory);
         }
 
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             Catalog.getCurrentCatalog().modifyTableInMemoryMeta(db, olapTable, 
properties);
         } finally {
@@ -1932,7 +1932,7 @@ public class SchemaChangeHandler extends AlterHandler {
         AlterJobV2 schemaChangeJobV2 = null;
 
         OlapTable olapTable = db.getOlapTableOrDdlException(tableName);
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             if (olapTable.getState() != OlapTableState.SCHEMA_CHANGE &&
                     olapTable.getState() != OlapTableState.WAITING_STABLE) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJob.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJob.java
index f781d65..f2df913 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJob.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJob.java
@@ -584,15 +584,9 @@ public class SchemaChangeJob extends AlterJob {
         long replicaId = schemaChangeTask.getReplicaId();
 
         // update replica's info
-        OlapTable olapTable;
-        try {
-            Database db = 
Catalog.getCurrentCatalog().getDbOrMetaException(dbId);
-            olapTable = db.getTableOrMetaException(tableId, 
Table.TableType.OLAP);
-        } catch (MetaNotFoundException e) {
-            LOG.warn(e.getMessage());
-            return;
-        }
-        olapTable.writeLock();
+        Database db = Catalog.getCurrentCatalog().getDbOrMetaException(dbId);
+        OlapTable olapTable = db.getTableOrMetaException(tableId, 
Table.TableType.OLAP);
+        olapTable.writeLockOrMetaException();
         try {
             Preconditions.checkState(olapTable.getState() == 
OlapTableState.SCHEMA_CHANGE);
 
@@ -668,12 +662,11 @@ public class SchemaChangeJob extends AlterJob {
         OlapTable olapTable;
         try {
             olapTable = db.getTableOrMetaException(tableId, 
Table.TableType.OLAP);
+            olapTable.writeLockOrMetaException();
         } catch (MetaNotFoundException e) {
             LOG.warn(e.getMessage());
             return -1;
         }
-
-        olapTable.writeLock();
         try {
             synchronized (this) {
                 boolean hasUnfinishedPartition = false;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java 
b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
index 1ad1493..2d77da2 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/alter/SchemaChangeJobV2.java
@@ -307,7 +307,7 @@ public class SchemaChangeJobV2 extends AlterJobV2 {
 
         // create all replicas success.
         // add all shadow indexes to catalog
-        tbl.writeLock();
+        tbl.writeLockOrAlterCancelException();
         try {
             Preconditions.checkState(tbl.getState() == 
OlapTableState.SCHEMA_CHANGE);
             addShadowIndexToCatalog(tbl);
@@ -465,7 +465,7 @@ public class SchemaChangeJobV2 extends AlterJobV2 {
          * all tasks are finished. check the integrity.
          * we just check whether all new replicas are healthy.
          */
-        tbl.writeLock();
+        tbl.writeLockOrAlterCancelException();
         try {
             Preconditions.checkState(tbl.getState() == 
OlapTableState.SCHEMA_CHANGE);
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/backup/RestoreJob.java 
b/fe/fe-core/src/main/java/org/apache/doris/backup/RestoreJob.java
index 8e92395..151ab13 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/backup/RestoreJob.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/backup/RestoreJob.java
@@ -445,7 +445,9 @@ public class RestoreJob extends AbstractJob {
             }
 
             OlapTable olapTbl = (OlapTable) tbl;
-            olapTbl.writeLock();
+            if (!olapTbl.writeLockIfExist()) {
+                continue;
+            }
             try {
                 if (olapTbl.getState() != OlapTableState.NORMAL) {
                     status = new Status(ErrCode.COMMON_ERROR,
@@ -783,7 +785,12 @@ public class RestoreJob extends AbstractJob {
 
             // add restored tables
             for (Table tbl : restoredTbls) {
-                db.writeLock();
+                if (!db.writeLockIfExist()) {
+                    status = new Status(ErrCode.COMMON_ERROR, "Database " + 
db.getFullName()
+                            + " has been dropped");
+                    return;
+                }
+                tbl.writeLock();
                 try {
                     if (!db.createTable(tbl)) {
                         status = new Status(ErrCode.COMMON_ERROR, "Table " + 
tbl.getName()
@@ -791,6 +798,7 @@ public class RestoreJob extends AbstractJob {
                         return;
                     }
                 } finally {
+                    tbl.writeUnlock();
                     db.writeUnlock();
                 }
             }
@@ -1109,9 +1117,11 @@ public class RestoreJob extends AbstractJob {
         // restored tables
         for (Table restoreTbl : restoredTbls) {
             db.writeLock();
+            restoreTbl.writeLock();
             try {
                 db.createTable(restoreTbl);
             } finally {
+                restoreTbl.writeUnlock();
                 db.writeUnlock();
             }
             if (restoreTbl.getType() != TableType.OLAP) {
@@ -1387,7 +1397,9 @@ public class RestoreJob extends AbstractJob {
                 continue;
             }
             OlapTable olapTbl = (OlapTable) tbl;
-            tbl.writeLock();
+            if (!tbl.writeLockIfExist()) {
+                continue;
+            }
             try {
                 Map<Long, Pair<Long, Long>> map = 
restoredVersionInfo.rowMap().get(tblId);
                 for (Map.Entry<Long, Pair<Long, Long>> entry : map.entrySet()) 
{
@@ -1550,22 +1562,29 @@ public class RestoreJob extends AbstractJob {
             // remove restored tbls
             for (Table restoreTbl : restoredTbls) {
                 LOG.info("remove restored table when cancelled: {}", 
restoreTbl.getName());
-                if (restoreTbl.getType() == TableType.OLAP) {
-                    OlapTable restoreOlapTable = (OlapTable) restoreTbl;
-                    restoreOlapTable.writeLock();
+                if (db.writeLockIfExist()) {
                     try {
-                        for (Partition part : 
restoreOlapTable.getPartitions()) {
-                            for (MaterializedIndex idx : 
part.getMaterializedIndices(IndexExtState.VISIBLE)) {
-                                for (Tablet tablet : idx.getTablets()) {
-                                    
Catalog.getCurrentInvertedIndex().deleteTablet(tablet.getId());
+                        if (restoreTbl.getType() == TableType.OLAP) {
+                            OlapTable restoreOlapTable = (OlapTable) 
restoreTbl;
+                            restoreOlapTable.writeLock();
+                            try {
+                                for (Partition part : 
restoreOlapTable.getPartitions()) {
+                                    for (MaterializedIndex idx : 
part.getMaterializedIndices(IndexExtState.VISIBLE)) {
+                                        for (Tablet tablet : idx.getTablets()) 
{
+                                            
Catalog.getCurrentInvertedIndex().deleteTablet(tablet.getId());
+                                        }
+                                    }
                                 }
+                                db.dropTable(restoreTbl.getName());
+                            } finally {
+                                restoreTbl.writeUnlock();
                             }
                         }
                     } finally {
-                        restoreTbl.writeUnlock();
+                        db.writeUnlock();
                     }
                 }
-                db.dropTableWithLock(restoreTbl.getName());
+
             }
 
             // remove restored partitions
@@ -1574,9 +1593,11 @@ public class RestoreJob extends AbstractJob {
                 if (restoreTbl == null) {
                     continue;
                 }
+                if (!restoreTbl.writeLockIfExist()) {
+                    continue;
+                }
                 LOG.info("remove restored partition in table {} when 
cancelled: {}",
                         restoreTbl.getName(), entry.second.getName());
-                restoreTbl.writeLock();
                 try {
                     restoreTbl.dropPartition(dbId, entry.second.getName(), 
true /* force drop */);
                 } finally {
@@ -1625,7 +1646,9 @@ public class RestoreJob extends AbstractJob {
             }
 
             OlapTable olapTbl = (OlapTable) tbl;
-            tbl.writeLock();
+            if (!tbl.writeLockIfExist()) {
+                continue;
+            }
             try {
                 if (olapTbl.getState() == OlapTableState.RESTORE
                         || olapTbl.getState() == 
OlapTableState.RESTORE_WITH_LOAD) {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
index e29a341..304c04b 100755
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
@@ -2760,7 +2760,26 @@ public class Catalog {
 
                 // save table names for recycling
                 Set<String> tableNames = db.getTableNamesWithLock();
-                unprotectDropDb(db, stmt.isForceDrop(), false);
+                List<Table> tableList = db.getTablesOnIdOrder();
+                MetaLockUtils.writeLockTables(tableList);
+                try {
+                    if (!stmt.isForceDrop()) {
+                        for (Table table : tableList) {
+                            if (table.getType() == TableType.OLAP) {
+                                OlapTable olapTable = (OlapTable) table;
+                                if (olapTable.getState() != 
OlapTableState.NORMAL) {
+                                    throw new DdlException("The table [" + 
olapTable.getState() + "]'s state is " + olapTable.getState() + ", cannot be 
dropped." +
+                                            " please cancel the operation on 
olap table firstly. If you want to forcibly drop(cannot be recovered)," +
+                                            " please use \"DROP table 
FORCE\".");
+                                }
+                            }
+                        }
+                    }
+                    unprotectDropDb(db, stmt.isForceDrop(), false);
+                } finally {
+                    MetaLockUtils.writeUnlockTables(tableList);
+                }
+
                 if (!stmt.isForceDrop()) {
                     Catalog.getCurrentRecycleBin().recycleDatabase(db, 
tableNames);
                 } else {
@@ -2790,13 +2809,9 @@ public class Catalog {
             icebergTableCreationRecordMgr.deregisterDb(db);
         }
         for (Table table : db.getTables()) {
-            table.writeLock();
-            try {
-                unprotectDropTable(db, table, isForeDrop, isReplay);
-            } finally {
-                table.writeUnlock();
-            }
+            unprotectDropTable(db, table, isForeDrop, isReplay);
         }
+        db.markDropped();
     }
 
     public void replayDropLinkDb(DropLinkDbAndUpdateDbInfo info) {
@@ -2822,7 +2837,13 @@ public class Catalog {
             db.writeLock();
             try {
                 Set<String> tableNames = db.getTableNamesWithLock();
-                unprotectDropDb(db, isForceDrop, true);
+                List<Table> tableList = db.getTablesOnIdOrder();
+                MetaLockUtils.writeLockTables(tableList);
+                try {
+                    unprotectDropDb(db, isForceDrop, true);
+                } finally {
+                    MetaLockUtils.writeUnlockTables(tableList);
+                }
                 if (!isForceDrop) {
                     Catalog.getCurrentRecycleBin().recycleDatabase(db, 
tableNames);
                 } else {
@@ -2853,6 +2874,9 @@ public class Catalog {
         if (!tryLock(false)) {
             throw new DdlException("Failed to acquire catalog lock. Try 
again");
         }
+        db.writeLock();
+        List<Table> tableList = db.getTablesOnIdOrder();
+        MetaLockUtils.writeLockTables(tableList);
         try {
             if (fullNameToDb.containsKey(db.getFullName())) {
                 throw new DdlException("Database[" + db.getFullName() + "] 
already exist.");
@@ -2868,7 +2892,10 @@ public class Catalog {
             // log
             RecoverInfo recoverInfo = new RecoverInfo(db.getId(), -1L, -1L);
             editLog.logRecoverDb(recoverInfo);
+            db.unmarkDropped();
         } finally {
+            MetaLockUtils.writeUnlockTables(tableList);
+            db.writeUnlock();
             unlock();
         }
 
@@ -2880,7 +2907,7 @@ public class Catalog {
         String tableName = recoverStmt.getTableName();
 
         Database db = this.getDbOrDdlException(dbName);
-        db.writeLock();
+        db.writeLockOrDdlException();
         try {
             if (db.getTable(tableName).isPresent()) {
                 
ErrorReport.reportDdlException(ErrorCode.ERR_TABLE_EXISTS_ERROR, tableName);
@@ -2899,7 +2926,7 @@ public class Catalog {
 
         Database db = this.getDbOrDdlException(dbName);
         OlapTable olapTable = db.getOlapTableOrDdlException(tableName);
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             String partitionName = recoverStmt.getPartitionName();
             if (olapTable.getPartition(partitionName) != null) {
@@ -2929,24 +2956,33 @@ public class Catalog {
     public void alterDatabaseQuota(AlterDatabaseQuotaStmt stmt) throws 
DdlException {
         String dbName = stmt.getDbName();
         Database db = this.getDbOrDdlException(dbName);
-
         QuotaType quotaType = stmt.getQuotaType();
-        if (quotaType == QuotaType.DATA) {
-            db.setDataQuotaWithLock(stmt.getQuota());
-        } else if (quotaType == QuotaType.REPLICA) {
-            db.setReplicaQuotaWithLock(stmt.getQuota());
+        db.writeLockOrDdlException();
+        try {
+            if (quotaType == QuotaType.DATA) {
+                db.setDataQuota(stmt.getQuota());
+            } else if (quotaType == QuotaType.REPLICA) {
+                db.setReplicaQuota(stmt.getQuota());
+            }
+            long quota = stmt.getQuota();
+            DatabaseInfo dbInfo = new DatabaseInfo(dbName, "", quota, 
quotaType);
+            editLog.logAlterDb(dbInfo);
+        } finally {
+            db.writeUnlock();
         }
-        long quota = stmt.getQuota();
-        DatabaseInfo dbInfo = new DatabaseInfo(dbName, "", quota, quotaType);
-        editLog.logAlterDb(dbInfo);
     }
 
     public void replayAlterDatabaseQuota(String dbName, long quota, QuotaType 
quotaType) throws MetaNotFoundException {
         Database db = this.getDbOrMetaException(dbName);
-        if (quotaType == QuotaType.DATA) {
-            db.setDataQuotaWithLock(quota);
-        } else if (quotaType == QuotaType.REPLICA) {
-            db.setReplicaQuotaWithLock(quota);
+        db.writeLock();
+        try {
+            if (quotaType == QuotaType.DATA) {
+                db.setDataQuota(quota);
+            } else if (quotaType == QuotaType.REPLICA) {
+                db.setReplicaQuota(quota);
+            }
+        } finally {
+            db.writeUnlock();
         }
     }
 
@@ -3314,8 +3350,7 @@ public class Catalog {
 
             // check again
             table = db.getOlapTableOrDdlException(tableName);
-
-            table.writeLock();
+            table.writeLockOrDdlException();
             try {
                 olapTable = (OlapTable) table;
                 if (olapTable.getState() != OlapTableState.NORMAL) {
@@ -4467,10 +4502,13 @@ public class Catalog {
         }
     }
 
-    public void replayCreateTable(String dbName, Table table) {
+    public void replayCreateTable(String dbName, Table table) throws 
MetaNotFoundException {
         Database db = this.fullNameToDb.get(dbName);
-        db.createTableWithLock(table, true, false);
-
+        try {
+            db.createTableWithLock(table, true, false);
+        } catch (DdlException e) {
+            throw new MetaNotFoundException(e.getMessage());
+        }
         if (!isCheckpointThread()) {
             // add to inverted index
             if (table.getType() == TableType.OLAP) {
@@ -4597,7 +4635,7 @@ public class Catalog {
 
         // check database
         Database db = this.getDbOrDdlException(dbName);
-        db.writeLock();
+        db.writeLockOrDdlException();
         try {
             Table table = db.getTableNullable(tableName);
             if (table == null) {
@@ -5004,7 +5042,7 @@ public class Catalog {
                 OlapTable olapTable = (OlapTable) table;
                 // use try lock to avoid blocking a long time.
                 // if block too long, backend report rpc will timeout.
-                if (!olapTable.tryWriteLock(Table.TRY_LOCK_TIMEOUT_MS, 
TimeUnit.MILLISECONDS)) {
+                if (!olapTable.tryWriteLockIfExist(Table.TRY_LOCK_TIMEOUT_MS, 
TimeUnit.MILLISECONDS)) {
                     LOG.warn("try get table {} writelock but failed when 
checking backend storage medium", table.getName());
                     continue;
                 }
@@ -5356,42 +5394,45 @@ public class Catalog {
 
     // entry of rename table operation
     public void renameTable(Database db, Table table, TableRenameClause 
tableRenameClause) throws DdlException {
-        db.writeLock();
-        table.writeLock();
+        db.writeLockOrDdlException();
         try {
-            if (table instanceof OlapTable) {
-                OlapTable olapTable = (OlapTable) table;
-                if (olapTable.getState() != OlapTableState.NORMAL) {
-                    throw new DdlException("Table[" + olapTable.getName() + "] 
is under " + olapTable.getState());
+            table.writeLockOrDdlException();
+            try {
+                if (table instanceof OlapTable) {
+                    OlapTable olapTable = (OlapTable) table;
+                    if (olapTable.getState() != OlapTableState.NORMAL) {
+                        throw new DdlException("Table[" + olapTable.getName() 
+ "] is under " + olapTable.getState());
+                    }
                 }
-            }
 
-            String oldTableName = table.getName();
-            String newTableName = tableRenameClause.getNewTableName();
-            if (oldTableName.equals(newTableName)) {
-                throw new DdlException("Same table name");
-            }
+                String oldTableName = table.getName();
+                String newTableName = tableRenameClause.getNewTableName();
+                if (oldTableName.equals(newTableName)) {
+                    throw new DdlException("Same table name");
+                }
 
-            // check if name is already used
-            if (db.getTable(newTableName).isPresent()) {
-                throw new DdlException("Table name[" + newTableName + "] is 
already used");
-            }
+                // check if name is already used
+                if (db.getTable(newTableName).isPresent()) {
+                    throw new DdlException("Table name[" + newTableName + "] 
is already used");
+                }
 
-            if (table.getType() == TableType.OLAP) {
-                // olap table should also check if any rollup has same name as 
"newTableName"
-                ((OlapTable) table).checkAndSetName(newTableName, false);
-            } else {
-                table.setName(newTableName);
-            }
+                if (table.getType() == TableType.OLAP) {
+                    // olap table should also check if any rollup has same 
name as "newTableName"
+                    ((OlapTable) table).checkAndSetName(newTableName, false);
+                } else {
+                    table.setName(newTableName);
+                }
 
-            db.dropTable(oldTableName);
-            db.createTable(table);
+                db.dropTable(oldTableName);
+                db.createTable(table);
 
-            TableInfo tableInfo = TableInfo.createForTableRename(db.getId(), 
table.getId(), newTableName);
-            editLog.logTableRename(tableInfo);
-            LOG.info("rename table[{}] to {}", oldTableName, newTableName);
+                TableInfo tableInfo = 
TableInfo.createForTableRename(db.getId(), table.getId(), newTableName);
+                editLog.logTableRename(tableInfo);
+                LOG.info("rename table[{}] to {}", oldTableName, newTableName);
+            } finally {
+                table.writeUnlock();
+            }
         } finally {
-            table.writeUnlock();
             db.writeUnlock();
         }
     }
@@ -5412,16 +5453,16 @@ public class Catalog {
         db.writeLock();
         try {
             Table table = db.getTableOrMetaException(tableId);
-            String tableName = table.getName();
-            db.dropTable(tableName);
             table.writeLock();
             try {
+                String tableName = table.getName();
+                db.dropTable(tableName);
                 table.setName(newTableName);
+                db.createTable(table);
+                LOG.info("replay rename table[{}] to {}", tableName, 
newTableName);
             } finally {
                 table.writeUnlock();
             }
-            db.createTable(table);
-            LOG.info("replay rename table[{}] to {}", tableName, newTableName);
         } finally {
             db.writeUnlock();
         }
@@ -5534,7 +5575,7 @@ public class Catalog {
     }
 
     public void renameRollup(Database db, OlapTable table, RollupRenameClause 
renameClause) throws DdlException {
-        table.writeLock();
+        table.writeLockOrDdlException();
         try {
             if (table.getState() != OlapTableState.NORMAL) {
                 throw new DdlException("Table[" + table.getName() + "] is 
under " + table.getState());
@@ -5595,7 +5636,7 @@ public class Catalog {
     }
 
     public void renamePartition(Database db, OlapTable table, 
PartitionRenameClause renameClause) throws DdlException {
-        table.writeLock();
+        table.writeLockOrDdlException();
         try {
             if (table.getState() != OlapTableState.NORMAL) {
                 throw new DdlException("Table[" + table.getName() + "] is 
under " + table.getState());
@@ -5806,8 +5847,7 @@ public class Catalog {
     }
 
     public void modifyDefaultDistributionBucketNum(Database db, OlapTable 
olapTable, ModifyDistributionClause modifyDistributionClause) throws 
DdlException {
-        olapTable.writeLock();
-
+        olapTable.writeLockOrDdlException();
         try {
             if (olapTable.isColocateTable()) {
                 throw new DdlException("Cannot change default bucket number of 
colocate table.");
@@ -6838,7 +6878,7 @@ public class Catalog {
         // before replacing, we need to check again.
         // Things may be changed outside the table lock.
         olapTable = (OlapTable) db.getTableOrDdlException(copiedTbl.getId());
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             if (olapTable.getState() != OlapTableState.NORMAL) {
                 throw new DdlException("Table' state is not NORMAL: " + 
olapTable.getState());
@@ -7040,7 +7080,7 @@ public class Catalog {
     // Convert table's distribution type from random to hash.
     // random distribution is no longer supported.
     public void convertDistributionType(Database db, OlapTable tbl) throws 
DdlException {
-        tbl.writeLock();
+        tbl.writeLockOrDdlException();
         try {
             if (!tbl.convertRandomDistributionToHashDistribution()) {
                 throw new DdlException("Table " + tbl.getName() + " is not 
random distributed");
@@ -7190,7 +7230,7 @@ public class Catalog {
             }
             Database db = this.getDbOrMetaException(meta.getDbId());
             Table table = db.getTableOrMetaException(meta.getTableId());
-            table.writeLock();
+            table.writeLockOrMetaException();
             try {
                 Replica replica = tabletInvertedIndex.getReplica(tabletId, 
backendId);
                 if (replica == null) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/CatalogRecycleBin.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/CatalogRecycleBin.java
index 5d5e903..e3d61be 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/CatalogRecycleBin.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/CatalogRecycleBin.java
@@ -366,15 +366,17 @@ public class CatalogRecycleBin extends MasterDaemon 
implements Writable {
             if (!table.getName().equals(tableName)) {
                 continue;
             }
-
-            db.createTable(table);
-
-            iterator.remove();
-            idToRecycleTime.remove(table.getId());
-
-            // log
-            RecoverInfo recoverInfo = new RecoverInfo(dbId, table.getId(), 
-1L);
-            
Catalog.getCurrentCatalog().getEditLog().logRecoverTable(recoverInfo);
+            table.writeLock();
+            try {
+                db.createTable(table);
+                iterator.remove();
+                idToRecycleTime.remove(table.getId());
+                // log
+                RecoverInfo recoverInfo = new RecoverInfo(dbId, table.getId(), 
-1L);
+                
Catalog.getCurrentCatalog().getEditLog().logRecoverTable(recoverInfo);
+            } finally {
+                table.writeUnlock();
+            }
             LOG.info("recover db[{}] with table[{}]: {}", dbId, table.getId(), 
table.getName());
             return true;
         }
@@ -391,13 +393,17 @@ public class CatalogRecycleBin extends MasterDaemon 
implements Writable {
             if (tableInfo.getTable().getId() != tableId) {
                 continue;
             }
-
             Preconditions.checkState(tableInfo.getDbId() == db.getId());
-
-            db.createTable(tableInfo.getTable());
-            iterator.remove();
-            idToRecycleTime.remove(tableInfo.getTable().getId());
-            LOG.info("replay recover table[{}]", tableId);
+            Table table = tableInfo.getTable();
+            table.writeLock();
+            try {
+                db.createTable(tableInfo.getTable());
+                iterator.remove();
+                idToRecycleTime.remove(tableInfo.getTable().getId());
+                LOG.info("replay recover table[{}]", tableId);
+            } finally {
+                table.writeUnlock();
+            }
             break;
         }
     }
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 1803c78..3817c34 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
@@ -95,6 +95,8 @@ public class Database extends MetaObject implements Writable {
 
     private volatile long replicaQuotaSize;
 
+    private volatile boolean isDropped;
+
     public enum DbState {
         NORMAL, LINK, MOVE
     }
@@ -126,6 +128,14 @@ public class Database extends MetaObject implements 
Writable {
         this.dbEncryptKey = new DatabaseEncryptKey();
     }
 
+    public void markDropped() {
+        isDropped = true;
+    }
+
+    public void unmarkDropped() {
+        isDropped = false;
+    }
+
     public void readLock() {
         this.rwLock.readLock().lock();
     }
@@ -155,6 +165,26 @@ public class Database extends MetaObject implements 
Writable {
         return this.rwLock.writeLock().isHeldByCurrentThread();
     }
 
+    public boolean writeLockIfExist() {
+        if (!isDropped) {
+            this.rwLock.writeLock().lock();
+            return true;
+        }
+        return false;
+    }
+
+    public <E extends Exception> void writeLockOrException(E e) throws E {
+        writeLock();
+        if (isDropped) {
+            writeUnlock();
+            throw e;
+        }
+    }
+
+    public void writeLockOrDdlException() throws DdlException {
+        writeLockOrException(new DdlException("unknown db, dbName=" + 
fullQualifiedName));
+    }
+
     public long getId() {
         return id;
     }
@@ -172,26 +202,16 @@ public class Database extends MetaObject implements 
Writable {
         }
     }
 
-    public void setDataQuotaWithLock(long newQuota) {
+    public void setDataQuota(long newQuota) {
         Preconditions.checkArgument(newQuota >= 0L);
         LOG.info("database[{}] set quota from {} to {}", fullQualifiedName, 
dataQuotaBytes, newQuota);
-        writeLock();
-        try {
-            this.dataQuotaBytes = newQuota;
-        } finally {
-            writeUnlock();
-        }
+        this.dataQuotaBytes = newQuota;
     }
 
-    public void setReplicaQuotaWithLock(long newQuota) {
+    public void setReplicaQuota(long newQuota) {
         Preconditions.checkArgument(newQuota >= 0L);
         LOG.info("database[{}] set replica quota from {} to {}", 
fullQualifiedName, replicaQuotaSize, newQuota);
-        writeLock();
-        try {
-            this.replicaQuotaSize = newQuota;
-        } finally {
-            writeUnlock();
-        }
+        this.replicaQuotaSize = newQuota;
     }
 
     public long getDataQuota() {
@@ -302,12 +322,12 @@ public class Database extends MetaObject implements 
Writable {
     }
 
     // return pair <success?, table exist?>
-    public Pair<Boolean, Boolean> createTableWithLock(Table table, boolean 
isReplay, boolean setIfNotExist) {
+    public Pair<Boolean, Boolean> createTableWithLock(Table table, boolean 
isReplay, boolean setIfNotExist) throws DdlException {
         boolean result = true;
         // if a table is already exists, then edit log won't be executed
         // some caller of this method may need to know this message
         boolean isTableExist = false;
-        writeLock();
+        writeLockOrDdlException();
         try {
             String tableName = table.getName();
             if (Catalog.isStoredTableNamesLowerCase()) {
@@ -349,18 +369,10 @@ public class Database extends MetaObject implements 
Writable {
             nameToTable.put(table.getName(), table);
             lowerCaseToTableName.put(tableName.toLowerCase(), tableName);
         }
+        table.unmarkDropped();
         return result;
     }
 
-    public void dropTableWithLock(String tableName) {
-        writeLock();
-        try {
-            dropTable(tableName);
-        } finally {
-            writeUnlock();
-        }
-    }
-
     public void dropTable(String tableName) {
         if (Catalog.isStoredTableNamesLowerCase()) {
             tableName = tableName.toLowerCase();
@@ -370,6 +382,7 @@ public class Database extends MetaObject implements 
Writable {
             this.nameToTable.remove(tableName);
             this.idToTable.remove(table.getId());
             this.lowerCaseToTableName.remove(tableName.toLowerCase());
+            table.markDropped();
         }
     }
 
@@ -490,6 +503,7 @@ public class Database extends MetaObject implements 
Writable {
     public Table getTableOrMetaException(long tableId) throws 
MetaNotFoundException {
         return getTableOrException(tableId, t -> new 
MetaNotFoundException("unknown table, tableId=" + t));
     }
+
     @SuppressWarnings("unchecked")
     public <T extends Table> T getTableOrMetaException(String tableName, 
TableType tableType) throws MetaNotFoundException {
         Table table = getTableOrMetaException(tableName);
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
index 919a94c..a0c1fb1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Table.java
@@ -17,8 +17,11 @@
 
 package org.apache.doris.catalog;
 
+import org.apache.doris.alter.AlterCancelException;
 import org.apache.doris.analysis.CreateTableStmt;
+import org.apache.doris.common.DdlException;
 import org.apache.doris.common.FeMetaVersion;
+import org.apache.doris.common.MetaNotFoundException;
 import org.apache.doris.common.io.Text;
 import org.apache.doris.common.io.Writable;
 import org.apache.doris.common.util.SqlUtils;
@@ -54,6 +57,8 @@ public class Table extends MetaObject implements Writable {
     // assume that the time a lock is held by thread is less then 100ms
     public static final long TRY_LOCK_TIMEOUT_MS = 100L;
 
+    public volatile boolean isDropped = false;
+
     public enum TableType {
         MYSQL,
         ODBC,
@@ -135,6 +140,14 @@ public class Table extends MetaObject implements Writable {
         this.createTime = Instant.now().getEpochSecond();
     }
 
+    public void markDropped() {
+        isDropped = true;
+    }
+
+    public void unmarkDropped() {
+        isDropped = false;
+    }
+
     public void readLock() {
         this.rwLock.readLock().lock();
     }
@@ -156,6 +169,14 @@ public class Table extends MetaObject implements Writable {
         this.rwLock.writeLock().lock();
     }
 
+    public boolean writeLockIfExist() {
+        if (!isDropped) {
+            this.rwLock.writeLock().lock();
+            return true;
+        }
+        return false;
+    }
+
     public boolean tryWriteLock(long timeout, TimeUnit unit) {
         try {
            return this.rwLock.writeLock().tryLock(timeout, unit);
@@ -173,6 +194,52 @@ public class Table extends MetaObject implements Writable {
         return this.rwLock.writeLock().isHeldByCurrentThread();
     }
 
+    public <E extends Exception> void writeLockOrException(E e) throws E {
+        writeLock();
+        if (isDropped) {
+            writeUnlock();
+            throw e;
+        }
+    }
+
+    public void writeLockOrDdlException() throws DdlException {
+        writeLockOrException(new DdlException("unknown table, tableName=" + 
name));
+    }
+
+    public void writeLockOrMetaException() throws MetaNotFoundException {
+        writeLockOrException(new MetaNotFoundException("unknown table, 
tableName=" + name));
+    }
+
+    public void writeLockOrAlterCancelException() throws AlterCancelException {
+        writeLockOrException(new AlterCancelException("unknown table, 
tableName=" + name));
+    }
+
+    public boolean tryWriteLockOrMetaException(long timeout, TimeUnit unit) 
throws MetaNotFoundException {
+        return tryWriteLockOrException(timeout, unit, new 
MetaNotFoundException("unknown table, tableName=" + name));
+    }
+
+    public <E extends Exception> boolean tryWriteLockOrException(long timeout, 
TimeUnit unit, E e) throws E {
+        if (tryWriteLock(timeout, unit)) {
+            if (isDropped) {
+                writeUnlock();
+                throw e;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public boolean tryWriteLockIfExist(long timeout, TimeUnit unit) {
+        if (tryWriteLock(timeout, unit)) {
+            if (isDropped) {
+                writeUnlock();
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
     public boolean isTypeRead() {
         return isTypeRead;
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/catalog/TabletStatMgr.java 
b/fe/fe-core/src/main/java/org/apache/doris/catalog/TabletStatMgr.java
index ed02c39..9755822 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/TabletStatMgr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/TabletStatMgr.java
@@ -91,9 +91,10 @@ public class TabletStatMgr extends MasterDaemon {
                 if (table.getType() != TableType.OLAP) {
                     continue;
                 }
-
                 OlapTable olapTable = (OlapTable) table;
-                table.writeLock();
+                if (!table.writeLockIfExist()) {
+                    continue;
+                }
                 try {
                     for (Partition partition : olapTable.getAllPartitions()) {
                         long version = partition.getVisibleVersion();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java
 
b/fe/fe-core/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java
index 4a6fc1d..e85b620 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/clone/DynamicPartitionScheduler.java
@@ -406,7 +406,9 @@ public class DynamicPartitionScheduler extends MasterDaemon 
{
             }
 
             for (DropPartitionClause dropPartitionClause : 
dropPartitionClauses) {
-                olapTable.writeLock();
+                if (!olapTable.writeLockIfExist()) {
+                    continue;
+                }
                 try {
                     Catalog.getCurrentCatalog().dropPartition(db, olapTable, 
dropPartitionClause);
                     clearDropPartitionFailedMsg(olapTable.getId());
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/clone/TabletSchedCtx.java 
b/fe/fe-core/src/main/java/org/apache/doris/clone/TabletSchedCtx.java
index c67c3cc..7af0af3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/clone/TabletSchedCtx.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/clone/TabletSchedCtx.java
@@ -678,8 +678,7 @@ public class TabletSchedCtx implements 
Comparable<TabletSchedCtx> {
             Database db = Catalog.getCurrentCatalog().getDbNullable(dbId);
             if (db != null) {
                 Table table = db.getTableNullable(tblId);
-                if (table != null) {
-                    table.writeLock();
+                if (table != null && table.writeLockIfExist()) {
                     try {
                         List<Replica> cloneReplicas = Lists.newArrayList();
                         tablet.getReplicas().stream().filter(r -> r.getState() 
== ReplicaState.CLONE).forEach(r -> {
@@ -833,10 +832,9 @@ public class TabletSchedCtx implements 
Comparable<TabletSchedCtx> {
         }
 
         // 1. check the tablet status first
-        Database db = Catalog.getCurrentCatalog().getDbOrException(dbId, s -> 
new SchedException(Status.UNRECOVERABLE, "db does not exist"));
-        OlapTable olapTable = (OlapTable) db.getTableOrException(tblId, s -> 
new SchedException(Status.UNRECOVERABLE, "tbl does not exist"));
-
-        olapTable.writeLock();
+        Database db = Catalog.getCurrentCatalog().getDbOrException(dbId, s -> 
new SchedException(Status.UNRECOVERABLE, "db " + dbId + " does not exist"));
+        OlapTable olapTable = (OlapTable) db.getTableOrException(tblId, s -> 
new SchedException(Status.UNRECOVERABLE, "tbl " + tabletId + " does not 
exist"));
+        olapTable.writeLockOrException(new 
SchedException(Status.UNRECOVERABLE, "table " + olapTable.getName() + " does 
not exist"));
         try {
             Partition partition = olapTable.getPartition(partitionId);
             if (partition == null) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/clone/TabletScheduler.java 
b/fe/fe-core/src/main/java/org/apache/doris/clone/TabletScheduler.java
index 1215da2..39573e1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/clone/TabletScheduler.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/clone/TabletScheduler.java
@@ -469,10 +469,11 @@ public class TabletScheduler extends MasterDaemon {
         stat.counterTabletScheduled.incrementAndGet();
 
         Pair<TabletStatus, TabletSchedCtx.Priority> statusPair;
-        // check this tablet again
-        Database db = catalog.getDbOrException(tabletCtx.getDbId(), s -> new 
SchedException(Status.UNRECOVERABLE, "db does not exist"));
-        OlapTable tbl = (OlapTable) 
db.getTableOrException(tabletCtx.getTblId(), s -> new 
SchedException(Status.UNRECOVERABLE, "tbl does not exist"));
-        tbl.writeLock();
+        Database db = 
Catalog.getCurrentCatalog().getDbOrException(tabletCtx.getDbId(),
+                s -> new SchedException(Status.UNRECOVERABLE, "db " + 
tabletCtx.getDbId() + " does not exist"));
+        OlapTable tbl = (OlapTable) 
db.getTableOrException(tabletCtx.getTblId(),
+                s -> new SchedException(Status.UNRECOVERABLE, "tbl " + 
tabletCtx.getTblId() + " does not exist"));
+        tbl.writeLockOrException(new SchedException(Status.UNRECOVERABLE, 
"table " + tbl.getName() + " does not exist"));
         try {
             boolean isColocateTable = 
colocateTableIndex.isColocateTable(tbl.getId());
 
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 ed0e06a..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
@@ -19,6 +19,7 @@ package org.apache.doris.common.util;
 
 import org.apache.doris.catalog.Database;
 import org.apache.doris.catalog.Table;
+import org.apache.doris.common.MetaNotFoundException;
 
 import java.util.List;
 import java.util.concurrent.TimeUnit;
@@ -60,13 +61,33 @@ public class MetaLockUtils {
         }
     }
 
-    public static boolean tryWriteLockTables(List<Table> tableList, long 
timeout, TimeUnit unit) {
+    public static void writeLockTablesOrMetaException(List<Table> tableList) 
throws MetaNotFoundException {
         for (int i = 0; i < tableList.size(); i++) {
-            if (!tableList.get(i).tryWriteLock(timeout, unit)) {
+            try {
+                tableList.get(i).writeLockOrMetaException();
+            } catch (MetaNotFoundException e) {
                 for (int j = i - 1; j >= 0; j--) {
                     tableList.get(j).writeUnlock();
                 }
-                return false;
+                throw e;
+            }
+        }
+    }
+
+    public static boolean tryWriteLockTablesOrMetaException(List<Table> 
tableList, long timeout, TimeUnit unit) throws MetaNotFoundException {
+        for (int i = 0; i < tableList.size(); i++) {
+            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();
+                }
+                throw e;
             }
         }
         return true;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/consistency/CheckConsistencyJob.java
 
b/fe/fe-core/src/main/java/org/apache/doris/consistency/CheckConsistencyJob.java
index d0cbb49..4d32786 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/consistency/CheckConsistencyJob.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/consistency/CheckConsistencyJob.java
@@ -215,7 +215,10 @@ public class CheckConsistencyJob {
 
         if (state != JobState.RUNNING) {
             // failed to send task. set tablet's checked version and version 
hash to avoid choosing it again
-            table.writeLock();
+            if (!table.writeLockIfExist()) {
+                LOG.debug("table[{}] does not exist", tabletMeta.getTableId());
+                return false;
+            }
             try {
                 tablet.setCheckedVersion(checkedVersion, checkedVersionHash);
             } finally {
@@ -261,11 +264,10 @@ public class CheckConsistencyJob {
 
         boolean isConsistent = true;
         Table table = db.getTableNullable(tabletMeta.getTableId());
-        if (table == null) {
+        if (table == null || !table.writeLockIfExist()) {
             LOG.warn("table[{}] does not exist", tabletMeta.getTableId());
             return -1;
         }
-        table.writeLock();
         try {
             OlapTable olapTable = (OlapTable) table;
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/http/rest/RowCountAction.java 
b/fe/fe-core/src/main/java/org/apache/doris/http/rest/RowCountAction.java
index e134fc3..4648065 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/http/rest/RowCountAction.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/http/rest/RowCountAction.java
@@ -74,7 +74,7 @@ public class RowCountAction extends RestBaseAction {
         Catalog catalog = Catalog.getCurrentCatalog();
         Database db = catalog.getDbOrDdlException(dbName);
         OlapTable olapTable = db.getOlapTableOrDdlException(tableName);
-        olapTable.writeLock();
+        olapTable.writeLockOrDdlException();
         try {
             for (Partition partition : olapTable.getAllPartitions()) {
                 long version = partition.getVisibleVersion();
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/http/rest/TableRowCountAction.java 
b/fe/fe-core/src/main/java/org/apache/doris/http/rest/TableRowCountAction.java
index 3b75547..1b4a8ed 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/http/rest/TableRowCountAction.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/http/rest/TableRowCountAction.java
@@ -84,13 +84,13 @@ public class TableRowCountAction extends RestBaseAction {
                 throw new DorisHttpException(HttpResponseStatus.BAD_REQUEST, 
e.getMessage());
             }
 
-            table.writeLock();
+            table.readLock();
             try {
                 OlapTable olapTable = (OlapTable) table;
                 resultMap.put("status", 200);
                 resultMap.put("size", olapTable.proximateRowCount());
             } finally {
-                table.writeUnlock();
+                table.readUnlock();
             }
         } catch (DorisHttpException e) {
             // status code  should conforms to HTTP semantic
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableRowCountAction.java
 
b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableRowCountAction.java
index 8d9d7f9..a473bc0 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableRowCountAction.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/httpv2/rest/TableRowCountAction.java
@@ -74,7 +74,7 @@ public class TableRowCountAction extends RestBaseController {
                 resultMap.put("status", 200);
                 resultMap.put("size", olapTable.proximateRowCount());
             } finally {
-                olapTable.readLock();
+                olapTable.readUnlock();
             }
         } catch (DorisHttpException e) {
             // status code  should conforms to HTTP semantic
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBJEJournal.java 
b/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBJEJournal.java
index c4c1b71..e4b4ac6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBJEJournal.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/journal/bdbje/BDBJEJournal.java
@@ -157,7 +157,6 @@ public class BDBJEJournal implements Journal {
                 } catch (InterruptedException e1) {
                     e1.printStackTrace();
                 }
-                continue;
             }
         }
 
diff --git a/fe/fe-core/src/main/java/org/apache/doris/load/LoadChecker.java 
b/fe/fe-core/src/main/java/org/apache/doris/load/LoadChecker.java
index 3793acc..17fdea6 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/load/LoadChecker.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/load/LoadChecker.java
@@ -331,7 +331,12 @@ public class LoadChecker extends MasterDaemon {
         // concurrent problems
 
         // table in tables are ordered.
-        MetaLockUtils.writeLockTables(tables);
+        try {
+            MetaLockUtils.writeLockTablesOrMetaException(tables);
+        } catch (UserException e) {
+            load.cancelLoadJob(job, CancelType.LOAD_RUN_FAIL, "table does not 
exist. dbId: " + job.getDbId() + ", err: " + e.getMessage());
+            return;
+        }
         try {
             TabletInvertedIndex invertedIndex = 
Catalog.getCurrentInvertedIndex();
             for (Replica replica : job.getFinishedReplicas()) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/BrokerLoadJob.java 
b/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/BrokerLoadJob.java
index 6f03f4f..cefd28e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/BrokerLoadJob.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/BrokerLoadJob.java
@@ -277,6 +277,7 @@ public class BrokerLoadJob extends BulkLoadJob {
         try {
             db = getDb();
             tableList = 
db.getTablesOnIdOrderOrThrowException(Lists.newArrayList(fileGroupAggInfo.getAllTableIds()));
+            MetaLockUtils.writeLockTablesOrMetaException(tableList);
         } catch (MetaNotFoundException e) {
             LOG.warn(new LogBuilder(LogKey.LOAD_JOB, id)
                     .add("database_id", dbId)
@@ -285,7 +286,6 @@ public class BrokerLoadJob extends BulkLoadJob {
             cancelJobWithoutCheck(new 
FailMsg(FailMsg.CancelType.LOAD_RUN_FAIL, e.getMessage()), true, true);
             return;
         }
-        MetaLockUtils.writeLockTables(tableList);
         try {
             LOG.info(new LogBuilder(LogKey.LOAD_JOB, id)
                     .add("txn_id", transactionId)
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/SparkLoadJob.java 
b/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/SparkLoadJob.java
index 9185437..d5e3136 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/SparkLoadJob.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/load/loadv2/SparkLoadJob.java
@@ -626,7 +626,7 @@ public class SparkLoadJob extends BulkLoadJob {
                          .build());
         Database db = getDb();
         List<Table> tableList = 
db.getTablesOnIdOrderOrThrowException(Lists.newArrayList(tableToLoadPartitions.keySet()));
-        MetaLockUtils.writeLockTables(tableList);
+        MetaLockUtils.writeLockTablesOrMetaException(tableList);
         try {
             Catalog.getCurrentGlobalTransactionMgr().commitTransaction(
                     dbId, tableList, transactionId, commitInfos,
diff --git a/fe/fe-core/src/main/java/org/apache/doris/master/MasterImpl.java 
b/fe/fe-core/src/main/java/org/apache/doris/master/MasterImpl.java
index 55de348..fdf971e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/master/MasterImpl.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/master/MasterImpl.java
@@ -338,12 +338,11 @@ public class MasterImpl {
         LOG.debug("push report state: {}", pushState.name());
 
         OlapTable olapTable = (OlapTable) db.getTableNullable(tableId);
-        if (olapTable == null) {
+        if (olapTable == null || !olapTable.writeLockIfExist()) {
             AgentTaskQueue.removeTask(backendId, TTaskType.REALTIME_PUSH, 
signature);
             LOG.warn("finish push replica error, cannot find table[" + tableId 
+ "] when push finished");
             return;
         }
-        olapTable.writeLock();
         try {
             Partition partition = olapTable.getPartition(partitionId);
             if (partition == null) {
@@ -552,12 +551,11 @@ public class MasterImpl {
         LOG.debug("push report state: {}", pushState.name());
 
         OlapTable olapTable = (OlapTable) db.getTableNullable(tableId);
-        if (olapTable == null) {
+        if (olapTable == null || !olapTable.writeLockIfExist()) {
             AgentTaskQueue.removeTask(backendId, TTaskType.REALTIME_PUSH, 
signature);
             LOG.warn("finish push replica error, cannot find table[" + tableId 
+ "] when push finished");
             return;
         }
-        olapTable.writeLock();
         try {
             Partition partition = olapTable.getPartition(partitionId);
             if (partition == null) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/master/ReportHandler.java 
b/fe/fe-core/src/main/java/org/apache/doris/master/ReportHandler.java
index 3775afb..fabc2c7 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/master/ReportHandler.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/master/ReportHandler.java
@@ -416,10 +416,9 @@ public class ReportHandler extends Daemon {
                 long tabletId = tabletIds.get(i);
                 long tableId = tabletMeta.getTableId();
                 OlapTable olapTable = (OlapTable) db.getTableNullable(tableId);
-                if (olapTable == null) {
+                if (olapTable == null || !olapTable.writeLockIfExist()) {
                     continue;
                 }
-                olapTable.writeLock();
                 try {
                     long partitionId = tabletMeta.getPartitionId();
                     Partition partition = olapTable.getPartition(partitionId);
@@ -545,10 +544,9 @@ public class ReportHandler extends Daemon {
                 long tabletId = tabletIds.get(i);
                 long tableId = tabletMeta.getTableId();
                 OlapTable olapTable = (OlapTable) db.getTableNullable(tableId);
-                if (olapTable == null) {
+                if (olapTable == null || !olapTable.writeLockIfExist()) {
                     continue;
                 }
-                olapTable.writeLock();
                 try {
                     long partitionId = tabletMeta.getPartitionId();
                     Partition partition = olapTable.getPartition(partitionId);
@@ -827,10 +825,9 @@ public class ReportHandler extends Daemon {
                 long tabletId = tabletIds.get(i);
                 long tableId = tabletMeta.getTableId();
                 OlapTable olapTable = (OlapTable) db.getTableNullable(tableId);
-                if (olapTable == null) {
+                if (olapTable == null || !olapTable.writeLockIfExist()) {
                     continue;
                 }
-                olapTable.writeLock();
                 try {
                     long partitionId = tabletMeta.getPartitionId();
                     Partition partition = olapTable.getPartition(partitionId);
@@ -949,7 +946,7 @@ public class ReportHandler extends Daemon {
 
         Database db = Catalog.getCurrentCatalog().getDbOrMetaException(dbId);
         OlapTable olapTable = db.getTableOrMetaException(tableId, 
Table.TableType.OLAP);
-        olapTable.writeLock();
+        olapTable.writeLockOrMetaException();
         try {
             Partition partition = olapTable.getPartition(partitionId);
             if (partition == null) {
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/transaction/DatabaseTransactionMgr.java
 
b/fe/fe-core/src/main/java/org/apache/doris/transaction/DatabaseTransactionMgr.java
index 5cc8002..87cd981 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/transaction/DatabaseTransactionMgr.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/transaction/DatabaseTransactionMgr.java
@@ -690,23 +690,8 @@ public class DatabaseTransactionMgr {
             }
         }
         List<Long> tableIdList = transactionState.getTableIdList();
-        // to be compatiable with old meta version, table List may be empty
-        if (tableIdList.isEmpty()) {
-            readLock();
-            try {
-                for (TableCommitInfo tableCommitInfo : 
transactionState.getIdToTableCommitInfos().values()) {
-                    long tableId = tableCommitInfo.getTableId();
-                    if (!tableIdList.contains(tableId)) {
-                        tableIdList.add(tableId);
-                    }
-                }
-            } finally {
-                readUnlock();
-            }
-        }
-
-        List<Table> tableList = 
db.getTablesOnIdOrderWithIgnoringWrongTableId(tableIdList);
-        MetaLockUtils.writeLockTables(tableList);
+        List<Table> tableList = 
db.getTablesOnIdOrderOrThrowException(tableIdList);
+        MetaLockUtils.writeLockTablesOrMetaException(tableList);
         try {
             boolean hasError = false;
             Iterator<TableCommitInfo> tableCommitInfoIterator = 
transactionState.getIdToTableCommitInfos().values().iterator();
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 198b5a4..6aedf62 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/InfoSchemaDbTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/catalog/InfoSchemaDbTest.java
index 0a808c9..422a7ac 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/catalog/InfoSchemaDbTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/InfoSchemaDbTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.doris.catalog;
 
+import org.apache.doris.common.DdlException;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -24,7 +25,7 @@ import java.io.IOException;
 
 public class InfoSchemaDbTest {
     @Test
-    public void testNormal() throws IOException {
+    public void testNormal() throws IOException, DdlException {
         Database db = new InfoSchemaDb();
 
         Assert.assertFalse(db.createTable(null));
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 47fb1ff..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
@@ -20,14 +20,20 @@ package org.apache.doris.common.util;
 import com.google.common.collect.Lists;
 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());
@@ -55,7 +61,7 @@ public class MetaLockUtilsTest {
     }
 
     @Test
-    public void testWriteLockTables() {
+    public void testWriteLockTables() throws MetaNotFoundException {
         List<Table> tableList = Lists.newArrayList(new 
Table(Table.TableType.OLAP), new Table(Table.TableType.OLAP));
         MetaLockUtils.writeLockTables(tableList);
         Assert.assertTrue(tableList.get(0).isWriteLockHeldByCurrentThread());
@@ -63,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: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to