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

jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 436524f0d4f Fix the problem that writes duplicate TConsensusGroupId 
when repairing data partition table (#17416)
436524f0d4f is described below

commit 436524f0d4ffe06df51330a765d2e61c1068a956
Author: libo <[email protected]>
AuthorDate: Thu Apr 2 08:45:12 2026 +0800

    Fix the problem that writes duplicate TConsensusGroupId when repairing data 
partition table (#17416)
---
 .../DataPartitionTableIntegrityCheckProcedure.java   | 20 ++++++++++++--------
 .../commons/partition/SeriesPartitionTable.java      | 13 ++++++++++++-
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/partition/DataPartitionTableIntegrityCheckProcedure.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/partition/DataPartitionTableIntegrityCheckProcedure.java
index a0e17794e7a..0970c3ac057 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/partition/DataPartitionTableIntegrityCheckProcedure.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/partition/DataPartitionTableIntegrityCheckProcedure.java
@@ -332,6 +332,7 @@ public class DataPartitionTableIntegrityCheckProcedure
 
       Map<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TConsensusGroupId>>>
           seriesPartitionMap = localDataPartitionTable.get(database);
+      long localEarliestSlotStartTime = Long.MAX_VALUE;
       for (Map.Entry<TSeriesPartitionSlot, Map<TTimePartitionSlot, 
List<TConsensusGroupId>>>
           seriesPartitionEntry : seriesPartitionMap.entrySet()) {
         Map<TTimePartitionSlot, List<TConsensusGroupId>> 
tTimePartitionSlotListMap =
@@ -346,14 +347,17 @@ public class DataPartitionTableIntegrityCheckProcedure
                 
.min(Comparator.comparingLong(TTimePartitionSlot::getStartTime))
                 .orElse(null);
 
-        if (localEarliestSlot.getStartTime()
-            > TimePartitionUtils.getStartTimeByPartitionId(earliestTimeslot)) {
-          databasesWithLostDataPartition.add(database);
-          LOG.warn(
-              "[DataPartitionIntegrity] Database {} has lost timeslot {} in 
its data table partition, and this issue needs to be repaired",
-              database,
-              earliestTimeslot);
-        }
+        localEarliestSlotStartTime =
+            Math.min(localEarliestSlotStartTime, 
localEarliestSlot.getStartTime());
+      }
+
+      if (localEarliestSlotStartTime
+          > TimePartitionUtils.getStartTimeByPartitionId(earliestTimeslot)) {
+        databasesWithLostDataPartition.add(database);
+        LOG.warn(
+            "[DataPartitionIntegrity] Database {} has lost timeslot {} in its 
data table partition, and this issue needs to be repaired",
+            database,
+            earliestTimeslot);
       }
     }
 
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SeriesPartitionTable.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SeriesPartitionTable.java
index 915e3df4e32..da8952051e5 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SeriesPartitionTable.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/partition/SeriesPartitionTable.java
@@ -37,10 +37,12 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.Vector;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentSkipListMap;
@@ -280,7 +282,16 @@ public class SeriesPartitionTable {
     if (sourceMap == null) return;
     sourceMap.seriesPartitionMap.forEach(
         (timeSlot, groups) -> {
-          this.seriesPartitionMap.computeIfAbsent(timeSlot, k -> new 
ArrayList<>()).addAll(groups);
+          List<TConsensusGroupId> groupList =
+              this.seriesPartitionMap.computeIfAbsent(timeSlot, k -> new 
ArrayList<>());
+          synchronized (groupList) {
+            Set<TConsensusGroupId> groupSet = new HashSet<>(groupList);
+            for (TConsensusGroupId groupId : groups) {
+              if (!groupSet.contains(groupId)) {
+                groupList.add(groupId);
+              }
+            }
+          }
         });
   }
 

Reply via email to