Skip to content

Commit c874b3c

Browse files
authored
Add print-wal tool and logs when failures of reading wal files (#15416)
* Add print-wal tool and logs when failures of reading wal files * fix position printed
1 parent 3e0163d commit c874b3c

8 files changed

Lines changed: 297 additions & 38 deletions

File tree

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertRowNode.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,14 @@ public PlanNode clone() {
151151

152152
@Override
153153
public String toString() {
154-
return "InsertRowNode{" + "time=" + time + ", values=" + Arrays.toString(values) + '}';
154+
return "InsertRowNode{"
155+
+ "insertTarget="
156+
+ targetPath
157+
+ ", time="
158+
+ time
159+
+ ", values="
160+
+ Arrays.toString(values)
161+
+ '}';
155162
}
156163

157164
@Override

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/write/InsertTabletNode.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,4 +1300,21 @@ public void updateLastCache(final String databaseName) {
13001300
isAligned,
13011301
measurementSchemas);
13021302
}
1303+
1304+
@Override
1305+
public String toString() {
1306+
return "InsertTabletNode{"
1307+
+ "targetPath="
1308+
+ targetPath
1309+
+ ", measurements="
1310+
+ Arrays.toString(measurements)
1311+
+ ", rowCount="
1312+
+ rowCount
1313+
+ ", timeRange=[,"
1314+
+ times[0]
1315+
+ ", "
1316+
+ times[times.length - 1]
1317+
+ "]"
1318+
+ '}';
1319+
}
13031320
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,9 @@ public WALFlushListener getWalFlushListener() {
198198
public abstract boolean isSignal();
199199

200200
public abstract long getMemorySize();
201+
202+
@Override
203+
public String toString() {
204+
return "WALEntry{" + "type=" + type + ", memTableId=" + memTableId + ", value=" + value + '}';
205+
}
201206
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/io/WALInputStream.java

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -217,47 +217,58 @@ private void loadNextSegmentV1() throws IOException {
217217
}
218218

219219
private void loadNextSegmentV2() throws IOException {
220+
long position = channel.position();
220221
SegmentInfo segmentInfo = getNextSegmentInfo();
221-
if (segmentInfo.compressionType != CompressionType.UNCOMPRESSED) {
222-
// A compressed segment
223-
if (Objects.isNull(dataBuffer)
224-
|| dataBuffer.capacity() < segmentInfo.uncompressedSize
225-
|| dataBuffer.capacity() > segmentInfo.uncompressedSize * 2) {
226-
MmapUtil.clean(dataBuffer);
227-
dataBuffer = ByteBuffer.allocateDirect(segmentInfo.uncompressedSize);
228-
}
229-
dataBuffer.clear();
222+
try {
223+
if (segmentInfo.compressionType != CompressionType.UNCOMPRESSED) {
224+
// A compressed segment
225+
if (Objects.isNull(dataBuffer)
226+
|| dataBuffer.capacity() < segmentInfo.uncompressedSize
227+
|| dataBuffer.capacity() > segmentInfo.uncompressedSize * 2) {
228+
MmapUtil.clean(dataBuffer);
229+
dataBuffer = ByteBuffer.allocateDirect(segmentInfo.uncompressedSize);
230+
}
231+
dataBuffer.clear();
230232

231-
if (Objects.isNull(compressedBuffer)
232-
|| compressedBuffer.capacity() < segmentInfo.dataInDiskSize
233-
|| compressedBuffer.capacity() > segmentInfo.dataInDiskSize * 2) {
234-
MmapUtil.clean(compressedBuffer);
235-
compressedBuffer = ByteBuffer.allocateDirect(segmentInfo.dataInDiskSize);
236-
}
237-
compressedBuffer.clear();
238-
// limit the buffer to prevent it from reading too much byte than expected
239-
compressedBuffer.limit(segmentInfo.dataInDiskSize);
240-
if (readWALBufferFromChannel(compressedBuffer) != segmentInfo.dataInDiskSize) {
241-
throw new IOException("Unexpected end of file");
242-
}
243-
compressedBuffer.flip();
244-
IUnCompressor unCompressor = IUnCompressor.getUnCompressor(segmentInfo.compressionType);
245-
uncompressWALBuffer(compressedBuffer, dataBuffer, unCompressor);
246-
} else {
247-
// An uncompressed segment
248-
if (Objects.isNull(dataBuffer)
249-
|| dataBuffer.capacity() < segmentInfo.dataInDiskSize
250-
|| dataBuffer.capacity() > segmentInfo.dataInDiskSize * 2) {
251-
MmapUtil.clean(dataBuffer);
252-
dataBuffer = ByteBuffer.allocateDirect(segmentInfo.dataInDiskSize);
253-
}
254-
dataBuffer.clear();
255-
// limit the buffer to prevent it from reading too much byte than expected
256-
dataBuffer.limit(segmentInfo.dataInDiskSize);
233+
if (Objects.isNull(compressedBuffer)
234+
|| compressedBuffer.capacity() < segmentInfo.dataInDiskSize
235+
|| compressedBuffer.capacity() > segmentInfo.dataInDiskSize * 2) {
236+
MmapUtil.clean(compressedBuffer);
237+
compressedBuffer = ByteBuffer.allocateDirect(segmentInfo.dataInDiskSize);
238+
}
239+
compressedBuffer.clear();
240+
// limit the buffer to prevent it from reading too much byte than expected
241+
compressedBuffer.limit(segmentInfo.dataInDiskSize);
242+
if (readWALBufferFromChannel(compressedBuffer) != segmentInfo.dataInDiskSize) {
243+
throw new IOException("Unexpected end of file");
244+
}
245+
compressedBuffer.flip();
246+
IUnCompressor unCompressor = IUnCompressor.getUnCompressor(segmentInfo.compressionType);
247+
uncompressWALBuffer(compressedBuffer, dataBuffer, unCompressor);
248+
} else {
249+
// An uncompressed segment
250+
if (Objects.isNull(dataBuffer)
251+
|| dataBuffer.capacity() < segmentInfo.dataInDiskSize
252+
|| dataBuffer.capacity() > segmentInfo.dataInDiskSize * 2) {
253+
MmapUtil.clean(dataBuffer);
254+
dataBuffer = ByteBuffer.allocateDirect(segmentInfo.dataInDiskSize);
255+
}
256+
dataBuffer.clear();
257+
// limit the buffer to prevent it from reading too much byte than expected
258+
dataBuffer.limit(segmentInfo.dataInDiskSize);
257259

258-
if (readWALBufferFromChannel(dataBuffer) != segmentInfo.dataInDiskSize) {
259-
throw new IOException("Unexpected end of file");
260+
if (readWALBufferFromChannel(dataBuffer) != segmentInfo.dataInDiskSize) {
261+
throw new IOException("Unexpected end of file");
262+
}
260263
}
264+
} catch (Exception e) {
265+
logger.error(
266+
"Unexpected error when loading a wal segment {} in {}@{}",
267+
segmentInfo,
268+
logFile,
269+
position,
270+
e);
271+
throw new IOException(e);
261272
}
262273
dataBuffer.flip();
263274
}
@@ -391,5 +402,17 @@ int headerSize() {
391402
? Byte.BYTES + Integer.BYTES
392403
: Byte.BYTES + Integer.BYTES * 2;
393404
}
405+
406+
@Override
407+
public String toString() {
408+
return "SegmentInfo{"
409+
+ "compressionType="
410+
+ compressionType
411+
+ ", dataInDiskSize="
412+
+ dataInDiskSize
413+
+ ", uncompressedSize="
414+
+ uncompressedSize
415+
+ '}';
416+
}
394417
}
395418
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/utils/WALEntryPosition.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALNode;
2626

2727
import org.apache.tsfile.utils.Pair;
28+
import org.slf4j.Logger;
29+
import org.slf4j.LoggerFactory;
2830

2931
import java.io.File;
3032
import java.io.IOException;
@@ -38,6 +40,9 @@
3840
* and give some methods to read the content from the disk.
3941
*/
4042
public class WALEntryPosition {
43+
44+
private static final Logger LOGGER = LoggerFactory.getLogger(WALEntryPosition.class);
45+
4146
private volatile String identifier = "";
4247
private volatile long walFileVersionId = -1;
4348
private volatile long position;
@@ -107,6 +112,14 @@ ByteBuffer read() throws IOException {
107112
ByteBuffer buffer = ByteBuffer.allocate(size);
108113
is.read(buffer);
109114
return buffer;
115+
} catch (Exception e) {
116+
LOGGER.error(
117+
"Unexpected error when reading a wal entry from {}@{} with size {}",
118+
walFile,
119+
position,
120+
size,
121+
e);
122+
throw new IOException(e);
110123
}
111124
}
112125

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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+
* <p>
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
* <p>
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.db.storageengine.dataregion.wal.utils;
21+
22+
import org.apache.iotdb.db.storageengine.dataregion.wal.buffer.WALEntry;
23+
import org.apache.iotdb.db.storageengine.dataregion.wal.io.WALReader;
24+
25+
import java.io.File;
26+
import java.io.IOException;
27+
import java.util.Stack;
28+
29+
public class WALPrintTool {
30+
31+
public void print(File file) throws IOException {
32+
Stack<File> stack = new Stack<>();
33+
if (file.exists()) {
34+
stack.push(file);
35+
} else {
36+
System.out.println("The initial file does not exist");
37+
}
38+
39+
while (!stack.isEmpty()) {
40+
File f = stack.pop();
41+
if (f.isDirectory()) {
42+
File[] files = f.listFiles();
43+
if (files != null) {
44+
for (File child : files) {
45+
stack.push(child);
46+
}
47+
}
48+
} else if (f.getName().endsWith(".wal")) {
49+
doPrint(f);
50+
}
51+
}
52+
}
53+
54+
private void doPrint(File file) throws IOException {
55+
System.out.printf("-----------------%s---------------%n", file.getAbsoluteFile());
56+
try (WALReader reader = new WALReader(file)) {
57+
long walCurrentReadOffset = reader.getWALCurrentReadOffset();
58+
while (reader.hasNext()) {
59+
WALEntry entry = reader.next();
60+
System.out.printf("%d\t%s%n", walCurrentReadOffset, entry.toString());
61+
walCurrentReadOffset = reader.getWALCurrentReadOffset();
62+
}
63+
}
64+
}
65+
66+
public static void main(String[] args) throws IOException {
67+
if (args.length == 0) {
68+
System.out.println("Usage: WALPrintTool <file>");
69+
return;
70+
}
71+
72+
WALPrintTool tool = new WALPrintTool();
73+
tool.print(new File(args[0]));
74+
}
75+
}

scripts/tools/wal/print-wal.sh

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/bin/bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
#
20+
21+
echo ---------------------
22+
echo Starting Printing the WAL
23+
echo ---------------------
24+
25+
source "$(dirname "$0")/../../conf/iotdb-common.sh"
26+
#get_iotdb_include and checkAllVariables is in iotdb-common.sh
27+
VARS=$(get_iotdb_include "$*")
28+
checkAllVariables
29+
export IOTDB_HOME="${IOTDB_HOME}/.."
30+
eval set -- "$VARS"
31+
32+
33+
if [ -n "$JAVA_HOME" ]; then
34+
for java in "$JAVA_HOME"/bin/amd64/java "$JAVA_HOME"/bin/java; do
35+
if [ -x "$java" ]; then
36+
JAVA="$java"
37+
break
38+
fi
39+
done
40+
else
41+
JAVA=java
42+
fi
43+
44+
CLASSPATH=""
45+
for f in ${IOTDB_HOME}/lib/*.jar; do
46+
CLASSPATH=${CLASSPATH}":"$f
47+
done
48+
49+
MAIN_CLASS=org.apache.iotdb.db.storageengine.dataregion.wal.utils.WALPrintTool
50+
51+
"$JAVA" -cp "$CLASSPATH" "$MAIN_CLASS" "$@"
52+
exit $?
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
@REM
2+
@REM Licensed to the Apache Software Foundation (ASF) under one
3+
@REM or more contributor license agreements. See the NOTICE file
4+
@REM distributed with this work for additional information
5+
@REM regarding copyright ownership. The ASF licenses this file
6+
@REM to you under the Apache License, Version 2.0 (the
7+
@REM "License"); you may not use this file except in compliance
8+
@REM with the License. You may obtain a copy of the License at
9+
@REM
10+
@REM http://www.apache.org/licenses/LICENSE-2.0
11+
@REM
12+
@REM Unless required by applicable law or agreed to in writing,
13+
@REM software distributed under the License is distributed on an
14+
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
@REM KIND, either express or implied. See the License for the
16+
@REM specific language governing permissions and limitations
17+
@REM under the License.
18+
@REM
19+
20+
21+
@echo off
22+
echo ````````````````````````
23+
echo Starting Printing the WAL
24+
echo ````````````````````````
25+
26+
if "%OS%" == "Windows_NT" setlocal
27+
28+
pushd %~dp0..\..\..
29+
if NOT DEFINED IOTDB_HOME set IOTDB_HOME=%CD%
30+
popd
31+
32+
if NOT DEFINED MAIN_CLASS set MAIN_CLASS=org.apache.iotdb.db.storageengine.dataregion.wal.utils.WALPrintTool
33+
if NOT DEFINED JAVA_HOME goto :err
34+
35+
@REM -----------------------------------------------------------------------------
36+
@REM JVM Opts
37+
set JAVA_OPTS=-ea^
38+
-Dfile.encoding=UTF-8
39+
40+
@REM -----------------------------------------------------------------------------
41+
@REM ***** CLASSPATH library setting *****
42+
@REM Ensure that any user defined CLASSPATH variables are not used on startup
43+
set CLASSPATH="%IOTDB_HOME%\lib\*"
44+
45+
goto okClasspath
46+
47+
:append
48+
set CLASSPATH=%CLASSPATH%;%1
49+
goto :eof
50+
51+
@REM -----------------------------------------------------------------------------
52+
:okClasspath
53+
54+
"%JAVA_HOME%\bin\java" %JAVA_OPTS% -cp "%CLASSPATH%" %MAIN_CLASS% %*
55+
56+
goto finally
57+
58+
59+
:err
60+
echo JAVA_HOME environment variable must be set!
61+
pause
62+
63+
64+
@REM -----------------------------------------------------------------------------
65+
:finally
66+
67+
ENDLOCAL

0 commit comments

Comments
 (0)