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 7d83f416a1a [fix](cloud)Fix `create dynamic table` race with `insert
overwrite` (#59489)
7d83f416a1a is described below
commit 7d83f416a1a0e42ae224e0ca091d7abdf7f25cb1
Author: deardeng <[email protected]>
AuthorDate: Mon Jan 5 13:30:48 2026 +0800
[fix](cloud)Fix `create dynamic table` race with `insert overwrite` (#59489)
### What problem does this PR solve?
1. Thread 1 executed a DROP TABLE operation, followed by a CREATE TABLE
operation, initializing a dynamic partition (Partition A) in memory.
2. Due to an optimization in the cloud, batch partition edit logs were
attempted; however, the edit log for Partition A was not yet
synchronized to the followers.
3. Thread 2 began an INSERT INTO ... OVERWRITE PARTITION (*) operation,
identifying Partition A in memory and writing a replace partition edit
log.
4. In follower, the replay thread attempted to replay the replace
partition edit log but found a dependency on Partition A, which was
absent from memory, resulting in an exception and subsequent
termination.
Fix
```
2025-12-30 16:10:42,774 ERROR (replayer|123) [EditLog.loadJournal():1445]
replay Operation Type 210, log id: 1910
java.lang.NullPointerException
at
com.google.common.base.Preconditions.checkNotNull(Preconditions.java:906)
at
org.apache.doris.catalog.OlapTable.checkPartition(OlapTable.java:2835)
at
org.apache.doris.catalog.OlapTable.replaceTempPartitions(OlapTable.java:2799)
at
org.apache.doris.catalog.Env.replayReplaceTempPartition(Env.java:6750)
at org.apache.doris.persist.EditLog.loadJournal(EditLog.java:986)
at org.apache.doris.catalog.Env.replayJournal(Env.java:3100)
at org.apache.doris.catalog.Env$4.runOneCycle(Env.java:2862)
at org.apache.doris.common.util.Daemon.run(Daemon.java:119)
2025-12-30 16:10:42,775 INFO (Thread-0|32) [DorisFE.lambda$start$0():159]
Received shutdown signal, starting graceful shutdown...
2025-12-30 16:10:42,776 INFO (Thread-0|32) [DorisFE.gracefulShutdown():639]
graceful shutdown finished
```
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. -->
- [x] 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.
- [ ] 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 -->
---
.../main/java/org/apache/doris/alter/Alter.java | 2 +-
.../main/java/org/apache/doris/catalog/Env.java | 13 +--
.../doris/clone/DynamicPartitionScheduler.java | 74 +++++++++++------
.../apache/doris/datasource/InternalCatalog.java | 29 +++----
.../org/apache/doris/mtmv/MTMVPartitionUtil.java | 2 +-
.../java/org/apache/doris/persist/EditLog.java | 22 +++++-
.../apache/doris/service/FrontendServiceImpl.java | 2 +-
.../different_serialize.groovy} | 2 +-
...eate_partition_and_insert_overwrite_race.groovy | 92 ++++++++++++++++++++++
9 files changed, 189 insertions(+), 49 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 ab1bf1be369..be11cbe7340 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
@@ -678,7 +678,7 @@ public class Alter {
DynamicPartitionUtil.checkAlterAllowed(
(OlapTable) db.getTableOrMetaException(tableName,
TableType.OLAP));
}
- Env.getCurrentEnv().addPartition(db, tableName,
(AddPartitionOp) alterOp, false, 0, true);
+ Env.getCurrentEnv().addPartition(db, tableName,
(AddPartitionOp) alterOp, false, 0, true, null);
} else if (alterOp instanceof AddPartitionLikeOp) {
if (!((AddPartitionLikeOp) alterOp).getTempPartition()) {
DynamicPartitionUtil.checkAlterAllowed(
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
index 95f66f14a4d..6dda1e152b9 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java
@@ -3480,14 +3480,17 @@ public class Env {
* @param isCreateTable this call is for creating table
* @param generatedPartitionId the preset partition id for the partition
to add
* @param writeEditLog whether to write an edit log for this addition
- * @return PartitionPersistInfo to be written to editlog. It may be null
if no partitions added.
+ * @batchPartitions output parameter, used to batch write edit log outside
this function, can be null.
+ * first is editlog PartitionPersistInfo, second is the added Partition
* @throws DdlException
*/
- public PartitionPersistInfo addPartition(Database db, String tableName,
AddPartitionOp addPartitionOp,
+ public void addPartition(Database db, String tableName, AddPartitionOp
addPartitionOp,
boolean isCreateTable, long
generatedPartitionId,
- boolean writeEditLog) throws
DdlException {
- return getInternalCatalog().addPartition(db, tableName, addPartitionOp,
- isCreateTable, generatedPartitionId, writeEditLog);
+ boolean writeEditLog,
+ List<Pair<PartitionPersistInfo,
Partition>> batchPartitions)
+ throws DdlException {
+ getInternalCatalog().addPartition(db, tableName, addPartitionOp,
+ isCreateTable, generatedPartitionId, writeEditLog,
batchPartitions);
}
public void addMultiPartitions(Database db, String tableName,
AlterMultiPartitionOp multiPartitionOp)
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 f77ec517667..495e8f9cdec 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
@@ -774,7 +774,7 @@ public class DynamicPartitionScheduler extends MasterDaemon
{
cloudBatchBeforeCreatePartitions(executeFirstTime,
addPartitionOps, olapTable, indexIds,
db, tableName, generatedPartitionIds);
- List<PartitionPersistInfo> partsInfo = new ArrayList<>();
+ List<Pair<PartitionPersistInfo, Partition>> batchPartsInfo =
new ArrayList<>();
for (int i = 0; i < addPartitionOps.size(); i++) {
try {
boolean needWriteEditLog = true;
@@ -783,15 +783,10 @@ public class DynamicPartitionScheduler extends
MasterDaemon {
if (Config.isCloudMode()) {
needWriteEditLog = !executeFirstTime;
}
- PartitionPersistInfo info =
- Env.getCurrentEnv().addPartition(db,
tableName, addPartitionOps.get(i),
+ Env.getCurrentEnv().addPartition(db, tableName,
addPartitionOps.get(i),
executeFirstTime,
executeFirstTime && Config.isCloudMode() ?
generatedPartitionIds.get(i) : 0,
- needWriteEditLog);
- if (info == null) {
- throw new Exception("null persisted partition
returned");
- }
- partsInfo.add(info);
+ needWriteEditLog, batchPartsInfo);
clearCreatePartitionFailedMsg(olapTable.getId());
} catch (Exception e) {
recordCreatePartitionFailedMsg(db.getFullName(),
tableName, e.getMessage(), olapTable.getId());
@@ -802,7 +797,7 @@ public class DynamicPartitionScheduler extends MasterDaemon
{
}
}
}
- cloudBatchAfterCreatePartitions(executeFirstTime, partsInfo,
+ cloudBatchAfterCreatePartitions(executeFirstTime,
batchPartsInfo,
addPartitionOps, db, olapTable, indexIds, tableName);
// ATTN: Breaking up dynamic partition table scheduling,
consuming peak CPU consumption
@@ -822,15 +817,16 @@ public class DynamicPartitionScheduler extends
MasterDaemon {
}
}
- private void cloudBatchAfterCreatePartitions(boolean executeFirstTime,
List<PartitionPersistInfo> partsInfo,
-
ArrayList<AddPartitionOp> addPartitionOps, Database db,
- OlapTable olapTable,
List<Long> indexIds,
- String tableName)
throws DdlException {
+ private void cloudBatchAfterCreatePartitions(boolean executeFirstTime,
+
List<Pair<PartitionPersistInfo, Partition>> batchPartsInfo,
+ ArrayList<AddPartitionOp>
addPartitionOps, Database db,
+ OlapTable olapTable,
List<Long> indexIds,
+ String tableName) throws
DdlException {
if (Config.isNotCloudMode()) {
return;
}
- List<Long> succeedPartitionIds =
partsInfo.stream().map(partitionPersistInfo
- ->
partitionPersistInfo.getPartition().getId()).collect(Collectors.toList());
+ List<Long> succeedPartitionIds =
batchPartsInfo.stream().map(partitionInfo
+ ->
partitionInfo.first.getPartition().getId()).collect(Collectors.toList());
if (!executeFirstTime || addPartitionOps.isEmpty()) {
LOG.info("cloud commit rpc in batch, {}-{}", !executeFirstTime,
addPartitionOps.size());
return;
@@ -847,7 +843,7 @@ public class DynamicPartitionScheduler extends MasterDaemon
{
succeedPartitionIds, indexIds, true /* isCreateTable */,
false /* isBatchCommit */);
LOG.info("begin write edit log to add partitions in batch, "
+ "numPartitions: {}, db: {}, table: {}, tableId: {}",
- partsInfo.size(), db.getFullName(), tableName,
olapTable.getId());
+ batchPartsInfo.size(), db.getFullName(), tableName,
olapTable.getId());
// ATTN: here, edit log must after commit cloud partition,
// prevent commit RPC failure from causing data loss
if
(DebugPointUtil.isEnable("FE.DynamicPartitionScheduler.before.logEditPartitions"))
{
@@ -855,20 +851,48 @@ public class DynamicPartitionScheduler extends
MasterDaemon {
// committed, but not log edit
throw new Exception("debug point
FE.DynamicPartitionScheduler.before.commitCloudPartition");
}
- for (int i = 0; i < partsInfo.size(); i++) {
-
Env.getCurrentEnv().getEditLog().logAddPartition(partsInfo.get(i));
- if
(DebugPointUtil.isEnable("FE.DynamicPartitionScheduler.in.logEditPartitions")) {
- if (i == partsInfo.size() / 2) {
- LOG.info("debug point
FE.DynamicPartitionScheduler.in.logEditPartitions, throw e");
- // committed, but log some edit, others failed
- throw new Exception("debug point
FE.DynamicPartitionScheduler"
- + ".in.commitCloudPartition");
+
+ for (int i = 0; i < batchPartsInfo.size(); i++) {
+ // get table write lock to add partition, edit log and modify
table state must be atomic
+ olapTable.writeLockOrDdlException();
+ try {
+ boolean isTempPartition =
addPartitionOps.get(i).isTempPartition();
+ Partition toAddPartition = batchPartsInfo.get(i).second;
+ String partitionName = toAddPartition.getName();
+ // ATTN: Check here to see if the newly created dynamic
+ // partition has already been added by another process.
+ // If it has, do not add this dynamic partition again,
+ // and call `onErasePartition` to clean up any remaining
information.
+ Partition checkIsAdded =
olapTable.getPartition(partitionName, isTempPartition);
+ if (checkIsAdded != null) {
+ LOG.warn("dynamic partition has been added, skip it. "
+ + "db: {}, table: {}, partition: {}, tableId:
{}",
+ db.getFullName(), tableName, partitionName,
olapTable.getId());
+ Env.getCurrentEnv().onErasePartition(toAddPartition);
+ continue;
+ }
+ if (isTempPartition) {
+ olapTable.addTempPartition(toAddPartition);
+ } else {
+ olapTable.addPartition(toAddPartition);
}
+
+
Env.getCurrentEnv().getEditLog().logAddPartition(batchPartsInfo.get(i).first);
+ if
(DebugPointUtil.isEnable("FE.DynamicPartitionScheduler.in.logEditPartitions")) {
+ if (i == batchPartsInfo.size() / 2) {
+ LOG.info("debug point
FE.DynamicPartitionScheduler.in.logEditPartitions, throw e");
+ // committed, but log some edit, others failed
+ throw new Exception("debug point
FE.DynamicPartitionScheduler"
+ + ".in.commitCloudPartition");
+ }
+ }
+ } finally {
+ olapTable.writeUnlock();
}
}
LOG.info("finish write edit log to add partitions in batch, "
+ "numPartitions: {}, db: {}, table: {}, tableId: {}",
- partsInfo.size(), db.getFullName(), tableName,
olapTable.getId());
+ batchPartsInfo.size(), db.getFullName(), tableName,
olapTable.getId());
} catch (Exception e) {
LOG.warn("cloud in commit step, dbName {}, tableName {}, tableId
{} exception {}",
db.getFullName(), tableName, olapTable.getId(),
e.getMessage());
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 454063d4f92..6302dbc9d18 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
@@ -1354,7 +1354,7 @@ public class InternalCatalog implements
CatalogIf<Database> {
} finally {
table.readUnlock();
}
- addPartition(db, tableName, addPartitionOp, false, 0, true);
+ addPartition(db, tableName, addPartitionOp, false, 0, true, null);
} catch (UserException e) {
throw new DdlException("Failed to ADD PARTITION " +
addPartitionLikeOp.getPartitionName()
@@ -1443,9 +1443,11 @@ public class InternalCatalog implements
CatalogIf<Database> {
}
}
- public PartitionPersistInfo addPartition(Database db, String tableName,
AddPartitionOp addPartitionOp,
+ public void addPartition(Database db, String tableName, AddPartitionOp
addPartitionOp,
boolean isCreateTable, long
generatedPartitionId,
- boolean writeEditLog) throws
DdlException {
+ boolean writeEditLog,
+ List<Pair<PartitionPersistInfo,
Partition>> batchPartitions)
+ throws DdlException {
// in cloud mode, isCreateTable == true, create dynamic partition use,
so partitionId must have been generated.
// isCreateTable == false, other case, partitionId generate in below,
must be set 0
if (!FeConstants.runningUnitTest && Config.isCloudMode()
@@ -1474,7 +1476,7 @@ public class InternalCatalog implements
CatalogIf<Database> {
if (singlePartitionDesc.isSetIfNotExists()) {
LOG.info("table[{}] add partition[{}] which already
exists", olapTable.getName(), partitionName);
if
(!DebugPointUtil.isEnable("InternalCatalog.addPartition.noCheckExists")) {
- return null;
+ return;
}
} else {
ErrorReport.reportDdlException(ErrorCode.ERR_SAME_NAME_PARTITION,
partitionName);
@@ -1641,7 +1643,7 @@ public class InternalCatalog implements
CatalogIf<Database> {
db, tableName, olapTable, partitionName, singlePartitionDesc);
if (ownerFutureOr.isErr()) {
if (ownerFutureOr.unwrapErr() == null) {
- return null;
+ return;
} else {
throw ownerFutureOr.unwrapErr();
}
@@ -1697,7 +1699,7 @@ public class InternalCatalog implements
CatalogIf<Database> {
LOG.info("table[{}] add partition[{}] which already
exists", olapTable.getName(), partitionName);
if (singlePartitionDesc.isSetIfNotExists()) {
failedCleanCallback.run();
- return null;
+ return;
} else {
ErrorReport.reportDdlException(ErrorCode.ERR_SAME_NAME_PARTITION,
partitionName);
}
@@ -1755,12 +1757,6 @@ public class InternalCatalog implements
CatalogIf<Database> {
// update partition info
partitionInfo.handleNewSinglePartitionDesc(singlePartitionDesc, partitionId,
isTempPartition);
- if (isTempPartition) {
- olapTable.addTempPartition(partition);
- } else {
- olapTable.addPartition(partition);
- }
-
// log
PartitionPersistInfo info = null;
if (partitionInfo.getType() == PartitionType.RANGE) {
@@ -1786,11 +1782,16 @@ public class InternalCatalog implements
CatalogIf<Database> {
}
if (writeEditLog) {
Env.getCurrentEnv().getEditLog().logAddPartition(info);
+ if (isTempPartition) {
+ olapTable.addTempPartition(partition);
+ } else {
+ olapTable.addPartition(partition);
+ }
LOG.info("succeed in creating partition[{}], temp: {}",
partitionId, isTempPartition);
} else {
+ batchPartitions.add(Pair.of(info, partition));
LOG.info("postpone creating partition[{}], temp: {}",
partitionId, isTempPartition);
}
- return info;
} finally {
olapTable.writeUnlock();
}
@@ -1837,7 +1838,7 @@ public class InternalCatalog implements
CatalogIf<Database> {
AddPartitionOp addPartitionOp = new AddPartitionOp(
singlePartitionDesc.translateToPartitionDefinition(), null,
multiPartitionOp.getProperties(), false);
- addPartition(db, tableName, addPartitionOp, false, 0, true);
+ addPartition(db, tableName, addPartitionOp, false, 0, true, null);
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVPartitionUtil.java
b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVPartitionUtil.java
index eee02b62a98..924f51ce064 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVPartitionUtil.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mtmv/MTMVPartitionUtil.java
@@ -405,7 +405,7 @@ public class MTMVPartitionUtil {
mtmv.getDefaultDistributionInfo().toDistributionDesc().toDistributionDescriptor(),
partitionProperties, false);
Env.getCurrentEnv().addPartition((Database) mtmv.getDatabase(),
mtmv.getName(), addPartitionClause,
- false, 0, true);
+ false, 0, true, null);
}
/**
diff --git a/fe/fe-core/src/main/java/org/apache/doris/persist/EditLog.java
b/fe/fe-core/src/main/java/org/apache/doris/persist/EditLog.java
index 0102d1a32a7..4f126fcf214 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/persist/EditLog.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/persist/EditLog.java
@@ -1666,7 +1666,21 @@ public class EditLog {
}
public long logAddPartition(PartitionPersistInfo info) {
+ if (DebugPointUtil.isEnable("FE.logAddPartition.slow")) {
+ DebugPointUtil.DebugPoint debugPoint =
DebugPointUtil.getDebugPoint("FE.logAddPartition.slow");
+ String pName = debugPoint.param("pName", "");
+ if (info.getPartition().getName().equals(pName)) {
+ int sleepMs = debugPoint.param("sleep", 1000);
+ LOG.info("logAddPartition debug point hit, pName {}, sleep {}
s", pName, sleepMs);
+ try {
+ Thread.sleep(sleepMs);
+ } catch (InterruptedException e) {
+ LOG.warn("sleep interrupted", e);
+ }
+ }
+ }
long logId = logEdit(OperationType.OP_ADD_PARTITION, info);
+ LOG.info("log add partition, logId:{}, info: {}", logId,
info.toJson());
AddPartitionRecord record = new AddPartitionRecord(logId, info);
Env.getCurrentEnv().getBinlogManager().addAddPartitionRecord(record);
return logId;
@@ -1674,6 +1688,7 @@ public class EditLog {
public long logDropPartition(DropPartitionInfo info) {
long logId = logEdit(OperationType.OP_DROP_PARTITION, info);
+ LOG.info("log drop partition, logId:{}, info: {}", logId,
info.toJson());
Env.getCurrentEnv().getBinlogManager().addDropPartitionRecord(info,
logId);
return logId;
}
@@ -1684,6 +1699,7 @@ public class EditLog {
public void logRecoverPartition(RecoverInfo info) {
long logId = logEdit(OperationType.OP_RECOVER_PARTITION, info);
+ LOG.info("log recover partition, logId:{}, info: {}", logId,
info.toJson());
Env.getCurrentEnv().getBinlogManager().addRecoverTableRecord(info,
logId);
}
@@ -1702,6 +1718,7 @@ public class EditLog {
public void logDropTable(DropInfo info) {
long logId = logEdit(OperationType.OP_DROP_TABLE, info);
+ LOG.info("log drop table, logId : {}, infos: {}", logId, info);
if (Strings.isNullOrEmpty(info.getCtl()) ||
info.getCtl().equals(InternalCatalog.INTERNAL_CATALOG_NAME)) {
DropTableRecord record = new DropTableRecord(logId, info);
Env.getCurrentEnv().getBinlogManager().addDropTableRecord(record);
@@ -1714,11 +1731,13 @@ public class EditLog {
public void logRecoverTable(RecoverInfo info) {
long logId = logEdit(OperationType.OP_RECOVER_TABLE, info);
+ LOG.info("log recover table, logId : {}, infos: {}", logId, info);
Env.getCurrentEnv().getBinlogManager().addRecoverTableRecord(info,
logId);
}
public void logDropRollup(DropInfo info) {
long logId = logEdit(OperationType.OP_DROP_ROLLUP, info);
+ LOG.info("log drop rollup, logId : {}, infos: {}", logId, info);
Env.getCurrentEnv().getBinlogManager().addDropRollup(info, logId);
}
@@ -1835,7 +1854,8 @@ public class EditLog {
}
public void logDatabaseRename(DatabaseInfo databaseInfo) {
- logEdit(OperationType.OP_RENAME_DB, databaseInfo);
+ long logId = logEdit(OperationType.OP_RENAME_DB, databaseInfo);
+ LOG.info("log database rename, logId : {}, infos: {}", logId,
databaseInfo);
}
public void logTableRename(TableInfo tableInfo) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
index 3a1f56c7672..1720a27001a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
@@ -3631,7 +3631,7 @@ public class FrontendServiceImpl implements
FrontendService.Iface {
for (AddPartitionOp addPartitionOp : addPartitionClauseMap.values()) {
try {
// here maybe check and limit created partitions num
- Env.getCurrentEnv().addPartition(db, olapTable.getName(),
addPartitionOp, false, 0, true);
+ Env.getCurrentEnv().addPartition(db, olapTable.getName(),
addPartitionOp, false, 0, true, null);
} catch (DdlException e) {
LOG.warn(e);
errorStatus.setErrorMsgs(
diff --git
a/regression-test/suites/cloud_p0/diffrent_serialize/diffrent_serialize.groovy
b/regression-test/suites/cloud_p0/different_serialize/different_serialize.groovy
similarity index 99%
rename from
regression-test/suites/cloud_p0/diffrent_serialize/diffrent_serialize.groovy
rename to
regression-test/suites/cloud_p0/different_serialize/different_serialize.groovy
index 682a8fff9ad..9433c97e130 100644
---
a/regression-test/suites/cloud_p0/diffrent_serialize/diffrent_serialize.groovy
+++
b/regression-test/suites/cloud_p0/different_serialize/different_serialize.groovy
@@ -17,7 +17,7 @@
import org.codehaus.groovy.runtime.IOGroovyMethods
-suite ("diffrent_serialize_cloud") {
+suite ("different_serialize_cloud") {
sql """ DROP TABLE IF EXISTS d_table; """
diff --git
a/regression-test/suites/cloud_p0/partition/test_create_partition_and_insert_overwrite_race.groovy
b/regression-test/suites/cloud_p0/partition/test_create_partition_and_insert_overwrite_race.groovy
new file mode 100644
index 00000000000..58c259db816
--- /dev/null
+++
b/regression-test/suites/cloud_p0/partition/test_create_partition_and_insert_overwrite_race.groovy
@@ -0,0 +1,92 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+import com.mysql.cj.jdbc.StatementImpl
+import org.apache.doris.regression.suite.ClusterOptions
+import org.apache.doris.regression.util.NodeType
+import org.apache.doris.regression.suite.SuiteCluster
+
+suite("test_create_partition_and_insert_overwrite_race", 'p0, docker') {
+ if (!isCloudMode()) {
+ return
+ }
+ def options = new ClusterOptions()
+ options.enableDebugPoints()
+ // one master, one observer
+ options.setFeNum(2)
+ options.feConfigs.add('sys_log_verbose_modules=org')
+ options.setBeNum(3)
+ options.cloudMode = true
+
+ // 1. connect to observer
+ options.connectToFollower = true
+ docker(options) {
+ sql """set enable_sql_cache=false"""
+ def tbl = 'test_create_partition_and_insert_overwrite_race_tbl'
+ def tbl2 = 'test_create_partition_and_insert_overwrite_race_tbl2'
+ def createTableSql = { String tableName ->
+ sql """
+ CREATE TABLE ${tableName} (
+ order_id BIGINT,
+ create_dt datetime,
+ username VARCHAR(20)
+ )
+ DUPLICATE KEY(order_id)
+ PARTITION BY RANGE(create_dt) ()
+ DISTRIBUTED BY HASH(order_id) BUCKETS 10
+ PROPERTIES(
+ "dynamic_partition.enable" = "true",
+ "dynamic_partition.time_unit" = "DAY",
+ "dynamic_partition.start" = "-5",
+ "dynamic_partition.end" = "5",
+ "dynamic_partition.prefix" = "p",
+ "dynamic_partition.create_history_partition" = "true"
+ );
+ """
+ }
+
+ createTableSql(tbl)
+ createTableSql(tbl2)
+
+ // Generate insert statements with dates: current date -2, -1, 0, +1,
+2 days
+ def now = new Date()
+ def dateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd")
+ for (def i = -2; i <= 2; i++) {
+ def targetDate = new Date(now.time + i * 24 * 60 * 60 * 1000L)
+ def dateStr = dateFormat.format(targetDate)
+ def hour = String.format("%02d", Math.abs(i) + 1)
+ def insertDate = "${dateStr} ${hour}:00:00"
+ sql """insert into ${tbl2} values (${i + 3}, '${insertDate}',
'test')"""
+ }
+
+ sql """DROP TABLE ${tbl}"""
+ def partitionNameFormat = new java.text.SimpleDateFormat("yyyyMMdd")
+ def currentPartitionName = "p" + partitionNameFormat.format(now)
+ cluster.injectDebugPoints(NodeType.FE,
['FE.logAddPartition.slow':[pName:currentPartitionName, sleep:50 * 1000]])
+ def futrue = thread {
+ for (def i = 0; i < 55; i++) {
+ try_sql """INSERT OVERWRITE TABLE ${tbl} partition(*) select *
from ${tbl2}"""
+ sleep(1 * 1000)
+ cluster.checkFeIsAlive(2, true)
+ }
+ }
+ def future1 = thread {
+ createTableSql(tbl)
+ }
+ futrue.get()
+ future1.get()
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]