Skip to content

Commit 8affcb3

Browse files
authored
Adapt file-scoped TsFile contexts and resource lifecycles (#18999)
* Adapt file-scoped TsFile contexts and resource lifecycles * Limit compaction context adaptation and preserve repair initialization * [Storage] Fix Pipe retries and WAL recovery file contexts Retain independent aligned chunks and buffer views for each reader construction attempt so failed attempts do not invalidate pending groups. Release pending value chunk references after successful construction. Propagate the recovered writer context to initial and snapshot recovery memtables. Cover constructor failure retries, partial retain cleanup, and aligned/non-aligned WAL insert and snapshot recovery. * [Storage] Preserve encryption policy when recovering header-only TsFiles * [Storage] Retain WAL files when TsFile recovery fails * [Storage] Block reuse of WAL nodes after failed recovery
1 parent 2d8f769 commit 8affcb3

64 files changed

Lines changed: 3040 additions & 255 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
package org.apache.iotdb.db.i18n;
2121

2222
public final class DataNodeQueryMessages {
23+
public static final String EXCEPTION_QUERY_CHUNK_RESOURCES_ARE_ALREADY_CLOSED_CA6A0559 =
24+
"Query chunk resources are already closed";
25+
public static final String LOG_FAILED_TO_RELEASE_QUERY_CHUNK_RESOURCES_91573FE5 =
26+
"Failed to release query chunk resources";
2327
public static final String EXCEPTION_FAILED_TO_CONVERT_TSFILE_ARG_TO_TABLETS_STATUS_ARG_E7C9F477 =
2428
"Failed to convert TsFile %s to tablets. Status: %s";
2529
public static final String EXCEPTION_FAILED_TO_CONVERT_TSFILE_ARG_TO_TABLETS_ARG_96358FDD =

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020
package org.apache.iotdb.db.i18n;
2121

2222
public final class StorageEngineMessages {
23+
public static final String EXCEPTION_CANNOT_ENABLE_WAL_NODE_ARG_BECAUSE_ITS_PREVIOUS_RECOVERY_FAILED_RESTART_AFTER_RESOLVING_THE_RECOVERY_FAILURE_56DF9750 =
24+
"Cannot enable WAL node %s because its previous recovery failed; restart after resolving the recovery failure.";
25+
public static final String LOG_WAL_NODE_RECOVERY_IN_ARG_WAS_INCOMPLETE_RETAINING_WAL_AND_CHECKPOINT_FILES_FOR_RETRY_48C1F7BF =
26+
"WAL node recovery in {} was incomplete; retaining WAL and checkpoint files for retry.";
27+
public static final String EXCEPTION_FILE_ENCRYPTION_PARAMETER_PROVIDER_RETURNED_NULL_15C41723 =
28+
"File encryption parameter provider returned null";
29+
public static final String EXCEPTION_PRECALCULATED_CHUNK_STAGING_IS_NOT_SUPPORTED_BY_THE_FILE_ENCRYPTION_POLICY_13DA8C32 =
30+
"Precalculated chunk staging is not supported by the file encryption policy";
31+
public static final String EXCEPTION_MULTIPLE_FILE_ENCRYPTION_PARAMETER_PROVIDERS_ARE_CONFIGURED_5E7DDA5B =
32+
"Multiple file encryption parameter providers are configured";
2333
public static final String EXCEPTION_UNSUPPORTED_OR_UNAVAILABLE_WAL_FORMAT_4629CFE4 =
2434
"Unsupported or unavailable WAL format";
2535
public static final String EXCEPTION_MULTIPLE_WAL_FORMAT_PROVIDERS_ARE_CONFIGURED_DD78877D =

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
package org.apache.iotdb.db.i18n;
2121

2222
public final class DataNodeQueryMessages {
23+
public static final String EXCEPTION_QUERY_CHUNK_RESOURCES_ARE_ALREADY_CLOSED_CA6A0559 =
24+
"查询 Chunk 资源已关闭";
25+
public static final String LOG_FAILED_TO_RELEASE_QUERY_CHUNK_RESOURCES_91573FE5 =
26+
"释放查询 Chunk 资源失败";
2327
public static final String EXCEPTION_FAILED_TO_CONVERT_TSFILE_ARG_TO_TABLETS_STATUS_ARG_E7C9F477 =
2428
"将 TsFile %s 转换为 tablet 失败。状态:%s";
2529
public static final String EXCEPTION_FAILED_TO_CONVERT_TSFILE_ARG_TO_TABLETS_ARG_96358FDD =

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020
package org.apache.iotdb.db.i18n;
2121

2222
public final class StorageEngineMessages {
23+
public static final String EXCEPTION_CANNOT_ENABLE_WAL_NODE_ARG_BECAUSE_ITS_PREVIOUS_RECOVERY_FAILED_RESTART_AFTER_RESOLVING_THE_RECOVERY_FAILURE_56DF9750 =
24+
"WAL 节点 %s 上次恢复失败,无法启用;请解决恢复失败原因后重启。";
25+
public static final String LOG_WAL_NODE_RECOVERY_IN_ARG_WAS_INCOMPLETE_RETAINING_WAL_AND_CHECKPOINT_FILES_FOR_RETRY_48C1F7BF =
26+
"目录 {} 中的 WAL 节点恢复未完成;保留 WAL 和 checkpoint 文件以便重试。";
27+
public static final String EXCEPTION_FILE_ENCRYPTION_PARAMETER_PROVIDER_RETURNED_NULL_15C41723 =
28+
"文件加密参数 Provider 返回 null";
29+
public static final String EXCEPTION_PRECALCULATED_CHUNK_STAGING_IS_NOT_SUPPORTED_BY_THE_FILE_ENCRYPTION_POLICY_13DA8C32 =
30+
"文件加密策略不支持预计算 Chunk 暂存";
31+
public static final String EXCEPTION_MULTIPLE_FILE_ENCRYPTION_PARAMETER_PROVIDERS_ARE_CONFIGURED_5E7DDA5B =
32+
"配置了多个文件加密参数 Provider";
2333
public static final String EXCEPTION_UNSUPPORTED_OR_UNAVAILABLE_WAL_FORMAT_4629CFE4 =
2434
"WAL 格式不支持或对应实现不可用";
2535
public static final String EXCEPTION_MULTIPLE_WAL_FORMAT_PROVIDERS_ARE_CONFIGURED_DD78877D =

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/scan/AlignedSinglePageWholeChunkReader.java‎

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,37 +63,61 @@ public class AlignedSinglePageWholeChunkReader extends AbstractChunkReader
6363
// deleted intervals of all the sub sensors
6464
private final List<List<TimeRange>> valueDeleteIntervalsList = new ArrayList<>();
6565
private final long pageEstimatedMemoryUsageInBytes;
66+
private final Chunk ownedTimeChunk;
67+
private final List<Chunk> ownedValueChunks;
6668

6769
public AlignedSinglePageWholeChunkReader(
6870
Chunk timeChunk, List<Chunk> valueChunkList, LongConsumer filteredRowsRecord)
6971
throws IOException {
7072
super(Long.MIN_VALUE, null, filteredRowsRecord);
73+
ownedTimeChunk = timeChunk;
74+
ownedValueChunks = new ArrayList<>(valueChunkList);
7175
this.timeChunkHeader = timeChunk.getHeader();
7276
this.timeChunkDataBuffer = timeChunk.getData();
7377
this.encryptParam = timeChunk.getEncryptParam();
74-
this.pageEstimatedMemoryUsageInBytes =
75-
calculateMaxPageEstimatedMemoryUsageInBytesWithBatchData(timeChunk, valueChunkList);
76-
77-
valueChunkList.forEach(
78-
chunk -> {
79-
this.valueChunkHeaderList.add(chunk == null ? null : chunk.getHeader());
80-
this.valueChunkDataBufferList.add(chunk == null ? null : chunk.getData());
81-
this.valueDeleteIntervalsList.add(chunk == null ? null : chunk.getDeleteIntervalList());
82-
});
78+
try {
79+
this.pageEstimatedMemoryUsageInBytes =
80+
calculateMaxPageEstimatedMemoryUsageInBytesWithBatchData(timeChunk, valueChunkList);
81+
82+
valueChunkList.forEach(
83+
chunk -> {
84+
this.valueChunkHeaderList.add(chunk == null ? null : chunk.getHeader());
85+
this.valueChunkDataBufferList.add(chunk == null ? null : chunk.getData());
86+
this.valueDeleteIntervalsList.add(chunk == null ? null : chunk.getDeleteIntervalList());
87+
});
88+
89+
initAllPageReaders();
90+
} catch (IOException | RuntimeException | Error e) {
91+
try {
92+
close();
93+
} catch (RuntimeException failure) {
94+
e.addSuppressed(failure);
95+
}
96+
throw e;
97+
}
98+
}
8399

84-
initAllPageReaders();
100+
@Override
101+
public void close() {
102+
ownedTimeChunk.close();
103+
for (Chunk chunk : ownedValueChunks) {
104+
if (chunk != null) {
105+
chunk.close();
106+
}
107+
}
85108
}
86109

87110
private void initAllPageReaders() throws IOException {
111+
int pageIndex = 0;
88112
while (timeChunkDataBuffer.remaining() > 0) {
89-
AlignedPageReader alignedPageReader = deserializeFromSinglePageChunk();
113+
AlignedPageReader alignedPageReader = deserializeFromSinglePageChunk(pageIndex++);
90114
if (alignedPageReader != null) {
91115
pageReaderList.add(alignedPageReader);
92116
}
93117
}
94118
}
95119

96-
private AlignedPageReader deserializeFromSinglePageChunk() throws IOException {
120+
private AlignedPageReader deserializeFromSinglePageChunk(int pageIndex) throws IOException {
97121
PageHeader timePageHeader =
98122
PageHeader.deserializeFrom(timeChunkDataBuffer, (Statistics<? extends Serializable>) null);
99123
List<PageHeader> valuePageHeaderList = new ArrayList<>();
@@ -115,7 +139,7 @@ private AlignedPageReader deserializeFromSinglePageChunk() throws IOException {
115139
skipCurrentPage(timePageHeader, valuePageHeaderList);
116140
return null;
117141
}
118-
return constructAlignedPageReader(timePageHeader, valuePageHeaderList);
142+
return constructAlignedPageReader(timePageHeader, valuePageHeaderList, pageIndex);
119143
}
120144

121145
private void skipCurrentPage(PageHeader timePageHeader, List<PageHeader> valuePageHeader) {
@@ -133,11 +157,17 @@ private void skipCurrentPage(PageHeader timePageHeader, List<PageHeader> valuePa
133157
}
134158

135159
private AlignedPageReader constructAlignedPageReader(
136-
PageHeader timePageHeader, List<PageHeader> rawValuePageHeaderList) throws IOException {
160+
PageHeader timePageHeader, List<PageHeader> rawValuePageHeaderList, int pageIndex)
161+
throws IOException {
137162
IDecryptor decryptor = IDecryptor.getDecryptor(encryptParam);
138163
ByteBuffer timePageData =
139164
ChunkReader.deserializePageData(
140-
timePageHeader, timeChunkDataBuffer, timeChunkHeader, decryptor);
165+
timePageHeader,
166+
timeChunkDataBuffer,
167+
timeChunkHeader,
168+
decryptor,
169+
encryptParam,
170+
pageIndex);
141171

142172
List<PageHeader> valuePageHeaderList = new ArrayList<>();
143173
LazyLoadPageData[] valuePageDataArray = new LazyLoadPageData[rawValuePageHeaderList.size()];
@@ -166,7 +196,9 @@ private AlignedPageReader constructAlignedPageReader(
166196
valueChunkDataBufferList.get(i).array(),
167197
currentPagePosition,
168198
IUnCompressor.getUnCompressor(valueChunkHeader.getCompressionType()),
169-
encryptParam);
199+
encryptParam,
200+
pageIndex,
201+
valueChunkHeader.getChunkOrdinal());
170202
valueDataTypeList.add(valueChunkHeader.getDataType());
171203
valueDecoderList.add(
172204
Decoder.getDecoderByType(

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/scan/SinglePageWholeChunkReader.java‎

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.apache.tsfile.read.common.Chunk;
3636
import org.apache.tsfile.read.common.type.Type;
3737
import org.apache.tsfile.read.reader.chunk.AbstractChunkReader;
38+
import org.apache.tsfile.read.reader.chunk.ChunkReader;
3839
import org.apache.tsfile.read.reader.page.LazyLoadPageData;
3940
import org.apache.tsfile.read.reader.page.PageReader;
4041
import org.apache.tsfile.utils.RamUsageEstimator;
@@ -55,29 +56,47 @@ public class SinglePageWholeChunkReader extends AbstractChunkReader
5556
private final ByteBuffer chunkDataBuffer;
5657
private final EncryptParameter encryptParam;
5758
private final long pageEstimatedMemoryUsageInBytes;
59+
private final Chunk ownedChunk;
5860

5961
public SinglePageWholeChunkReader(Chunk chunk) throws IOException {
6062
super(Long.MIN_VALUE, null, null);
63+
ownedChunk = chunk;
6164

6265
this.chunkHeader = chunk.getHeader();
6366
this.chunkDataBuffer = chunk.getData();
6467
this.encryptParam = chunk.getEncryptParam();
65-
this.pageEstimatedMemoryUsageInBytes =
66-
calculateMaxPageEstimatedMemoryUsageInBytesWithBatchData(chunk);
67-
initAllPageReaders();
68+
try {
69+
this.pageEstimatedMemoryUsageInBytes =
70+
calculateMaxPageEstimatedMemoryUsageInBytesWithBatchData(chunk);
71+
initAllPageReaders();
72+
} catch (IOException | RuntimeException | Error e) {
73+
try {
74+
chunk.close();
75+
} catch (RuntimeException failure) {
76+
e.addSuppressed(failure);
77+
}
78+
throw e;
79+
}
80+
}
81+
82+
@Override
83+
public void close() {
84+
ownedChunk.close();
6885
}
6986

7087
private void initAllPageReaders() throws IOException {
88+
int pageIndex = 0;
7189
// construct next satisfied page header
7290
while (chunkDataBuffer.remaining() > 0) {
7391
pageReaderList.add(
7492
constructPageReader(
7593
PageHeader.deserializeFrom(
76-
chunkDataBuffer, (Statistics<? extends Serializable>) null)));
94+
chunkDataBuffer, (Statistics<? extends Serializable>) null),
95+
pageIndex++));
7796
}
7897
}
7998

80-
private PageReader constructPageReader(PageHeader pageHeader) throws IOException {
99+
private PageReader constructPageReader(PageHeader pageHeader, int pageIndex) throws IOException {
81100
final int currentPagePosition = chunkDataBuffer.position();
82101
chunkDataBuffer.position(currentPagePosition + pageHeader.getCompressedSize());
83102
return new PageReader(
@@ -86,7 +105,9 @@ private PageReader constructPageReader(PageHeader pageHeader) throws IOException
86105
chunkDataBuffer.array(),
87106
currentPagePosition,
88107
IUnCompressor.getUnCompressor(chunkHeader.getCompressionType()),
89-
encryptParam),
108+
encryptParam,
109+
pageIndex,
110+
chunkHeader.getChunkOrdinal()),
90111
chunkHeader.getDataType(),
91112
Decoder.getDecoderByType(chunkHeader.getEncodingType(), chunkHeader.getDataType()),
92113
getConfiguredTimeDecoder(),
@@ -194,11 +215,13 @@ private static int countSinglePageTimeValues(final Chunk chunk) throws IOExcepti
194215
chunkDataBuffer.rewind();
195216
final PageHeader pageHeader = deserializePageHeader(chunkDataBuffer, chunk.getHeader());
196217
final ByteBuffer pageData =
197-
deserializePageData(
218+
ChunkReader.deserializePageData(
198219
pageHeader,
199220
chunkDataBuffer,
200221
chunk.getHeader(),
201-
IDecryptor.getDecryptor(chunk.getEncryptParam()));
222+
IDecryptor.getDecryptor(chunk.getEncryptParam()),
223+
chunk.getEncryptParam(),
224+
0);
202225
final Decoder decoder =
203226
Decoder.getDecoderByType(chunk.getHeader().getEncodingType(), TSDataType.INT64);
204227

0 commit comments

Comments
 (0)