morningman commented on a change in pull request #3775:
URL: https://github.com/apache/incubator-doris/pull/3775#discussion_r530313863



##########
File path: fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
##########
@@ -128,30 +124,10 @@ public void 
processDropMaterializedView(DropMaterializedViewStmt stmt) throws Dd
             ErrorReport.reportDdlException(ErrorCode.ERR_BAD_DB_ERROR, dbName);
         }
 
-        db.writeLock();
-        try {
-            String tableName = stmt.getTableName().getTbl();
-            Table table = db.getTable(tableName);
-            // if table exists
-            if (table == null) {
-                ErrorReport.reportDdlException(ErrorCode.ERR_BAD_TABLE_ERROR, 
tableName);
-            }
-            // check table type
-            if (table.getType() != TableType.OLAP) {
-                throw new DdlException("Do not support non-OLAP table [" + 
tableName + "] when drop materialized view");
-            }
-            // check table state
-            OlapTable olapTable = (OlapTable) table;
-            if (olapTable.getState() != OlapTableState.NORMAL) {
-                throw new DdlException("Table[" + table.getName() + "]'s state 
is not NORMAL. "
-                        + "Do not allow doing DROP ops");
-            }
-            // drop materialized view
-            
((MaterializedViewHandler)materializedViewHandler).processDropMaterializedView(stmt,
 db, olapTable);
-
-        } finally {
-            db.writeUnlock();
-        }
+        String tableName = stmt.getTableName().getTbl();
+        OlapTable olapTable = (OlapTable) 
db.getTableOrThrowException(tableName, TableType.OLAP);

Review comment:
       Missing `if (olapTable.getState() != OlapTableState.NORMAL) {` check?

##########
File path: fe/fe-core/src/main/java/org/apache/doris/backup/BackupHandler.java
##########
@@ -274,25 +274,25 @@ private void backup(Repository repository, Database db, 
BackupStmt stmt) throws
         // This is just a pre-check to avoid most of invalid backup requests.
         // Also calculate the signature for incremental backup check.
         List<TableRef> tblRefs = stmt.getTableRefs();
-        BackupMeta curBackupMeta = null;
-        db.readLock();
-        try {
-            List<Table> backupTbls = Lists.newArrayList();
-            for (TableRef tblRef : tblRefs) {
-                String tblName = tblRef.getName().getTbl();
-                Table tbl = db.getTable(tblName);
-                if (tbl == null) {
-                    
ErrorReport.reportDdlException(ErrorCode.ERR_BAD_TABLE_ERROR, tblName);
-                }
-                if (tbl.getType() != TableType.OLAP) {
-                    
ErrorReport.reportDdlException(ErrorCode.ERR_NOT_OLAP_TABLE, tblName);
-                }
 
-                OlapTable olapTbl = (OlapTable) tbl;
+        List<Table> backupTbls = Lists.newArrayList();
+        for (TableRef tblRef : tblRefs) {
+            String tblName = tblRef.getName().getTbl();
+            Table tbl = db.getTable(tblName);

Review comment:
       Why not using `getOrThrowException`?

##########
File path: fe/fe-core/src/main/java/org/apache/doris/load/Load.java
##########
@@ -3229,19 +3234,19 @@ public void unprotectDelete(DeleteInfo deleteInfo, 
Database db) {
 
     public void replayFinishAsyncDeleteJob(AsyncDeleteJob deleteJob, Catalog 
catalog) {
         Database db = catalog.getDb(deleteJob.getDbId());
-        db.writeLock();
+        writeLock();

Review comment:
       The lock order is wrong.
   the origin lock order is `db lock` -> 'load lock'.
   But here you use 'table lock' -> 'load lock' 

##########
File path: fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
##########
@@ -232,54 +223,61 @@ private void processAlterExternalTable(AlterTableStmt 
stmt, Table externalTable,
         List<AlterClause> alterClauses = stmt.getOps();
         AlterOperations currentAlterOps = new AlterOperations();
         currentAlterOps.checkConflict(alterClauses);
-
         if (currentAlterOps.hasRenameOp()) {
             processRename(db, externalTable, alterClauses);
         } else if (currentAlterOps.hasSchemaChangeOp()) {
-            schemaChangeHandler.processExternalTable(alterClauses, db, 
externalTable);
+            externalTable.writeLock();
+            try {
+                schemaChangeHandler.processExternalTable(alterClauses, db, 
externalTable);
+            } finally {
+                externalTable.writeUnlock();
+            }
         }
     }
 
     public void processAlterTable(AlterTableStmt stmt) throws UserException {
         TableName dbTableName = stmt.getTbl();
         String dbName = dbTableName.getDb();
+        String tableName = dbTableName.getTbl();
         final String clusterName = stmt.getClusterName();
 
         Database db = Catalog.getCurrentCatalog().getDb(dbName);
         if (db == null) {
             ErrorReport.reportDdlException(ErrorCode.ERR_BAD_DB_ERROR, dbName);
         }
+        Table table = db.getTable(tableName);
+        if (table == null) {
+            ErrorReport.reportDdlException(ErrorCode.ERR_BAD_TABLE_ERROR, 
tableName);
+        }
         List<AlterClause> alterClauses = Lists.newArrayList();
+        // some operations will take long time to process, need to be done 
outside the table lock
+        boolean needProcessOutsideTableLock = false;
 
-        // some operations will take long time to process, need to be done 
outside the database lock
-        boolean needProcessOutsideDatabaseLock = false;
-        String tableName = dbTableName.getTbl();
-        db.writeLock();
-        try {
-            Table table = db.getTable(tableName);
-            if (table == null) {
-                ErrorReport.reportDdlException(ErrorCode.ERR_BAD_TABLE_ERROR, 
tableName);
-            }
+        // check conflict alter ops first
+        AlterOperations currentAlterOps = new AlterOperations();
+        currentAlterOps.checkConflict(alterClauses);
+        // check cluster capacity and db quota outside table lock to escape 
dead lock, only need to check once.
+        if (currentAlterOps.needCheckCapacity()) {
+            Catalog.getCurrentSystemInfo().checkClusterCapacity(clusterName);
+            db.checkQuota();
+        }
 
-            switch (table.getType()) {
-                case OLAP:
-                    OlapTable olapTable = (OlapTable) table;
-                    needProcessOutsideDatabaseLock = 
processAlterOlapTable(stmt, olapTable, alterClauses, clusterName, db);
-                    break;
-                case ODBC:
-                case MYSQL:
-                case ELASTICSEARCH:
-                    processAlterExternalTable(stmt, table, db);
-                    return;
-                default:
-                    throw new DdlException("Do not support alter " + 
table.getType().toString() + " table[" + tableName + "]");
-            }
-        } finally {
-            db.writeUnlock();
+        switch (table.getType()) {

Review comment:
       I think we can just lock the table outside the `switch`, avoid call 
lock/unlock everywhere inside the `processAlterOlapTable` and 
`processAlterExternalTable`.

##########
File path: fe/fe-core/src/main/java/org/apache/doris/backup/RestoreJob.java
##########
@@ -664,18 +667,25 @@ private void checkAndPrepareMeta() {
                                 remoteDataProperty, (short) 
restoreReplicationNum,
                                 
remotePartitionInfo.getIsInMemory(remotePartId));
                         localTbl.addPartition(restoredPart);
+                    } finally {
+                        localTbl.writeUnlock();
                     }
 
-                    // add restored tables
-                    for (OlapTable tbl : restoredTbls) {
+                }
+
+                // add restored tables
+                for (OlapTable tbl : restoredTbls) {
+                    db.writeLock();
+                    try {

Review comment:
       We can use `db.createTableWithLock()`

##########
File path: fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
##########
@@ -476,27 +464,48 @@ public void processAlterCluster(AlterSystemStmt stmt) 
throws UserException {
     private void processRename(Database db, OlapTable table, List<AlterClause> 
alterClauses) throws DdlException {
         for (AlterClause alterClause : alterClauses) {
             if (alterClause instanceof TableRenameClause) {
-                Catalog.getCurrentCatalog().renameTable(db, table, 
(TableRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof RollupRenameClause) {
-                Catalog.getCurrentCatalog().renameRollup(db, table, 
(RollupRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof PartitionRenameClause) {
-                Catalog.getCurrentCatalog().renamePartition(db, table, 
(PartitionRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof ColumnRenameClause) {
-                Catalog.getCurrentCatalog().renameColumn(db, table, 
(ColumnRenameClause) alterClause);
+                db.writeLock();
+                table.writeLock();
+                try {
+                    Catalog.getCurrentCatalog().renameTable(db, table, 
(TableRenameClause) alterClause);
+                } finally {
+                    table.writeUnlock();
+                    db.writeUnlock();
+                }
                 break;
             } else {
-                Preconditions.checkState(false);
+                table.writeLock();

Review comment:
       Put lock inside the method

##########
File path: fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
##########
@@ -476,27 +464,48 @@ public void processAlterCluster(AlterSystemStmt stmt) 
throws UserException {
     private void processRename(Database db, OlapTable table, List<AlterClause> 
alterClauses) throws DdlException {
         for (AlterClause alterClause : alterClauses) {
             if (alterClause instanceof TableRenameClause) {
-                Catalog.getCurrentCatalog().renameTable(db, table, 
(TableRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof RollupRenameClause) {
-                Catalog.getCurrentCatalog().renameRollup(db, table, 
(RollupRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof PartitionRenameClause) {
-                Catalog.getCurrentCatalog().renamePartition(db, table, 
(PartitionRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof ColumnRenameClause) {
-                Catalog.getCurrentCatalog().renameColumn(db, table, 
(ColumnRenameClause) alterClause);
+                db.writeLock();

Review comment:
       Better put these locks inside the `renameTable` method.

##########
File path: 
fe/fe-core/src/main/java/org/apache/doris/alter/MaterializedViewHandler.java
##########
@@ -722,14 +732,21 @@ public void processBatchDropRollup(List<AlterClause> 
dropRollupClauses, Database
             editLog.logBatchDropRollup(new BatchDropInfo(dbId, tableId, 
indexIdSet));
             LOG.info("finished drop rollup index[{}] in table[{}]", 
String.join("", rollupNameSet), olapTable.getName());
         } finally {
-            db.writeUnlock();
+            olapTable.writeUnlock();
         }
     }
 
     public void processDropMaterializedView(DropMaterializedViewStmt 
dropMaterializedViewStmt, Database db,
             OlapTable olapTable) throws DdlException, MetaNotFoundException {
-        Preconditions.checkState(db.isWriteLockHeldByCurrentThread());
+        Preconditions.checkState(olapTable.isWriteLockHeldByCurrentThread());
+        olapTable.writeLock();

Review comment:
       Why lock again?

##########
File path: fe/fe-core/src/main/java/org/apache/doris/alter/Alter.java
##########
@@ -476,27 +464,48 @@ public void processAlterCluster(AlterSystemStmt stmt) 
throws UserException {
     private void processRename(Database db, OlapTable table, List<AlterClause> 
alterClauses) throws DdlException {
         for (AlterClause alterClause : alterClauses) {
             if (alterClause instanceof TableRenameClause) {
-                Catalog.getCurrentCatalog().renameTable(db, table, 
(TableRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof RollupRenameClause) {
-                Catalog.getCurrentCatalog().renameRollup(db, table, 
(RollupRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof PartitionRenameClause) {
-                Catalog.getCurrentCatalog().renamePartition(db, table, 
(PartitionRenameClause) alterClause);
-                break;
-            } else if (alterClause instanceof ColumnRenameClause) {
-                Catalog.getCurrentCatalog().renameColumn(db, table, 
(ColumnRenameClause) alterClause);
+                db.writeLock();
+                table.writeLock();
+                try {
+                    Catalog.getCurrentCatalog().renameTable(db, table, 
(TableRenameClause) alterClause);
+                } finally {
+                    table.writeUnlock();
+                    db.writeUnlock();
+                }
                 break;
             } else {
-                Preconditions.checkState(false);
+                table.writeLock();
+                try {
+                    if (alterClause instanceof RollupRenameClause) {
+                        Catalog.getCurrentCatalog().renameRollup(db, table, 
(RollupRenameClause) alterClause);
+                        break;
+                    } else if (alterClause instanceof PartitionRenameClause) {
+                        Catalog.getCurrentCatalog().renamePartition(db, table, 
(PartitionRenameClause) alterClause);
+                        break;
+                    } else if (alterClause instanceof ColumnRenameClause) {
+                        Catalog.getCurrentCatalog().renameColumn(db, table, 
(ColumnRenameClause) alterClause);
+                        break;
+                    } else {
+                        Preconditions.checkState(false);
+                    }
+                } finally {
+                    table.writeUnlock();
+                }
             }
         }
     }
 
     private void processRename(Database db, Table table, List<AlterClause> 
alterClauses) throws DdlException {
         for (AlterClause alterClause : alterClauses) {
             if (alterClause instanceof TableRenameClause) {
-                Catalog.getCurrentCatalog().renameTable(db, table, 
(TableRenameClause) alterClause);
+                db.writeLock();

Review comment:
       Put lock inside the method

##########
File path: fe/fe-core/src/main/java/org/apache/doris/backup/RestoreJob.java
##########
@@ -1347,42 +1374,53 @@ public void cancelInternal(boolean isReplay) {
         // clean restored objs
         Database db = catalog.getDb(dbId);
         if (db != null) {
-            db.writeLock();
-            try {
-                // rollback table's state to NORMAL
-                setTableStateToNormal(db);
+            // rollback table's state to NORMAL
+            setTableStateToNormal(db);
 
-                // remove restored tbls
-                for (OlapTable restoreTbl : restoredTbls) {
-                    LOG.info("remove restored table when cancelled: {}", 
restoreTbl.getName());
+            // remove restored tbls
+            for (OlapTable restoreTbl : restoredTbls) {
+                LOG.info("remove restored table when cancelled: {}", 
restoreTbl.getName());
+                restoreTbl.writeLock();
+                try {
                     for (Partition part : restoreTbl.getPartitions()) {
                         for (MaterializedIndex idx : 
part.getMaterializedIndices(IndexExtState.VISIBLE)) {
                             for (Tablet tablet : idx.getTablets()) {
                                 
Catalog.getCurrentInvertedIndex().deleteTablet(tablet.getId());
                             }
                         }
                     }
+                } finally {
+                    restoreTbl.writeUnlock();
+                }
+                db.writeLock();
+                try {

Review comment:
       Use `db.dropTableWithLock()`

##########
File path: fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
##########
@@ -2043,12 +2044,7 @@ public long saveDb(DataOutputStream dos, long checksum) 
throws IOException {
             // Don't write information_schema db meta
             if (!InfoSchemaDb.isInfoSchemaDb(dbName)) {
                 checksum ^= entry.getKey();
-                db.readLock();
-                try {
-                    db.write(dos);
-                } finally {
-                    db.readUnlock();
-                }
+                db.write(dos);

Review comment:
       Is it safe to write db without lock?

##########
File path: fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
##########
@@ -6673,86 +6680,75 @@ public void convertDistributionType(Database db, 
OlapTable tbl) throws DdlExcept
             editLog.logModifyDistributionType(tableInfo);
             LOG.info("finished to modify distribution type of table: " + 
tbl.getName());
         } finally {
-            db.writeUnlock();
+            tbl.writeUnlock();
         }
     }
 
     public void replayConvertDistributionType(TableInfo tableInfo) {
         Database db = getDb(tableInfo.getDbId());
-        db.writeLock();
+        OlapTable tbl = (OlapTable) db.getTable(tableInfo.getTableId());
+        if (tbl == null) {
+            return;
+        }
+        tbl.writeLock();
         try {
-            OlapTable tbl = (OlapTable) db.getTable(tableInfo.getTableId());
             tbl.convertRandomDistributionToHashDistribution();
             LOG.info("replay modify distribution type of table: " + 
tbl.getName());
         } finally {
-            db.writeUnlock();
+            tbl.writeUnlock();
         }
     }
 
     /*
      * The entry of replacing partitions with temp partitions.
      */
-    public void replaceTempPartition(Database db, String tableName, 
ReplacePartitionClause clause) throws DdlException {
+    public void replaceTempPartition(Database db, OlapTable olapTable, 
ReplacePartitionClause clause) throws DdlException {
+        Preconditions.checkState(olapTable.isWriteLockHeldByCurrentThread());
         List<String> partitionNames = clause.getPartitionNames();
         List<String> tempPartitionNames = clause.getTempPartitionNames();
         boolean isStrictRange = clause.isStrictRange();
         boolean useTempPartitionName = clause.useTempPartitionName();
-        db.writeLock();
-        try {
-            Table table = db.getTable(tableName);
-            if (table == null) {
-                ErrorReport.reportDdlException(ErrorCode.ERR_BAD_TABLE_ERROR, 
tableName);
-            }
-
-            if (table.getType() != TableType.OLAP) {
-                throw new DdlException("Table[" + tableName + "] is not OLAP 
table");
+        // check partition exist
+        for (String partName : partitionNames) {
+            if (!olapTable.checkPartitionNameExist(partName, false)) {

Review comment:
       Does `checkPartitionNameExist ` need table lock?

##########
File path: fe/fe-core/src/main/java/org/apache/doris/catalog/Catalog.java
##########
@@ -6673,86 +6680,75 @@ public void convertDistributionType(Database db, 
OlapTable tbl) throws DdlExcept
             editLog.logModifyDistributionType(tableInfo);
             LOG.info("finished to modify distribution type of table: " + 
tbl.getName());
         } finally {
-            db.writeUnlock();
+            tbl.writeUnlock();
         }
     }
 
     public void replayConvertDistributionType(TableInfo tableInfo) {
         Database db = getDb(tableInfo.getDbId());
-        db.writeLock();
+        OlapTable tbl = (OlapTable) db.getTable(tableInfo.getTableId());
+        if (tbl == null) {
+            return;
+        }
+        tbl.writeLock();
         try {
-            OlapTable tbl = (OlapTable) db.getTable(tableInfo.getTableId());
             tbl.convertRandomDistributionToHashDistribution();
             LOG.info("replay modify distribution type of table: " + 
tbl.getName());
         } finally {
-            db.writeUnlock();
+            tbl.writeUnlock();
         }
     }
 
     /*
      * The entry of replacing partitions with temp partitions.
      */
-    public void replaceTempPartition(Database db, String tableName, 
ReplacePartitionClause clause) throws DdlException {
+    public void replaceTempPartition(Database db, OlapTable olapTable, 
ReplacePartitionClause clause) throws DdlException {
+        Preconditions.checkState(olapTable.isWriteLockHeldByCurrentThread());
         List<String> partitionNames = clause.getPartitionNames();
         List<String> tempPartitionNames = clause.getTempPartitionNames();
         boolean isStrictRange = clause.isStrictRange();
         boolean useTempPartitionName = clause.useTempPartitionName();
-        db.writeLock();
-        try {
-            Table table = db.getTable(tableName);
-            if (table == null) {
-                ErrorReport.reportDdlException(ErrorCode.ERR_BAD_TABLE_ERROR, 
tableName);
-            }
-
-            if (table.getType() != TableType.OLAP) {
-                throw new DdlException("Table[" + tableName + "] is not OLAP 
table");
+        // check partition exist
+        for (String partName : partitionNames) {
+            if (!olapTable.checkPartitionNameExist(partName, false)) {
+                throw new DdlException("Partition[" + partName + "] does not 
exist");
             }
-
-            OlapTable olapTable = (OlapTable) table;
-            // check partition exist
-            for (String partName : partitionNames) {
-                if (!olapTable.checkPartitionNameExist(partName, false)) {
-                    throw new DdlException("Partition[" + partName + "] does 
not exist");
-                }
-            }
-            for (String partName : tempPartitionNames) {
-                if (!olapTable.checkPartitionNameExist(partName, true)) {
-                    throw new DdlException("Temp partition[" + partName + "] 
does not exist");
-                }
+        }
+        for (String partName : tempPartitionNames) {
+            if (!olapTable.checkPartitionNameExist(partName, true)) {
+                throw new DdlException("Temp partition[" + partName + "] does 
not exist");
             }
-
-            olapTable.replaceTempPartitions(partitionNames, 
tempPartitionNames, isStrictRange, useTempPartitionName);
-
-            // write log
-            ReplacePartitionOperationLog info = new 
ReplacePartitionOperationLog(db.getId(), olapTable.getId(),
-                    partitionNames, tempPartitionNames, isStrictRange, 
useTempPartitionName);
-            editLog.logReplaceTempPartition(info);
-            LOG.info("finished to replace partitions {} with temp partitions 
{} from table: {}",
-                    clause.getPartitionNames(), 
clause.getTempPartitionNames(), tableName);
-        } finally {
-            db.writeUnlock();
         }
+        olapTable.replaceTempPartitions(partitionNames, tempPartitionNames, 
isStrictRange, useTempPartitionName);

Review comment:
       Does `replaceTempPartitions` need table lock?

##########
File path: 
fe/fe-core/src/main/java/org/apache/doris/clone/ColocateTableBalancer.java
##########
@@ -233,16 +232,16 @@ private void matchGroup() {
                             }
                         }
                     }
-                } // end for tables
-
-                // mark group as stable or unstable
-                if (isGroupStable) {
-                    colocateIndex.markGroupStable(groupId, true);
-                } else {
-                    colocateIndex.markGroupUnstable(groupId, true);
+                } finally {
+                    olapTable.readUnlock();
                 }
-            } finally {
-                db.readUnlock();
+            } // end for tables
+
+            // mark group as stable or unstable
+            if (isGroupStable) {
+                colocateIndex.markGroupStable(groupId, true);

Review comment:
       is it safe to `markGroupStable/markGroupUnstable` outside the lock?

##########
File path: 
fe/fe-core/src/main/java/org/apache/doris/load/loadv2/SparkLoadPendingTask.java
##########
@@ -133,13 +136,18 @@ private void createEtlJobConf() throws LoadException {
         }
 
         Map<Long, EtlTable> tables = Maps.newHashMap();
-        db.readLock();
+        Map<Long, Set<Long>> tableIdToPartitionIds = Maps.newHashMap();
+        Set<Long> allPartitionsTableIds = Sets.newHashSet();
+        prepareTablePartitionInfos(db, tableIdToPartitionIds, 
allPartitionsTableIds);

Review comment:
       In origin implementation, this `prepareTablePartitionInfos` and 
following logic is within same db lock.
   But now you put them into 2 lock phases, which becomes not atomic.

##########
File path: fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
##########
@@ -456,23 +437,23 @@ public void analyze(TQueryOptions tQueryOptions) throws 
UserException {
         if (parsedStmt instanceof QueryStmt
                 || parsedStmt instanceof InsertStmt
                 || parsedStmt instanceof CreateTableAsSelectStmt) {
-            Map<String, Database> dbs = Maps.newTreeMap();
+            Map<Long, Table> tableMap = Maps.newTreeMap();
             QueryStmt queryStmt;
             Set<String> parentViewNameSet = Sets.newHashSet();
             if (parsedStmt instanceof QueryStmt) {
                 queryStmt = (QueryStmt) parsedStmt;
-                queryStmt.getDbs(analyzer, dbs, parentViewNameSet);
+                queryStmt.getTables(analyzer, tableMap, parentViewNameSet);
             } else {
                 InsertStmt insertStmt;
                 if (parsedStmt instanceof InsertStmt) {
                     insertStmt = (InsertStmt) parsedStmt;
                 } else {
                     insertStmt = ((CreateTableAsSelectStmt) 
parsedStmt).getInsertStmt();
                 }
-                insertStmt.getDbs(analyzer, dbs, parentViewNameSet);
+                insertStmt.getTables(analyzer, tableMap, parentViewNameSet);
             }
-
-            lock(dbs);
+            List<Table> tables = Lists.newArrayList(tableMap.values());

Review comment:
       Are you sure this can get table list in order?
   I think it is more safe and clear to change `tableMap` to `tableList`, and 
sort the `tableList` explicitly.

##########
File path: fe/fe-core/src/main/java/org/apache/doris/master/ReportHandler.java
##########
@@ -14,6 +14,22 @@
 // KIND, either express or implied.  See the License for the
 // specific language governing permissions and limitations
 // under the License.
+// Licensed to the Apache Software Foundation (ASF) under one

Review comment:
       Why this license is different?

##########
File path: fe/fe-core/src/main/java/org/apache/doris/load/Load.java
##########
@@ -398,7 +398,7 @@ private void addLoadJob(LoadJob job, Database db) throws 
DdlException {
         }
 
         // check if table is in restore process
-        db.readLock();
+        readLock();

Review comment:
       I think we should hold the table's readLock before checking table' state

##########
File path: fe/fe-core/src/main/java/org/apache/doris/load/LoadChecker.java
##########
@@ -565,18 +568,14 @@ private void runOneQuorumFinishedDeleteJob(AsyncDeleteJob 
job) {
             load.removeDeleteJobAndSetState(job);
             return;
         }
-        db.readLock();
-        try {
-            // if the delete job is quorum finished, just set it to finished
-            job.clearTasks();
-            job.setState(DeleteState.FINISHED);
-            // log
-            Catalog.getCurrentCatalog().getEditLog().logFinishAsyncDelete(job);
-            load.removeDeleteJobAndSetState(job);
-            LOG.info("delete job {} finished", job.getJobId());
-        } finally {
-            db.readUnlock();
-        }
+
+        // if the delete job is quorum finished, just set it to finished
+        job.clearTasks();

Review comment:
       This part should be protected by lock

##########
File path: 
fe/fe-core/src/main/java/org/apache/doris/system/SystemInfoService.java
##########
@@ -894,18 +893,8 @@ public long getBackendReportVersion(long backendId) {
     public void updateBackendReportVersion(long backendId, long 
newReportVersion, long dbId) {
         AtomicLong atomicLong = null;
         if ((atomicLong = idToReportVersionRef.get(backendId)) != null) {
-            Database db = Catalog.getCurrentCatalog().getDb(dbId);
-            if (db != null) {
-                db.readLock();
-                try {
-                    atomicLong.set(newReportVersion);
-                    LOG.debug("update backend {} report version: {}, db: {}", 
backendId, newReportVersion, dbId);
-                } finally {
-                    db.readUnlock();
-                }
-            } else {
-                LOG.warn("failed to update backend report version, db {} does 
not exist", dbId);
-            }
+            atomicLong.set(newReportVersion);

Review comment:
       In original implementation, we use db locks to ensure mutual exclusion 
and order.
   So here we may still need to add table locks.

##########
File path: 
fe/fe-core/src/main/java/org/apache/doris/task/HadoopLoadPendingTask.java
##########
@@ -70,41 +70,41 @@ public HadoopLoadPendingTask(LoadJob job) {
 
     @Override
     protected void createEtlRequest() throws Exception {
-        db.readLock();
-        try {
-            EtlTaskConf taskConf = new EtlTaskConf();
-            // output path
-            taskConf.setOutputPath(getOutputPath());
-            // output file pattern
-            taskConf.setOutputFilePattern(job.getLabel() + 
".%(table)s.%(view)s.%(bucket)s");
-            // tables (partitions)
-            Map<String, EtlPartitionConf> etlPartitions = 
createEtlPartitions();
-            Preconditions.checkNotNull(etlPartitions);
-            taskConf.setEtlPartitions(etlPartitions);
+        EtlTaskConf taskConf = new EtlTaskConf();

Review comment:
       Table's lock should be held to call method like `createEtlPartitions()`

##########
File path: 
fe/fe-core/src/main/java/org/apache/doris/transaction/PublishVersionDaemon.java
##########
@@ -190,16 +190,18 @@ private void publishVersion() throws UserException {
                             LOG.warn("Database [{}] has been dropped.", 
transactionState.getDbId());
                             continue;
                         }
-                        db.readLock();
-                        try {
-                            for (int i = 0; i < 
transactionState.getTableIdList().size(); i++) {
-                                long tableId = 
transactionState.getTableIdList().get(i);
-                                Table table = db.getTable(tableId);
-                                if (table == null || table.getType() != 
Table.TableType.OLAP) {
-                                    LOG.warn("Table [{}] in database [{}] has 
been dropped.", tableId, db.getFullName());
-                                    continue;
-                                }
-                                OlapTable olapTable = (OlapTable) table;
+
+
+                        for (int i = 0; i < 
transactionState.getTableIdList().size(); i++) {
+                            long tableId = 
transactionState.getTableIdList().get(i);
+                            Table table = db.getTable(tableId);
+                            if (table == null || table.getType() != 
Table.TableType.OLAP) {
+                                LOG.warn("Table [{}] in database [{}] has been 
dropped.", tableId, db.getFullName());
+                                continue;
+                            }
+                            OlapTable olapTable = (OlapTable) table;
+                            olapTable.readLock();

Review comment:
       Is it more safe to lock all tables at once outside the for loop?

##########
File path: fe/fe-core/src/main/java/org/apache/doris/load/Load.java
##########
@@ -3229,19 +3234,19 @@ public void unprotectDelete(DeleteInfo deleteInfo, 
Database db) {
 
     public void replayFinishAsyncDeleteJob(AsyncDeleteJob deleteJob, Catalog 
catalog) {
         Database db = catalog.getDb(deleteJob.getDbId());
-        db.writeLock();
+        writeLock();

Review comment:
       All other place in Load.java should also be checked again.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org
For additional commands, e-mail: commits-h...@doris.apache.org

Reply via email to