This is an automated email from the ASF dual-hosted git repository.
dataroaring pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new cbfe547981c [fix](database) Fix `insert into` race with `drop table`
(#55264)
cbfe547981c is described below
commit cbfe547981cc72ba26ec964a603f00927217cd91
Author: deardeng <[email protected]>
AuthorDate: Wed Aug 27 13:47:32 2025 +0800
[fix](database) Fix `insert into` race with `drop table` (#55264)
### What problem does this PR solve?
1. insert into hold table lock to get db lock in function
getUsedDataQuotaWithLock
2. drop table hold db lock to get table lock
3. deadlock
```
"mysql-nio-pool-371" #1548056 daemon prio=5 os_prio=0 cpu=39804.63ms
elapsed=6822.19s tid=0x00007fd16c224d60 nid=0x407f1 waiting on condition
[0x00007fcffccfa000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
- parking to wait for <0x00007fd42bd9b588> (a
java.util.concurrent.locks.ReentrantReadWriteLock$FairSync)
at
java.util.concurrent.locks.LockSupport.park([email protected]/LockSupport.java:211)
at
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire([email protected]/AbstractQueuedSynchronizer.java:715)
at
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireShared([email protected]/AbstractQueuedSynchronizer.java:1027)
at
java.util.concurrent.locks.ReentrantReadWriteLock$ReadLock.lock([email protected]/ReentrantReadWriteLock.java:738)
at
org.apache.doris.common.lock.MonitoredReentrantReadWriteLock$ReadLock.lock(MonitoredReentrantReadWriteLock.java:69)
at org.apache.doris.catalog.Database.readLock(Database.java:166)
at
org.apache.doris.catalog.Database.getUsedDataSize(Database.java:307)
at
org.apache.doris.catalog.Database.getUsedDataQuotaWithLock(Database.java:300)
at
org.apache.doris.transaction.DatabaseTransactionMgr.checkDatabaseDataQuota(DatabaseTransactionMgr.java:387)
at
org.apache.doris.transaction.DatabaseTransactionMgr.beginTransaction(DatabaseTransactionMgr.java:324)
at
org.apache.doris.transaction.GlobalTransactionMgr.beginTransaction(GlobalTransactionMgr.java:175)
at
org.apache.doris.transaction.GlobalTransactionMgr.beginTransaction(GlobalTransactionMgr.java:139)
at
org.apache.doris.nereids.trees.plans.commands.insert.OlapInsertExecutor.beginTransaction(OlapInsertExecutor.java:100)
at
org.apache.doris.nereids.trees.plans.commands.insert.InsertIntoTableCommand.initPlan(InsertIntoTableCommand.java:256)
at
org.apache.doris.nereids.trees.plans.commands.insert.InsertIntoTableCommand.initPlan(InsertIntoTableCommand.java:195)
at
org.apache.doris.nereids.trees.plans.commands.insert.InsertIntoTableCommand.runInternal(InsertIntoTableCommand.java:495)
at
org.apache.doris.nereids.trees.plans.commands.insert.InsertIntoTableCommand.run(InsertIntoTableCommand.java:179)
at
org.apache.doris.qe.StmtExecutor.executeByNereids(StmtExecutor.java:657)
at org.apache.doris.qe.StmtExecutor.execute(StmtExecutor.java:525)
at
org.apache.doris.qe.StmtExecutor.queryRetry(StmtExecutor.java:487)
at org.apache.doris.qe.StmtExecutor.execute(StmtExecutor.java:472)
at
org.apache.doris.qe.ConnectProcessor.executeQuery(ConnectProcessor.java:349)
at
org.apache.doris.qe.ConnectProcessor.handleQuery(ConnectProcessor.java:249)
at
org.apache.doris.qe.MysqlConnectProcessor.handleQuery(MysqlConnectProcessor.java:233)
at
org.apache.doris.qe.MysqlConnectProcessor.dispatch(MysqlConnectProcessor.java:261)
at
org.apache.doris.qe.MysqlConnectProcessor.processOnce(MysqlConnectProcessor.java:443)
at
org.apache.doris.mysql.ReadListener.lambda$handleEvent$0(ReadListener.java:52)
at
org.apache.doris.mysql.ReadListener$$Lambda$1480/0x0000000801baec60.run(Unknown
Source)
at
java.util.concurrent.ThreadPoolExecutor.runWorker([email protected]/ThreadPoolExecutor.java:1136)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run([email protected]/ThreadPoolExecutor.java:635)
at java.lang.Thread.run([email protected]/Thread.java:833)
Locked ownable synchronizers:
- <0x00007fd2e3bdcca0> (a
java.util.concurrent.ThreadPoolExecutor$Worker)
"mysql-nio-pool-367" #1548052 daemon prio=5 os_prio=0 cpu=34141.80ms
elapsed=6822.19s tid=0x00007fd16800f040 nid=0x407ed waiting on condition
[0x00007fcffd4fe000]
java.lang.Thread.State: WAITING (parking)
at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
- parking to wait for <0x00007fd42bd77428> (a
java.util.concurrent.locks.ReentrantReadWriteLock$FairSync)
at
java.util.concurrent.locks.LockSupport.park([email protected]/LockSupport.java:211)
at
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire([email protected]/AbstractQueuedSynchronizer.java:715)
at
java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire([email protected]/AbstractQueuedSynchronizer.java:938)
at
java.util.concurrent.locks.ReentrantReadWriteLock$WriteLock.lock([email protected]/ReentrantReadWriteLock.java:959)
at
org.apache.doris.common.lock.MonitoredReentrantReadWriteLock$WriteLock.lock(MonitoredReentrantReadWriteLock.java:106)
at org.apache.doris.catalog.Table.writeLock(Table.java:234)
at
org.apache.doris.datasource.InternalCatalog.dropTableInternal(InternalCatalog.java:953)
at
org.apache.doris.datasource.InternalCatalog.dropTable(InternalCatalog.java:921)
at org.apache.doris.catalog.Env.dropTable(Env.java:4791)
at
org.apache.doris.nereids.trees.plans.commands.DropTableCommand.run(DropTableCommand.java:79)
at
org.apache.doris.qe.StmtExecutor.executeByNereids(StmtExecutor.java:657)
at org.apache.doris.qe.StmtExecutor.execute(StmtExecutor.java:525)
at
org.apache.doris.qe.StmtExecutor.queryRetry(StmtExecutor.java:487)
at org.apache.doris.qe.StmtExecutor.execute(StmtExecutor.java:472)
at
org.apache.doris.qe.ConnectProcessor.executeQuery(ConnectProcessor.java:349)
at
org.apache.doris.qe.ConnectProcessor.handleQuery(ConnectProcessor.java:249)
at
org.apache.doris.qe.MysqlConnectProcessor.handleQuery(MysqlConnectProcessor.java:233)
at
org.apache.doris.qe.MysqlConnectProcessor.dispatch(MysqlConnectProcessor.java:261)
at
org.apache.doris.qe.MysqlConnectProcessor.processOnce(MysqlConnectProcessor.java:443)
at
org.apache.doris.mysql.ReadListener.lambda$handleEvent$0(ReadListener.java:52)
at
org.apache.doris.mysql.ReadListener$$Lambda$1480/0x0000000801baec60.run(Unknown
Source)
at
java.util.concurrent.ThreadPoolExecutor.runWorker([email protected]/ThreadPoolExecutor.java:1136)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run([email protected]/ThreadPoolExecutor.java:635)
at java.lang.Thread.run([email protected]/Thread.java:833)
Locked ownable synchronizers:
- <0x00007fd2e3b8fc08> (a
java.util.concurrent.ThreadPoolExecutor$Worker)
- <0x00007fd42bd9b588> (a
java.util.concurrent.locks.ReentrantReadWriteLock$FairSync)
```
Issue Number: close #xxx
Related PR: #xxx
Problem Summary:
### Release note
None
### Check List (For Author)
- Test <!-- At least one of them must be included. -->
- [ ] Regression test
- [ ] Unit Test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [x] Previous test can cover this change.
- [ ] No code files have been changed.
- [ ] Other reason <!-- Add your reason? -->
- Behavior changed:
- [x] No.
- [ ] Yes. <!-- Explain the behavior change -->
- Does this need documentation?
- [x] No.
- [ ] Yes. <!-- Add document PR link here. eg:
https://github.com/apache/doris-website/pull/1214 -->
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label <!-- Add branch pick label that this PR
should merge into -->
---
.../src/main/java/org/apache/doris/catalog/Database.java | 12 +++---------
.../main/java/org/apache/doris/common/proc/DbsProcDir.java | 2 +-
.../java/org/apache/doris/datasource/InternalCatalog.java | 2 +-
.../org/apache/doris/transaction/DatabaseTransactionMgr.java | 2 +-
.../doris/transaction/DbUsedDataQuotaInfoCollector.java | 2 +-
5 files changed, 7 insertions(+), 13 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Database.java
index a213dc4e595..897e002f3cd 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
@@ -301,20 +301,14 @@ public class Database extends MetaObject implements
Writable, DatabaseIf<Table>,
}
}
- public long getUsedDataQuotaWithLock() {
+ public long getUsedDataQuota() {
return getUsedDataSize().first;
}
public Pair<Long, Long> getUsedDataSize() {
long usedDataSize = 0;
long usedRemoteDataSize = 0;
- List<Table> tables = new ArrayList<>();
- readLock();
- try {
- tables.addAll(this.idToTable.values());
- } finally {
- readUnlock();
- }
+ List<Table> tables = new ArrayList<>(this.idToTable.values());
for (Table table : tables) {
if (!table.isManagedTable()) {
@@ -356,7 +350,7 @@ public class Database extends MetaObject implements
Writable, DatabaseIf<Table>,
Pair<Double, String> quotaUnitPair =
DebugUtil.getByteUint(dataQuotaBytes);
String readableQuota =
DebugUtil.DECIMAL_FORMAT_SCALE_3.format(quotaUnitPair.first) + " "
+ quotaUnitPair.second;
- long usedDataQuota = getUsedDataQuotaWithLock();
+ long usedDataQuota = getUsedDataQuota();
long leftDataQuota = Math.max(dataQuotaBytes - usedDataQuota, 0);
Pair<Double, String> leftQuotaUnitPair =
DebugUtil.getByteUint(leftDataQuota);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/common/proc/DbsProcDir.java
b/fe/fe-core/src/main/java/org/apache/doris/common/proc/DbsProcDir.java
index 16672f83417..17c38c4cf39 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/common/proc/DbsProcDir.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/common/proc/DbsProcDir.java
@@ -121,7 +121,7 @@ public class DbsProcDir implements ProcDirInterface {
dbInfo.add(dbName);
dbInfo.add(tableNum);
- long usedDataQuota = (db instanceof Database) ? ((Database)
db).getUsedDataQuotaWithLock() : 0;
+ long usedDataQuota = (db instanceof Database) ? ((Database)
db).getUsedDataQuota() : 0;
long dataQuota = (db instanceof Database) ? ((Database)
db).getDataQuota() : 0;
String readableUsedQuota =
DebugUtil.printByteWithUnit(usedDataQuota);
String readableQuota = DebugUtil.printByteWithUnit(dataQuota);
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
index 38c6b2c0862..dba12b7b4e9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/datasource/InternalCatalog.java
@@ -5038,7 +5038,7 @@ public class InternalCatalog implements
CatalogIf<Database> {
public Map<String, Long> getUsedDataQuota() {
Map<String, Long> dbToDataSize = new TreeMap<>();
for (Database db : this.idToDb.values()) {
- dbToDataSize.put(db.getFullName(), db.getUsedDataQuotaWithLock());
+ dbToDataSize.put(db.getFullName(), db.getUsedDataQuota());
}
return dbToDataSize;
}
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 c1d8018e616..6263b48fabe 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
@@ -384,7 +384,7 @@ public class DatabaseTransactionMgr {
Database db = env.getInternalCatalog().getDbOrMetaException(dbId);
if (usedQuotaDataBytes == -1) {
- usedQuotaDataBytes = db.getUsedDataQuotaWithLock();
+ usedQuotaDataBytes = db.getUsedDataQuota();
}
long dataQuotaBytes = db.getDataQuota();
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/transaction/DbUsedDataQuotaInfoCollector.java
b/fe/fe-core/src/main/java/org/apache/doris/transaction/DbUsedDataQuotaInfoCollector.java
index f03da231b9b..3a85c75d284 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/transaction/DbUsedDataQuotaInfoCollector.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/transaction/DbUsedDataQuotaInfoCollector.java
@@ -55,7 +55,7 @@ public class DbUsedDataQuotaInfoCollector extends
MasterDaemon {
continue;
}
try {
- long usedDataQuotaBytes = db.getUsedDataQuotaWithLock();
+ long usedDataQuotaBytes = db.getUsedDataQuota();
globalTransactionMgr.updateDatabaseUsedQuotaData(dbId,
usedDataQuotaBytes);
if (LOG.isDebugEnabled()) {
LOG.debug("Update database[{}] used data quota bytes :
{}.", db.getFullName(), usedDataQuotaBytes);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]