This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.2
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.2 by this push:
new b9ec1ba7fa3 branch-4.2: [fix](fe) Use concurrent map for OlapTable
partition names to avoid ConcurrentModificationException #69166 (#69263)
b9ec1ba7fa3 is described below
commit b9ec1ba7fa3babaaf0ec7dd28986bc399e180ab2
Author: yujun <[email protected]>
AuthorDate: Tue Oct 20 16:20:57 2026 +0800
branch-4.2: [fix](fe) Use concurrent map for OlapTable partition names to
avoid ConcurrentModificationException #69166 (#69263)
cherry-pick: #69166
---
.../java/org/apache/doris/catalog/OlapTable.java | 7 +++++--
.../org/apache/doris/catalog/OlapTableTest.java | 21 +++++++++++++++++++++
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
index 4f6283d3979..6b2dd7fa1d3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/OlapTable.java
@@ -121,6 +121,7 @@ import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -188,9 +189,11 @@ public class OlapTable extends Table implements
MTMVRelatedTableIf, GsonPostProc
// to invalidate stale partition pruning metadata without reacting to
ordinary data writes. This is transient and
// rebuilt from zero after deserialization because prepared statement
cache is also in-memory.
private transient AtomicLong partitionTopologyVersion = new AtomicLong(0L);
- // handled in postgsonprocess
+ // handled in postgsonprocess. Sorted, and weakly consistent so that
lock-free readers
+ // (e.g. EXPLAIN plan rendering) never hit ConcurrentModificationException
while the table
+ // write lock holder adds/drops partitions.
@Getter
- protected Map<String, Partition> nameToPartition = Maps.newTreeMap();
+ protected Map<String, Partition> nameToPartition = new
ConcurrentSkipListMap<>();
@SerializedName(value = "di", alternate = {"distributionInfo"})
private DistributionInfo defaultDistributionInfo;
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/catalog/OlapTableTest.java
b/fe/fe-core/src/test/java/org/apache/doris/catalog/OlapTableTest.java
index b9340f1c8fd..9bc8cdad92b 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/catalog/OlapTableTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/catalog/OlapTableTest.java
@@ -51,6 +51,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -187,6 +188,26 @@ public class OlapTableTest {
Assert.assertEquals(version + 1,
olapTable.getPartitionTopologyVersion());
}
+ @Test
+ public void testPartitionNameMapToleratesConcurrentAdd() {
+ OlapTable olapTable = new OlapTable();
+ for (int i = 0; i < 3; i++) {
+ olapTable.addPartition(newPartitionForTopologyVersionTest(10 + i,
"p" + i));
+ }
+
+ // getPartitionNames() copies nameToPartition's keys without holding
any lock, while a writer
+ // holding the table write lock may add a partition at the same time,
so the iteration must be
+ // weakly consistent instead of fail fast.
+ Iterator<String> iterator =
olapTable.getNameToPartition().keySet().iterator();
+ Assert.assertTrue(iterator.hasNext());
+ iterator.next();
+ olapTable.addPartition(newPartitionForTopologyVersionTest(20, "p10"));
+ while (iterator.hasNext()) {
+ iterator.next();
+ }
+ Assert.assertEquals(4, olapTable.getPartitionNames().size());
+ }
+
private void addPartitionForTopologyVersionTest(OlapTable olapTable, long
partitionId, String partitionName) {
olapTable.getPartitionInfo().addPartition(partitionId, new
DataProperty(TStorageMedium.HDD),
new ReplicaAllocation((short) 1), false, true);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]