Skip to content

Commit 7790a6f

Browse files
authored
Preserve write-path causes and return delete failure details (#18933) (#18993)
* Preserve causes in write-path diagnostics * Return delete failure details to clients * Avoid stack traces for expected write-path errors
1 parent 4166bb9 commit 7790a6f

5 files changed

Lines changed: 74 additions & 7 deletions

File tree

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/statemachine/dataregion/DataExecutionVisitor.java‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,12 @@ public TSStatus visitDeleteData(DeleteDataNode node, DataRegion dataRegion) {
243243
return StatusUtils.OK;
244244
} catch (WriteProcessRejectException e) {
245245
return RpcUtils.getStatus(e.getErrorCode(), e.getMessage());
246-
} catch (IOException | IllegalPathException e) {
246+
} catch (IOException e) {
247247
LOGGER.error("Error in executing plan node: {}", node, e);
248-
return new TSStatus(TSStatusCode.WRITE_PROCESS_ERROR.getStatusCode());
248+
return RpcUtils.getStatus(TSStatusCode.WRITE_PROCESS_ERROR, e.getMessage());
249+
} catch (IllegalPathException e) {
250+
LOGGER.error("{}: {}", node, e.getMessage());
251+
return RpcUtils.getStatus(TSStatusCode.WRITE_PROCESS_ERROR, e.getMessage());
249252
} finally {
250253
dataRegion.writeUnlock();
251254
}

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/timeindex/FileTimeIndexCacheRecorder.java‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ public void logFileTimeIndex(TsFileResource... tsFileResources) {
102102
buffer.flip();
103103
writer.write(buffer);
104104
} catch (IOException e) {
105-
LOGGER.warn("Meet error when record FileTimeIndexCache: {}", e.getMessage());
105+
LOGGER.warn("Meet error when record FileTimeIndexCache: {}", e.getMessage(), e);
106106
}
107107
});
108108
if (!result) {
@@ -155,7 +155,7 @@ public void compactFileTimeIndexIfNeeded(
155155
}
156156
}
157157
} catch (IOException e) {
158-
LOGGER.warn("Meet error when compact FileTimeIndexCache: {}", e.getMessage());
158+
LOGGER.warn("Meet error when compact FileTimeIndexCache: {}", e.getMessage(), e);
159159
}
160160
});
161161
if (!result) {
@@ -199,7 +199,7 @@ public void removeFileTimeIndexCache(int dataRegionId) {
199199
writer.close();
200200
deleteFileOrDirectory(writer.getLogFile(), true);
201201
} catch (IOException e) {
202-
LOGGER.warn("Meet error when close FileTimeIndexCache: {}", e.getMessage());
202+
LOGGER.warn("Meet error when close FileTimeIndexCache: {}", e.getMessage(), e);
203203
}
204204
}
205205
}

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/buffer/WALBuffer.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,8 @@ public Set<Long> getMemTableIds(long fileVersionId) {
765765
"Fail to read memTable ids from the wal file {} of wal node {}: {}",
766766
id,
767767
identifier,
768-
e.getMessage());
768+
e.getMessage(),
769+
e);
769770
} catch (IOException e) {
770771
logger.warn(
771772
"Fail to read memTable ids from the wal file {} of wal node {}.",

‎iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/recover/WALNodeRecoverTask.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,8 @@ private void recoverTsFiles() {
292292
logger.warn(
293293
"Fail to read memTable ids from the wal file {} of wal node: {}",
294294
walFile.getAbsoluteFile(),
295-
e.getMessage());
295+
logDirectory.getName(),
296+
e);
296297
} catch (IOException e) {
297298
logger.warn(
298299
"Fail to read memTable ids from the wal file {} of wal node.",
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.iotdb.db.consensus.statemachine.dataregion;
20+
21+
import org.apache.iotdb.common.rpc.thrift.TSStatus;
22+
import org.apache.iotdb.commons.path.PartialPath;
23+
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId;
24+
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.DeleteDataNode;
25+
import org.apache.iotdb.db.storageengine.dataregion.DataRegion;
26+
import org.apache.iotdb.rpc.TSStatusCode;
27+
28+
import org.junit.Assert;
29+
import org.junit.Test;
30+
import org.mockito.Mockito;
31+
32+
import java.io.IOException;
33+
import java.util.Collections;
34+
35+
import static org.mockito.ArgumentMatchers.any;
36+
import static org.mockito.ArgumentMatchers.anyLong;
37+
38+
public class DataExecutionVisitorTest {
39+
40+
@Test
41+
public void testDeleteFailureReturnsMessage() throws Exception {
42+
final DataRegion dataRegion = Mockito.mock(DataRegion.class);
43+
Mockito.when(dataRegion.getDatabaseName()).thenReturn("root.sg");
44+
final IOException failure = new IOException("injected delete failure");
45+
Mockito.doThrow(failure)
46+
.when(dataRegion)
47+
.deleteByDevice(any(PartialPath.class), anyLong(), anyLong(), anyLong());
48+
49+
final DeleteDataNode node =
50+
new DeleteDataNode(
51+
new PlanNodeId("delete-error-test"),
52+
Collections.singletonList(new PartialPath("root.sg.device.s1")),
53+
Long.MIN_VALUE,
54+
Long.MAX_VALUE);
55+
56+
final TSStatus status = new DataExecutionVisitor().visitDeleteData(node, dataRegion);
57+
58+
Assert.assertEquals(TSStatusCode.WRITE_PROCESS_ERROR.getStatusCode(), status.getCode());
59+
Assert.assertEquals(failure.getMessage(), status.getMessage());
60+
Mockito.verify(dataRegion).writeUnlock();
61+
}
62+
}

0 commit comments

Comments
 (0)