This is an automated email from the ASF dual-hosted git repository.
shuwenwei pushed a commit to branch table_disk_usage_statistics_with_cache
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to
refs/heads/table_disk_usage_statistics_with_cache by this push:
new 415e426e99f fix bug
415e426e99f is described below
commit 415e426e99fc168fd70306723aa8b15108d99cb2
Author: shuwenwei <[email protected]>
AuthorDate: Tue Jan 27 14:55:04 2026 +0800
fix bug
---
.../AbstractTableSizeCacheWriter.java | 2 +-
.../tsfile/TsFileTableDiskUsageCacheWriter.java | 38 +++--
.../utils/TsFileTableSizeCacheWriterTest.java | 190 ++++++++++++++++++++-
3 files changed, 214 insertions(+), 16 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageCache/AbstractTableSizeCacheWriter.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageCache/AbstractTableSizeCacheWriter.java
index 84a017f474d..4f080ca5073 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageCache/AbstractTableSizeCacheWriter.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageCache/AbstractTableSizeCacheWriter.java
@@ -33,7 +33,7 @@ import java.util.concurrent.TimeUnit;
public abstract class AbstractTableSizeCacheWriter {
protected static final Logger logger =
LoggerFactory.getLogger(AbstractTableSizeCacheWriter.class);
- protected static final String TEMP_CACHE_FILE_SUBFIX = ".tmp";
+ public static final String TEMP_CACHE_FILE_SUBFIX = ".tmp";
protected final int regionId;
protected long previousCompactionTimestamp = System.currentTimeMillis();
protected long lastWriteTimestamp = System.currentTimeMillis();
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageCache/tsfile/TsFileTableDiskUsageCacheWriter.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageCache/tsfile/TsFileTableDiskUsageCacheWriter.java
index 772b93732ef..2ecd3d39662 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageCache/tsfile/TsFileTableDiskUsageCacheWriter.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/utils/tableDiskUsageCache/tsfile/TsFileTableDiskUsageCacheWriter.java
@@ -20,6 +20,7 @@
package
org.apache.iotdb.db.storageengine.dataregion.utils.tableDiskUsageCache.tsfile;
import org.apache.iotdb.commons.consensus.DataRegionId;
+import org.apache.iotdb.commons.utils.FileUtils;
import org.apache.iotdb.db.storageengine.StorageEngine;
import org.apache.iotdb.db.storageengine.dataregion.DataRegion;
import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileID;
@@ -43,8 +44,8 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
public class TsFileTableDiskUsageCacheWriter extends
AbstractTableSizeCacheWriter {
- private static final String TSFILE_CACHE_KEY_FILENAME_PREFIX =
"TableSizeKeyFile_";
- private static final String TSFILE_CACHE_VALUE_FILENAME_PREFIX =
"TableSizeValueFile_";
+ public static final String TSFILE_CACHE_KEY_FILENAME_PREFIX =
"TableSizeKeyFile_";
+ public static final String TSFILE_CACHE_VALUE_FILENAME_PREFIX =
"TableSizeValueFile_";
public static final int KEY_FILE_OFFSET_RECORD_LENGTH = 5 * Long.BYTES + 1;
public static final int KEY_FILE_REDIRECT_RECORD_LENGTH = 7 * Long.BYTES + 1;
public static final byte KEY_FILE_RECORD_TYPE_OFFSET = 1;
@@ -76,32 +77,33 @@ public class TsFileTableDiskUsageCacheWriter extends
AbstractTableSizeCacheWrite
}
continue;
}
- if (isTempFile) {
- try {
- Files.delete(file.toPath());
- } catch (IOException ignored) {
- }
- }
int version;
try {
- version =
Integer.parseInt(fileName.substring(TSFILE_CACHE_KEY_FILENAME_PREFIX.length()));
+ version = getVersion(fileName);
} catch (NumberFormatException ignored) {
continue;
}
+ if (isTempFile) {
+ FileUtils.deleteFileIfExist(file);
+ FileUtils.deleteFileIfExist(generateValueFile(version, true));
+ continue;
+ }
File valueFile =
new File(dir + File.separator + TSFILE_CACHE_VALUE_FILENAME_PREFIX
+ version);
// may have a valid value index file
if (!valueFile.exists()) {
File tempValueFile = new File(valueFile.getPath() +
TEMP_CACHE_FILE_SUBFIX);
if (tempValueFile.exists()) {
- tempValueFile.renameTo(valueFile);
+ try {
+ Files.move(tempValueFile.toPath(), valueFile.toPath());
+ } catch (IOException e) {
+ logger.warn("Failed to move {} to {}", tempValueFile, valueFile,
e);
+ continue;
+ }
valueFiles.add(valueFile);
} else {
// lost value file
- try {
- Files.delete(file.toPath());
- } catch (IOException ignored) {
- }
+ FileUtils.deleteFileIfExist(file);
continue;
}
}
@@ -127,6 +129,14 @@ public class TsFileTableDiskUsageCacheWriter extends
AbstractTableSizeCacheWrite
}
}
+ private int getVersion(String fileName) throws NumberFormatException {
+ int version = 0;
+ String removePrefixStr =
fileName.substring(TSFILE_CACHE_KEY_FILENAME_PREFIX.length());
+ int suffixIdx = removePrefixStr.indexOf('.');
+ return Integer.parseInt(
+ suffixIdx > 0 ? removePrefixStr.substring(0, suffixIdx) :
removePrefixStr);
+ }
+
public void write(TsFileID tsFileID, Map<String, Long> tableSizeMap) throws
IOException {
tsFileTableSizeIndexFileWriter.write(tsFileID, tableSizeMap);
markWritten();
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/utils/TsFileTableSizeCacheWriterTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/utils/TsFileTableSizeCacheWriterTest.java
index 7b860c570e0..2a7a7eefd33 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/utils/TsFileTableSizeCacheWriterTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/utils/TsFileTableSizeCacheWriterTest.java
@@ -28,6 +28,7 @@ import
org.apache.iotdb.db.storageengine.dataregion.compaction.AbstractCompactio
import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileID;
import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileManager;
import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource;
+import
org.apache.iotdb.db.storageengine.dataregion.utils.tableDiskUsageCache.AbstractTableSizeCacheWriter;
import
org.apache.iotdb.db.storageengine.dataregion.utils.tableDiskUsageCache.DataRegionTableSizeQueryContext;
import
org.apache.iotdb.db.storageengine.dataregion.utils.tableDiskUsageCache.TimePartitionTableSizeQueryContext;
import
org.apache.iotdb.db.storageengine.dataregion.utils.tableDiskUsageCache.tsfile.TsFileTableDiskUsageCacheWriter;
@@ -35,6 +36,8 @@ import
org.apache.iotdb.db.storageengine.dataregion.utils.tableDiskUsageCache.ts
import org.apache.tsfile.exception.write.WriteProcessException;
import org.apache.tsfile.utils.Pair;
+import org.apache.tsfile.utils.ReadWriteForEncodingUtils;
+import org.apache.tsfile.utils.ReadWriteIOUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -43,9 +46,11 @@ import org.mockito.Mockito;
import java.io.File;
import java.io.IOException;
+import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -240,7 +245,7 @@ public class TsFileTableSizeCacheWriterTest extends
AbstractCompactionTest {
}
@Test
- public void testRecoverWriter() throws IOException {
+ public void testRecoverWriter1() throws IOException {
TsFileTableDiskUsageCacheWriter writer =
new TsFileTableDiskUsageCacheWriter(mockDataRegion.getDatabaseName(),
0);
for (int i = 1; i <= 10; i++) {
@@ -264,6 +269,189 @@ public class TsFileTableSizeCacheWriterTest extends
AbstractCompactionTest {
writer.close();
Assert.assertEquals(keyFileValidLength, keyFile.length());
Assert.assertEquals(valueFileValidLength, valueFile.length());
+
+ Files.write(keyFile.toPath(), new byte[] {0, 0, 0, 0},
StandardOpenOption.APPEND);
+ writer = new
TsFileTableDiskUsageCacheWriter(mockDataRegion.getDatabaseName(), 0);
+ writer.close();
+ Assert.assertEquals(keyFileValidLength, keyFile.length());
+ Assert.assertEquals(valueFileValidLength, valueFile.length());
+
+ ByteBuffer buffer =
+
ByteBuffer.allocate(TsFileTableDiskUsageCacheWriter.KEY_FILE_OFFSET_RECORD_LENGTH);
+ TsFileID tsFileID = new TsFileID(0, 1, 2, 3, 4);
+
ReadWriteIOUtils.write(TsFileTableDiskUsageCacheWriter.KEY_FILE_RECORD_TYPE_OFFSET,
buffer);
+ ReadWriteIOUtils.write(tsFileID.timePartitionId, buffer);
+ ReadWriteIOUtils.write(tsFileID.timestamp, buffer);
+ ReadWriteIOUtils.write(tsFileID.fileVersion, buffer);
+ ReadWriteIOUtils.write(tsFileID.compactionVersion, buffer);
+ ReadWriteIOUtils.write(valueFileValidLength, buffer);
+ Files.write(
+ keyFile.toPath(),
+ Arrays.copyOf(buffer.array(), buffer.position()),
+ StandardOpenOption.APPEND);
+ writer = new
TsFileTableDiskUsageCacheWriter(mockDataRegion.getDatabaseName(), 0);
+ writer.close();
+ Assert.assertEquals(keyFileValidLength, keyFile.length());
+ Assert.assertEquals(valueFileValidLength, valueFile.length());
+
+ buffer.clear();
+ ReadWriteForEncodingUtils.writeVarInt(1, buffer);
+ ReadWriteIOUtils.writeVar("table1", buffer);
+ ReadWriteIOUtils.write(10L, buffer);
+ Files.write(
+ valueFile.toPath(),
+ Arrays.copyOf(buffer.array(), buffer.position()),
+ StandardOpenOption.APPEND);
+ writer = new
TsFileTableDiskUsageCacheWriter(mockDataRegion.getDatabaseName(), 0);
+ writer.close();
+ Assert.assertEquals(keyFileValidLength, keyFile.length());
+ Assert.assertEquals(valueFileValidLength, valueFile.length());
+ }
+
+ @Test
+ public void testRecoverWriter2() throws IOException {
+ File dir =
+ StorageEngine.getDataRegionSystemDir(
+ mockDataRegion.getDatabaseName(),
mockDataRegion.getDataRegionIdString());
+ dir.mkdirs();
+ File keyFile1 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX + "0");
+ File valueFile1 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX + "0");
+ File tempKeyFile2 =
+ new File(
+ dir,
+ TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX
+ + "1"
+ + AbstractTableSizeCacheWriter.TEMP_CACHE_FILE_SUBFIX);
+ File tempValueFile2 =
+ new File(
+ dir,
+ TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX
+ + "1"
+ + AbstractTableSizeCacheWriter.TEMP_CACHE_FILE_SUBFIX);
+
+ keyFile1.createNewFile();
+ valueFile1.createNewFile();
+ tempKeyFile2.createNewFile();
+ tempValueFile2.createNewFile();
+ TsFileTableDiskUsageCacheWriter writer =
+ new TsFileTableDiskUsageCacheWriter(mockDataRegion.getDatabaseName(),
0);
+ writer.close();
+ Assert.assertTrue(keyFile1.exists());
+ Assert.assertTrue(valueFile1.exists());
+ Assert.assertFalse(tempKeyFile2.exists());
+ Assert.assertFalse(tempValueFile2.exists());
+ Assert.assertEquals(keyFile1, writer.getKeyFile());
+ Assert.assertEquals(valueFile1, writer.getValueFile());
+ }
+
+ @Test
+ public void testRecoverWriter3() throws IOException {
+ File dir =
+ StorageEngine.getDataRegionSystemDir(
+ mockDataRegion.getDatabaseName(),
mockDataRegion.getDataRegionIdString());
+ dir.mkdirs();
+ File keyFile1 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX + "0");
+ File valueFile1 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX + "0");
+ File keyFile2 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX + "1");
+ File valueFile2 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX + "1");
+
+ keyFile1.createNewFile();
+ valueFile1.createNewFile();
+ keyFile2.createNewFile();
+ valueFile2.createNewFile();
+ TsFileTableDiskUsageCacheWriter writer =
+ new TsFileTableDiskUsageCacheWriter(mockDataRegion.getDatabaseName(),
0);
+ writer.close();
+ Assert.assertFalse(keyFile1.exists());
+ Assert.assertFalse(valueFile1.exists());
+ Assert.assertTrue(keyFile2.exists());
+ Assert.assertTrue(valueFile2.exists());
+ Assert.assertEquals(keyFile2, writer.getKeyFile());
+ Assert.assertEquals(valueFile2, writer.getValueFile());
+ }
+
+ @Test
+ public void testRecoverWriter4() throws IOException {
+ File dir =
+ StorageEngine.getDataRegionSystemDir(
+ mockDataRegion.getDatabaseName(),
mockDataRegion.getDataRegionIdString());
+ dir.mkdirs();
+ File keyFile1 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX + "0");
+ File valueFile1 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX + "0");
+ File keyFile2 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX + "1");
+ File tempValueFile2 =
+ new File(
+ dir,
+ TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX
+ + "1"
+ + AbstractTableSizeCacheWriter.TEMP_CACHE_FILE_SUBFIX);
+ File valueFile2 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX + "1");
+
+ keyFile1.createNewFile();
+ valueFile1.createNewFile();
+ keyFile2.createNewFile();
+ tempValueFile2.createNewFile();
+ TsFileTableDiskUsageCacheWriter writer =
+ new TsFileTableDiskUsageCacheWriter(mockDataRegion.getDatabaseName(),
0);
+ writer.close();
+ Assert.assertFalse(keyFile1.exists());
+ Assert.assertFalse(valueFile1.exists());
+ Assert.assertFalse(tempValueFile2.exists());
+ Assert.assertTrue(keyFile2.exists());
+ Assert.assertTrue(valueFile2.exists());
+ Assert.assertEquals(keyFile2, writer.getKeyFile());
+ Assert.assertEquals(valueFile2, writer.getValueFile());
+ }
+
+ @Test
+ public void testRecoverWriter5() throws IOException {
+ File dir =
+ StorageEngine.getDataRegionSystemDir(
+ mockDataRegion.getDatabaseName(),
mockDataRegion.getDataRegionIdString());
+ dir.mkdirs();
+ File keyFile1 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX + "1");
+ File valueFile1 =
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX + "1");
+ File tempKeyFile2 =
+ new File(
+ dir,
+ TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX
+ + "2"
+ + TsFileTableDiskUsageCacheWriter.TEMP_CACHE_FILE_SUBFIX);
+ File tempValueFile2 =
+ new File(
+ dir,
+ TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX
+ + "2"
+ + AbstractTableSizeCacheWriter.TEMP_CACHE_FILE_SUBFIX);
+
+ keyFile1.createNewFile();
+ tempKeyFile2.createNewFile();
+ tempValueFile2.createNewFile();
+ TsFileTableDiskUsageCacheWriter writer =
+ new TsFileTableDiskUsageCacheWriter(mockDataRegion.getDatabaseName(),
0);
+ writer.close();
+ Assert.assertFalse(keyFile1.exists());
+ Assert.assertFalse(valueFile1.exists());
+ Assert.assertFalse(tempValueFile2.exists());
+ Assert.assertFalse(tempKeyFile2.exists());
+ Assert.assertEquals(
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_KEY_FILENAME_PREFIX + "0"),
+ writer.getKeyFile());
+ Assert.assertEquals(
+ new File(dir,
TsFileTableDiskUsageCacheWriter.TSFILE_CACHE_VALUE_FILENAME_PREFIX + "0"),
+ writer.getValueFile());
}
private Map<String, Long> generateTableSizeMap(int tableNum) {