Skip to content

Commit d2fcb53

Browse files
authored
Fix delayed query cleanup during file metadata scans (#18679)
1 parent 9572044 commit d2fcb53

4 files changed

Lines changed: 429 additions & 0 deletions

File tree

‎iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
public final class DataNodeQueryMessages {
2323

24+
public static final String EXCEPTION_FRAGMENT_INSTANCE_ARG_IS_ALREADY_ARG_B44984B4 =
25+
"Fragment instance %s is already %s";
26+
2427
public static final String EXCEPTION_INVALID_THRIFT_MAXIMUM_FRAME_SIZE_ARG_FROM_ARG_A639588B =
2528
"Invalid Thrift maximum frame size %d from %s";
2629
public static final String MESSAGE_FAILED_TO_DISPATCH_LOAD_COMMAND_ARG_TO_NODE_ARG_BECAUSE_OF_EXCEPTION_ARG_2D8A483D =

‎iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121

2222
public final class DataNodeQueryMessages {
2323

24+
public static final String EXCEPTION_FRAGMENT_INSTANCE_ARG_IS_ALREADY_ARG_B44984B4 =
25+
"Fragment instance %s 已处于 %s 状态";
26+
2427
public static final String EXCEPTION_INVALID_THRIFT_MAXIMUM_FRAME_SIZE_ARG_FROM_ARG_A639588B =
2528
"Thrift 最大帧大小 %d 无效,来源:%s";
2629
public static final String MESSAGE_FAILED_TO_DISPATCH_LOAD_COMMAND_ARG_TO_NODE_ARG_BECAUSE_OF_EXCEPTION_ARG_2D8A483D =

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/SeriesScanUtil.java‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.apache.iotdb.db.exception.CorruptedTsFileException;
2626
import org.apache.iotdb.db.i18n.DataNodeQueryMessages;
2727
import org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceContext;
28+
import org.apache.iotdb.db.queryengine.execution.fragment.FragmentInstanceState;
2829
import org.apache.iotdb.db.queryengine.execution.fragment.QueryContext;
2930
import org.apache.iotdb.db.queryengine.metric.SeriesScanCostMetricSet;
3031
import org.apache.iotdb.db.queryengine.plan.analyze.cache.schema.DataNodeTTLCache;
@@ -285,6 +286,7 @@ protected DescPriorityMergeReader getDescPriorityMergeReader() {
285286
// Optional.empty(), it needs to return directly to the checkpoint method that checks the operator
286287
// execution time slice.
287288
public Optional<Boolean> hasNextFile() throws IOException {
289+
checkFragmentInstanceState();
288290
if (runtimeFilterExhausted || !paginationController.hasCurLimit()) {
289291
return Optional.of(false);
290292
}
@@ -2016,8 +2018,10 @@ private void unpackAllOverlappedTsFilesToTimeSeriesMetadata(long endpointTime)
20162018
}
20172019

20182020
private Optional<ITimeSeriesMetadata> unpackSeqTsFileResource() throws IOException {
2021+
checkFragmentInstanceState();
20192022
ITimeSeriesMetadata timeseriesMetadata =
20202023
loadTimeSeriesMetadata(orderUtils.getNextSeqFileResource(true), true);
2024+
checkFragmentInstanceState();
20212025
// skip if data type is mismatched which may be caused by delete
20222026
if (timeseriesMetadata != null && timeseriesMetadata.typeMatch(getTsDataTypeList())) {
20232027
timeseriesMetadata.setSeq(true);
@@ -2029,8 +2033,10 @@ private Optional<ITimeSeriesMetadata> unpackSeqTsFileResource() throws IOExcepti
20292033
}
20302034

20312035
private Optional<ITimeSeriesMetadata> unpackUnseqTsFileResource() throws IOException {
2036+
checkFragmentInstanceState();
20322037
ITimeSeriesMetadata timeseriesMetadata =
20332038
loadTimeSeriesMetadata(orderUtils.getNextUnseqFileResource(true), false);
2039+
checkFragmentInstanceState();
20342040
// skip if data type is mismatched which may be caused by delete
20352041
if (timeseriesMetadata != null && timeseriesMetadata.typeMatch(getTsDataTypeList())) {
20362042
timeseriesMetadata.setSeq(false);
@@ -2041,6 +2047,24 @@ private Optional<ITimeSeriesMetadata> unpackUnseqTsFileResource() throws IOExcep
20412047
}
20422048
}
20432049

2050+
private void checkFragmentInstanceState() throws IOException {
2051+
// Compaction also uses this scanner, but its context has no fragment state machine.
2052+
if (context.getStateMachine() == null) {
2053+
return;
2054+
}
2055+
FragmentInstanceState state = context.getStateMachine().getState();
2056+
if (state.isDone()) {
2057+
// A scan over many overlapping files may stay in one operator call long after cancellation.
2058+
// Exit on the driver thread so it can release its lock and finish resource cleanup.
2059+
throw new IOException(
2060+
String.format(
2061+
DataNodeQueryMessages.EXCEPTION_FRAGMENT_INSTANCE_ARG_IS_ALREADY_ARG_B44984B4,
2062+
context.getId(),
2063+
state),
2064+
context.getFailureCause().orElse(null));
2065+
}
2066+
}
2067+
20442068
protected ITimeSeriesMetadata loadTimeSeriesMetadata(TsFileResource resource, boolean isSeq)
20452069
throws IOException {
20462070
return FileLoaderUtils.loadTimeSeriesMetadata(

0 commit comments

Comments
 (0)