diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/source/dataregion/historical/PipeHistoricalDataRegionTsFileSource.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/source/dataregion/historical/PipeHistoricalDataRegionTsFileSource.java index d0dd6549f07ad..1d984f9e18f45 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/source/dataregion/historical/PipeHistoricalDataRegionTsFileSource.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/source/dataregion/historical/PipeHistoricalDataRegionTsFileSource.java @@ -691,7 +691,7 @@ private boolean mayTsFileResourceOverlappedWithPattern(final TsFileResource reso .getDeviceIsAlignedMapFromCache(resource.getTsFile(), false); deviceSet = Objects.nonNull(deviceIsAlignedMap) ? deviceIsAlignedMap.keySet() : resource.getDevices(); - } catch (final IOException e) { + } catch (final IOException | RuntimeException e) { LOGGER.warn( "Pipe {}@{}: failed to get devices from TsFile {}, extract it anyway", pipeName, @@ -714,7 +714,7 @@ private boolean isTsFileResourceCoveredByPattern(final TsFileResource resource) .getDeviceIsAlignedMapFromCache(resource.getTsFile(), false); deviceSet = Objects.nonNull(deviceIsAlignedMap) ? deviceIsAlignedMap.keySet() : resource.getDevices(); - } catch (final IOException e) { + } catch (final IOException | RuntimeException e) { return false; } diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/source/dataregion/historical/PipeHistoricalDataRegionTsFileSourceTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/source/dataregion/historical/PipeHistoricalDataRegionTsFileSourceTest.java index 61e55dc5cac0e..7562e54e5811b 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/source/dataregion/historical/PipeHistoricalDataRegionTsFileSourceTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/source/dataregion/historical/PipeHistoricalDataRegionTsFileSourceTest.java @@ -34,6 +34,7 @@ import org.apache.iotdb.commons.utils.FileUtils; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus; +import org.apache.iotdb.db.storageengine.dataregion.tsfile.timeindex.FileTimeIndex; import org.apache.iotdb.pipe.api.customizer.parameter.PipeParameterValidator; import org.apache.iotdb.pipe.api.customizer.parameter.PipeParameters; import org.apache.iotdb.pipe.api.event.Event; @@ -412,6 +413,36 @@ public void testTsFileResourceCoveredByPattern() throws Exception { } } + @Test + public void testMissingTsFileResourceDoesNotBlockHistoricalExtraction() throws Exception { + final File tempDir = Files.createTempDirectory("pipeHistoricalMissingResource").toFile(); + + try { + final PipeHistoricalDataRegionTsFileSource source = + new PipeHistoricalDataRegionTsFileSource(); + final TsFileResource resource = createTsFileResource(tempDir, "missing-resource.tsfile"); + resource.setTimeIndex(new FileTimeIndex()); + + setPrivateField(source, "pipeName", "pipe"); + setPrivateField(source, "dataRegionId", 1); + setPrivateField(source, "pipePattern", new PrefixPipePattern("root.**")); + + final Method mayOverlapMethod = + PipeHistoricalDataRegionTsFileSource.class.getDeclaredMethod( + "mayTsFileResourceOverlappedWithPattern", TsFileResource.class); + mayOverlapMethod.setAccessible(true); + Assert.assertTrue((Boolean) mayOverlapMethod.invoke(source, resource)); + + final Method coveredMethod = + PipeHistoricalDataRegionTsFileSource.class.getDeclaredMethod( + "isTsFileResourceCoveredByPattern", TsFileResource.class); + coveredMethod.setAccessible(true); + Assert.assertFalse((Boolean) coveredMethod.invoke(source, resource)); + } finally { + FileUtils.deleteFileOrDirectory(tempDir); + } + } + private static void assertMayTsFileContainUnprocessedData( final File tempDir, final String fileName,