This is an automated email from the ASF dual-hosted git repository.
JackieTien97 pushed a commit to branch dev/1.3
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/dev/1.3 by this push:
new 49d6dad7679 [to dev/1.3] Fix IndexOutOfBoundsException caused by
concurrent sort and delete on TVList- #18390
49d6dad7679 is described below
commit 49d6dad76798319b83a92dcbd241a844245e08bf
Author: shuwenwei <[email protected]>
AuthorDate: Tue Aug 4 13:52:11 2026 +0800
[to dev/1.3] Fix IndexOutOfBoundsException caused by concurrent sort and
delete on TVList- #18390
---
.../db/utils/datastructure/AlignedTVList.java | 23 +++++++++++++++++++---
.../iotdb/db/utils/datastructure/TVList.java | 8 +++++++-
2 files changed, 27 insertions(+), 4 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
index 958b8c4e657..f787ff64fda 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
@@ -548,7 +548,13 @@ public abstract class AlignedTVList extends TVList {
}
@Override
- public int delete(long lowerBound, long upperBound) {
+ /*
+ * Must be synchronized with sort() on the same TVList instance: a query may
sort
+ * this list in place (sort() is synchronized), and a concurrent delete would
+ * otherwise read the half-rebuilt indices and throw
IndexOutOfBoundsException
+ * or delete wrong rows.
+ */
+ public synchronized int delete(long lowerBound, long upperBound) {
int deletedNumber = 0;
for (int i = 0; i < dataTypes.size(); i++) {
deletedNumber += delete(lowerBound, upperBound, i).left;
@@ -559,12 +565,17 @@ public abstract class AlignedTVList extends TVList {
/**
* Delete points in a specific column.
*
+ * <p>Must be synchronized with {@link #sort()} on the same TVList instance:
a query may sort this
+ * list in place ({@code sort()} is synchronized), and a concurrent delete
would otherwise read
+ * the half-rebuilt {@code indices} and throw IndexOutOfBoundsException or
delete wrong rows.
+ *
* @param lowerBound deletion lower bound
* @param upperBound deletion upper bound
* @param columnIndex column index to be deleted
* @return Delete info pair. Left: deletedNumber int; right: ifDeleteColumn
boolean
*/
- public Pair<Integer, Boolean> delete(long lowerBound, long upperBound, int
columnIndex) {
+ public synchronized Pair<Integer, Boolean> delete(
+ long lowerBound, long upperBound, int columnIndex) {
if (columnIndex >= values.size()) {
return new Pair<>(0, false);
}
@@ -586,7 +597,13 @@ public abstract class AlignedTVList extends TVList {
return new Pair<>(deletedNumber, deleteColumn);
}
- public void deleteColumn(int columnIndex) {
+ /*
+ * Must be synchronized with sort() on the same TVList instance: a query may
sort
+ * this list in place (sort() is synchronized), and a concurrent delete would
+ * otherwise read the half-rebuilt indices and throw
IndexOutOfBoundsException
+ * or delete wrong rows.
+ */
+ public synchronized void deleteColumn(int columnIndex) {
if (bitMaps == null) {
List<List<BitMap>> localBitMaps = new ArrayList<>(dataTypes.size());
for (int j = 0; j < dataTypes.size(); j++) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
index 20e4a71932f..a085c29e130 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
@@ -569,7 +569,13 @@ public abstract class TVList implements WALEntryValue {
return clone();
}
- public int delete(long lowerBound, long upperBound) {
+ /*
+ * Must be synchronized with sort() on the same TVList instance: a query may
sort
+ * this list in place (sort() is synchronized), and a concurrent delete would
+ * otherwise read the half-rebuilt indices and throw
IndexOutOfBoundsException
+ * or delete wrong rows.
+ */
+ public synchronized int delete(long lowerBound, long upperBound) {
int deletedNumber = 0;
long maxTime = Long.MIN_VALUE;
long minTime = Long.MAX_VALUE;