This is an automated email from the ASF dual-hosted git repository. JackieTien97 pushed a commit to branch rc/2.0.10 in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 17d4baf339a2d73ace4b4e9757e63adb1c315f9a Author: Hongzhi Gao <[email protected]> AuthorDate: Wed Jun 3 16:27:38 2026 +0800 Feature/iotconsensus snap multi dir (#16811) * move FolderManager to node-common module * move FolderManager to node-common module * Multi-directory snapshot support for IoTConsensus receiver * Revert "Multi-directory snapshot support for IoTConsensus receiver" This reverts commit 1fef8e49063f027d7f3c08a3d0689c20523191b0. * IoTConsensus receiver snapshot multi dirs * fix imports * Add keep same disk when loading snapshot * Use commons i18n for disk messages * Fix multi directory strategy package prefix * Fix IoTConsensus snapshot fragment placement * Use local data dirs for IoTConsensus snapshot receive * Honor folder availability for same disk selection --------- Co-authored-by: luoluoyuyu <[email protected]> --- .../iotdb/consensus/config/ConsensusConfig.java | 15 +++ .../apache/iotdb/consensus/iot/IoTConsensus.java | 32 ++++-- .../consensus/iot/IoTConsensusServerImpl.java | 96 +++++++++++++---- .../apache/iotdb/consensus/iot/ReplicateTest.java | 27 +++++ .../apache/iotdb/consensus/iot/StabilityTest.java | 8 ++ .../java/org/apache/iotdb/db/conf/IoTDBConfig.java | 13 ++- .../org/apache/iotdb/db/conf/IoTDBDescriptor.java | 6 ++ .../db/consensus/DataRegionConsensusImpl.java | 2 + .../iotconsensusv2/IoTConsensusV2Receiver.java | 6 +- .../protocol/thrift/IoTDBDataNodeReceiver.java | 6 +- .../pipe/sink/util/builder/PipeTsFileBuilder.java | 6 +- .../db/storageengine/dataregion/DataRegion.java | 2 +- .../execute/task/InnerSpaceCompactionTask.java | 2 +- .../impl/SizeTieredCompactionSelector.java | 2 +- .../dataregion/snapshot/SnapshotLoader.java | 106 ++++++++++--------- .../tsfile/generator/TsFileNameGenerator.java | 4 +- .../allocation/AbstractNodeAllocationStrategy.java | 6 +- .../db/storageengine/load/LoadTsFileManager.java | 6 +- .../storageengine/load/disk/ILoadDiskSelector.java | 2 +- .../InheritSystemMultiDisksStrategySelector.java | 2 +- .../db/storageengine/load/disk/MinIOSelector.java | 2 +- .../iotdb/db/storageengine/load/util/LoadUtil.java | 6 +- .../db/storageengine/rescon/disk/TierManager.java | 11 +- .../strategy/DirectoryStrategyTest.java | 10 +- .../iotdb/db/storageengine/dataregion/TTLTest.java | 4 +- .../BatchedCompactionWithTsFileSplitterTest.java | 16 ++- ...actionWithReadPointPerformerValidationTest.java | 4 +- .../utils/CompactionFileGeneratorUtils.java | 2 +- .../utils/MultiTsFileDeviceIteratorTest.java | 7 +- .../dataregion/snapshot/IoTDBSnapshotTest.java | 115 ++++++++++++++++++--- .../rescon/disk/FolderManagerTest.java | 5 +- .../conf/iotdb-system.properties.template | 6 ++ .../apache/iotdb/commons/i18n/UtilMessages.java | 12 +++ .../apache/iotdb/commons/i18n/UtilMessages.java | 12 +++ .../apache/iotdb/commons}/disk/FolderManager.java | 53 +++++++--- .../commons}/disk/strategy/DirectoryStrategy.java | 12 +-- .../disk/strategy/DirectoryStrategyType.java | 2 +- .../strategy/MaxDiskUsableSpaceFirstStrategy.java | 4 +- .../MinFolderOccupiedSpaceFirstStrategy.java | 8 +- .../strategy/RandomOnDiskUsableSpaceStrategy.java | 4 +- .../commons}/disk/strategy/SequenceStrategy.java | 4 +- .../exception/DiskSpaceInsufficientException.java | 4 +- 42 files changed, 478 insertions(+), 174 deletions(-) diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/config/ConsensusConfig.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/config/ConsensusConfig.java index a4bc9852035..f834e41a4c9 100644 --- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/config/ConsensusConfig.java +++ b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/config/ConsensusConfig.java @@ -22,6 +22,7 @@ package org.apache.iotdb.consensus.config; import org.apache.iotdb.common.rpc.thrift.TConsensusGroupType; import org.apache.iotdb.common.rpc.thrift.TEndPoint; +import java.util.List; import java.util.Optional; public class ConsensusConfig { @@ -29,6 +30,7 @@ public class ConsensusConfig { private final TEndPoint thisNodeEndPoint; private final int thisNodeId; private final String storageDir; + private final List<String> recvSnapshotDirs; private final TConsensusGroupType consensusGroupType; private final RatisConfig ratisConfig; private final IoTConsensusConfig iotConsensusConfig; @@ -38,6 +40,7 @@ public class ConsensusConfig { TEndPoint thisNode, int thisNodeId, String storageDir, + List<String> recvSnapshotDirs, TConsensusGroupType consensusGroupType, RatisConfig ratisConfig, IoTConsensusConfig iotConsensusConfig, @@ -45,6 +48,7 @@ public class ConsensusConfig { this.thisNodeEndPoint = thisNode; this.thisNodeId = thisNodeId; this.storageDir = storageDir; + this.recvSnapshotDirs = recvSnapshotDirs; this.consensusGroupType = consensusGroupType; this.ratisConfig = ratisConfig; this.iotConsensusConfig = iotConsensusConfig; @@ -63,6 +67,10 @@ public class ConsensusConfig { return storageDir; } + public List<String> getRecvSnapshotDirs() { + return recvSnapshotDirs; + } + public TConsensusGroupType getConsensusGroupType() { return consensusGroupType; } @@ -88,6 +96,7 @@ public class ConsensusConfig { private TEndPoint thisNode; private int thisNodeId; private String storageDir; + private List<String> recvSnapshotDirs; private TConsensusGroupType consensusGroupType; private RatisConfig ratisConfig; private IoTConsensusConfig iotConsensusConfig; @@ -98,6 +107,7 @@ public class ConsensusConfig { thisNode, thisNodeId, storageDir, + recvSnapshotDirs, consensusGroupType, Optional.ofNullable(ratisConfig).orElseGet(() -> RatisConfig.newBuilder().build()), Optional.ofNullable(iotConsensusConfig) @@ -121,6 +131,11 @@ public class ConsensusConfig { return this; } + public Builder setRecvSnapshotDirs(List<String> recvSnapshotDirs) { + this.recvSnapshotDirs = recvSnapshotDirs; + return this; + } + public Builder setConsensusGroupType(TConsensusGroupType groupType) { this.consensusGroupType = groupType; return this; diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensus.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensus.java index f3895d3edaf..d84f0a5aa81 100644 --- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensus.java +++ b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensus.java @@ -26,6 +26,7 @@ import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory; import org.apache.iotdb.commons.concurrent.ThreadName; import org.apache.iotdb.commons.concurrent.threadpool.ScheduledExecutorUtil; import org.apache.iotdb.commons.consensus.ConsensusGroupId; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.exception.StartupException; import org.apache.iotdb.commons.request.IConsensusRequest; import org.apache.iotdb.commons.service.RegisterManager; @@ -94,6 +95,7 @@ public class IoTConsensus implements IConsensus { private final TEndPoint thisNode; private final int thisNodeId; private final File storageDir; + private final List<String> recvSnapshotDirs; private final IStateMachine.Registry registry; private final Map<ConsensusGroupId, IoTConsensusServerImpl> stateMachineMap = new ConcurrentHashMap<>(); @@ -110,6 +112,7 @@ public class IoTConsensus implements IConsensus { this.thisNode = config.getThisNodeEndPoint(); this.thisNodeId = config.getThisNodeId(); this.storageDir = new File(config.getStorageDir()); + this.recvSnapshotDirs = config.getRecvSnapshotDirs(); this.config = config.getIotConsensusConfig(); this.registry = registry; this.service = new IoTConsensusRPCService(thisNode, config.getIotConsensusConfig()); @@ -177,6 +180,7 @@ public class IoTConsensus implements IConsensus { IoTConsensusServerImpl consensus = new IoTConsensusServerImpl( path.toString(), + recvSnapshotDirs, new Peer(consensusGroupId, thisNodeId, thisNode), new TreeSet<>(), registry.apply(consensusGroupId), @@ -186,6 +190,8 @@ public class IoTConsensus implements IConsensus { config); stateMachineMap.put(consensusGroupId, consensus); } + } catch (DiskSpaceInsufficientException e) { + throw new IOException(e); } } if (correctPeerListBeforeStart != null) { @@ -283,16 +289,22 @@ public class IoTConsensus implements IConsensus { return null; } - IoTConsensusServerImpl impl = - new IoTConsensusServerImpl( - path, - new Peer(groupId, thisNodeId, thisNode), - new TreeSet<>(peers), - registry.apply(groupId), - backgroundTaskService, - clientManager, - syncClientManager, - config); + IoTConsensusServerImpl impl = null; + try { + impl = + new IoTConsensusServerImpl( + path, + recvSnapshotDirs, + new Peer(groupId, thisNodeId, thisNode), + new TreeSet<>(peers), + registry.apply(groupId), + backgroundTaskService, + clientManager, + syncClientManager, + config); + } catch (DiskSpaceInsufficientException e) { + throw new RuntimeException(e); + } impl.start(); return impl; })) diff --git a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java index 74ba871643b..33ff3a4c273 100644 --- a/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java +++ b/iotdb-core/consensus/src/main/java/org/apache/iotdb/consensus/iot/IoTConsensusServerImpl.java @@ -26,6 +26,9 @@ import org.apache.iotdb.commons.client.exception.ClientManagerException; import org.apache.iotdb.commons.consensus.ConsensusGroupId; import org.apache.iotdb.commons.consensus.index.ComparableConsensusRequest; import org.apache.iotdb.commons.consensus.index.impl.IoTProgressIndex; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.request.IConsensusRequest; import org.apache.iotdb.commons.service.metric.MetricService; import org.apache.iotdb.commons.service.metric.PerformanceOverviewMetrics; @@ -115,6 +118,7 @@ public class IoTConsensusServerImpl { private final Lock stateMachineLock = new ReentrantLock(); private final Condition stateMachineCondition = stateMachineLock.newCondition(); private final String storageDir; + private FolderManager recvFolderManager = null; private final TreeSet<Peer> configuration; private final AtomicLong searchIndex; private final LogDispatcher logDispatcher; @@ -132,15 +136,29 @@ public class IoTConsensusServerImpl { public IoTConsensusServerImpl( String storageDir, + List<String> recvSnapshotDirs, Peer thisNode, TreeSet<Peer> configuration, IStateMachine stateMachine, ScheduledExecutorService backgroundTaskService, IClientManager<TEndPoint, AsyncIoTConsensusServiceClient> clientManager, IClientManager<TEndPoint, SyncIoTConsensusServiceClient> syncClientManager, - IoTConsensusConfig config) { + IoTConsensusConfig config) + throws DiskSpaceInsufficientException { this.active = true; this.storageDir = storageDir; + List<String> snapshotDirs = new ArrayList<>(); + if (recvSnapshotDirs != null) { + for (String dir : recvSnapshotDirs) { + snapshotDirs.add(dir + File.separator + SNAPSHOT_DIR_NAME); + } + } else { + snapshotDirs.add(storageDir); + } + + this.recvFolderManager = + new FolderManager( + snapshotDirs, DirectoryStrategyType.MIN_FOLDER_OCCUPIED_SPACE_FIRST_STRATEGY); this.thisNode = thisNode; this.stateMachine = stateMachine; this.cacheQueueMap = new ConcurrentHashMap<>(); @@ -360,18 +378,45 @@ public class IoTConsensusServerImpl { throws ConsensusGroupModifyPeerException { try { String targetFilePath = calculateSnapshotPath(snapshotId, originalFilePath); - File targetFile = getSnapshotPath(targetFilePath); - Path parentDir = Paths.get(targetFile.getParent()); - if (!Files.exists(parentDir)) { - Files.createDirectories(parentDir); - } - try (FileOutputStream fos = new FileOutputStream(targetFile.getAbsolutePath(), true); - FileChannel channel = fos.getChannel()) { - channel.write(fileChunk.slice(), fileOffset); + File existingFile = getExistingSnapshotFile(targetFilePath); + if (existingFile != null) { + writeSnapshotFragment(existingFile, fileChunk, fileOffset); + return; } + + recvFolderManager.getNextWithRetry( + folder -> { + writeSnapshotFragment(getSnapshotPath(folder, targetFilePath), fileChunk, fileOffset); + return null; + }); } catch (IOException e) { throw new ConsensusGroupModifyPeerException( String.format(IoTConsensusMessages.ERROR_RECEIVING_SNAPSHOT, snapshotId), e); + } catch (DiskSpaceInsufficientException e) { + throw new ConsensusGroupModifyPeerException( + String.format(IoTConsensusMessages.ERROR_RECEIVING_SNAPSHOT, snapshotId), e); + } + } + + private File getExistingSnapshotFile(String targetFilePath) { + for (String folder : recvFolderManager.getFolders()) { + File targetFile = getSnapshotPath(folder, targetFilePath); + if (targetFile.exists()) { + return targetFile; + } + } + return null; + } + + private void writeSnapshotFragment(File targetFile, ByteBuffer fileChunk, long fileOffset) + throws IOException { + Path parentDir = Paths.get(targetFile.getParent()); + if (!Files.exists(parentDir)) { + Files.createDirectories(parentDir); + } + try (FileOutputStream fos = new FileOutputStream(targetFile.getAbsolutePath(), true); + FileChannel channel = fos.getChannel()) { + channel.write(fileChunk.slice(), fileOffset); } } @@ -404,12 +449,17 @@ public class IoTConsensusServerImpl { public void loadSnapshot(String snapshotId) { // TODO: (xingtanzjr) throw exception if the snapshot load failed - stateMachine.loadSnapshot(getSnapshotPath(snapshotId)); + recvFolderManager + .getFolders() + .forEach( + dir -> { + stateMachine.loadSnapshot(getSnapshotPath(dir, snapshotId)); + }); } - private File getSnapshotPath(String snapshotRelativePath) { - File storageDirFile = new File(storageDir); - File snapshotDir = new File(storageDir, snapshotRelativePath); + private File getSnapshotPath(String curStorageDir, String snapshotRelativePath) { + File storageDirFile = new File(curStorageDir); + File snapshotDir = new File(curStorageDir, snapshotRelativePath); try { if (!snapshotDir .getCanonicalFile() @@ -829,15 +879,19 @@ public class IoTConsensusServerImpl { } public void cleanupSnapshot(String snapshotId) throws ConsensusGroupModifyPeerException { - File snapshotDir = getSnapshotPath(snapshotId); - if (snapshotDir.exists()) { - try { - FileUtils.deleteDirectory(snapshotDir); - } catch (IOException e) { - throw new ConsensusGroupModifyPeerException(e); + List<String> allDirs = new ArrayList<>(Collections.singletonList(storageDir)); + allDirs.addAll(recvFolderManager.getFolders()); + for (String dir : allDirs) { + File snapshotDir = getSnapshotPath(dir, snapshotId); + if (snapshotDir.exists()) { + try { + FileUtils.deleteDirectory(snapshotDir); + } catch (IOException e) { + throw new ConsensusGroupModifyPeerException(e); + } + } else { + logger.info(IoTConsensusMessages.FILE_NOT_EXIST, snapshotDir); } - } else { - logger.info(IoTConsensusMessages.FILE_NOT_EXIST, snapshotDir); } } diff --git a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/ReplicateTest.java b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/ReplicateTest.java index f22d3fdadcd..ca96ffec485 100644 --- a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/ReplicateTest.java +++ b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/ReplicateTest.java @@ -71,6 +71,21 @@ public class ReplicateTest { new File("target" + File.separator + "2"), new File("target" + File.separator + "3")); + private final List<List<String>> peersRecvSnapshotDirs = + Arrays.asList( + Arrays.asList( + "target" + File.separator + "1-1", + "target" + File.separator + "1-2", + "target" + File.separator + "1-3"), + Arrays.asList( + "target" + File.separator + "2-1", + "target" + File.separator + "2-2", + "target" + File.separator + "2-3"), + Arrays.asList( + "target" + File.separator + "3-1", + "target" + File.separator + "3-2", + "target" + File.separator + "3-3")); + private final ConsensusGroup group = new ConsensusGroup(gid, peers); private final List<IoTConsensus> servers = new ArrayList<>(); private final List<TestStateMachine> stateMachines = new ArrayList<>(); @@ -81,6 +96,7 @@ public class ReplicateTest { file.mkdirs(); stateMachines.add(new TestStateMachine()); } + peersRecvSnapshotDirs.forEach(innerList -> innerList.forEach(dir -> new File(dir).mkdirs())); initServer(); } @@ -90,6 +106,16 @@ public class ReplicateTest { for (File file : peersStorage) { FileUtils.deleteFully(file); } + peersRecvSnapshotDirs.forEach( + innerList -> + innerList.forEach( + dir -> { + try { + FileUtils.deleteFully(new File(dir)); + } catch (IOException e) { + throw new RuntimeException(e); + } + })); } private void initServer() throws IOException { @@ -105,6 +131,7 @@ public class ReplicateTest { .setThisNodeId(peers.get(i).getNodeId()) .setThisNode(peers.get(i).getEndpoint()) .setStorageDir(peersStorage.get(i).getAbsolutePath()) + .setRecvSnapshotDirs(peersRecvSnapshotDirs.get(i)) .setConsensusGroupType(TConsensusGroupType.DataRegion) .build(), groupId -> stateMachines.get(finalI)) diff --git a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/StabilityTest.java b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/StabilityTest.java index 1351b674312..9844b2f1e7e 100644 --- a/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/StabilityTest.java +++ b/iotdb-core/consensus/src/test/java/org/apache/iotdb/consensus/iot/StabilityTest.java @@ -45,6 +45,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -60,6 +61,12 @@ public class StabilityTest { private final File storageDir = new File("target" + java.io.File.separator + "stability"); + private final List<String> recvSnapshotDirs = + Arrays.asList( + "target" + File.separator + "1-1", + "target" + File.separator + "1-2", + "target" + File.separator + "1-3"); + private IoTConsensus consensusImpl; private final int basePort = 6667; @@ -73,6 +80,7 @@ public class StabilityTest { .setThisNodeId(1) .setThisNode(new TEndPoint("0.0.0.0", basePort)) .setStorageDir(storageDir.getAbsolutePath()) + .setRecvSnapshotDirs(recvSnapshotDirs) .setConsensusGroupType(TConsensusGroupType.DataRegion) .build(), gid -> new TestStateMachine()) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java index fbc817d4f61..84fb1fef329 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java @@ -87,8 +87,7 @@ public class IoTDBConfig { public static final String WATERMARK_GROUPED_LSB = "GroupBasedLSBMethod"; public static final String CONFIG_NAME = "iotdb-system.properties"; private static final Logger logger = LoggerFactory.getLogger(IoTDBConfig.class); - private static final String MULTI_DIR_STRATEGY_PREFIX = - "org.apache.iotdb.db.storageengine.rescon.disk.strategy."; + private static final String MULTI_DIR_STRATEGY_PREFIX = "org.apache.iotdb.commons.disk.strategy."; private static final String[] CLUSTER_ALLOWED_MULTI_DIR_STRATEGIES = new String[] {"SequenceStrategy", "MaxDiskUsableSpaceFirstStrategy"}; private static final String DEFAULT_MULTI_DIR_STRATEGY = "SequenceStrategy"; @@ -1219,6 +1218,8 @@ public class IoTDBConfig { private boolean includeNullValueInWriteThroughputMetric = false; + private boolean keepSameDiskWhenLoadingSnapshot = false; + private ConcurrentHashMap<String, EncryptParameter> tsFileDBToEncryptMap = new ConcurrentHashMap<>( Collections.singletonMap("root.__audit", new EncryptParameter("UNENCRYPTED", null))); @@ -4434,6 +4435,14 @@ public class IoTDBConfig { this.passwordLockTimeMinutes = passwordLockTimeMinutes; } + public boolean isKeepSameDiskWhenLoadingSnapshot() { + return keepSameDiskWhenLoadingSnapshot; + } + + public void setKeepSameDiskWhenLoadingSnapshot(boolean keepSameDiskWhenLoadingSnapshot) { + this.keepSameDiskWhenLoadingSnapshot = keepSameDiskWhenLoadingSnapshot; + } + public ConcurrentHashMap<String, EncryptParameter> getTSFileDBToEncryptMap() { return tsFileDBToEncryptMap; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java index 5debbb71972..8cba13b2265 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java @@ -1285,6 +1285,12 @@ public class IoTDBDescriptor { "region_migration_speed_limit_bytes_per_second", ConfigurationFileUtils.getConfigurationDefaultValue( "region_migration_speed_limit_bytes_per_second")))); + conf.setKeepSameDiskWhenLoadingSnapshot( + Boolean.parseBoolean( + properties.getProperty( + "keep_same_disk_when_loading_snapshot", + ConfigurationFileUtils.getConfigurationDefaultValue( + "keep_same_disk_when_loading_snapshot")))); } private void loadIoTConsensusV2Props(TrimProperties properties) throws IOException { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/DataRegionConsensusImpl.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/DataRegionConsensusImpl.java index e96b7495312..6fc3bbdb596 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/DataRegionConsensusImpl.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/consensus/DataRegionConsensusImpl.java @@ -55,6 +55,7 @@ import org.apache.ratis.util.TimeDuration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Arrays; import java.util.concurrent.TimeUnit; /** @@ -139,6 +140,7 @@ public class DataRegionConsensusImpl { .setThisNodeId(CONF.getDataNodeId()) .setThisNode(new TEndPoint(CONF.getInternalAddress(), CONF.getDataRegionConsensusPort())) .setStorageDir(CONF.getDataRegionConsensusDir()) + .setRecvSnapshotDirs(Arrays.asList(CONF.getLocalDataDirs())) .setConsensusGroupType(TConsensusGroupType.DataRegion) .setIoTConsensusConfig( IoTConsensusConfig.newBuilder() diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/iotconsensusv2/IoTConsensusV2Receiver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/iotconsensusv2/IoTConsensusV2Receiver.java index 59905e54dad..7d01318c82e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/iotconsensusv2/IoTConsensusV2Receiver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/iotconsensusv2/IoTConsensusV2Receiver.java @@ -27,6 +27,9 @@ import org.apache.iotdb.commons.consensus.ConsensusGroupId; import org.apache.iotdb.commons.consensus.DataRegionId; import org.apache.iotdb.commons.consensus.index.ProgressIndex; import org.apache.iotdb.commons.consensus.index.ProgressIndexType; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.pipe.receiver.IoTDBReceiverAgent; import org.apache.iotdb.commons.pipe.receiver.PipeReceiverFilePathUtils; import org.apache.iotdb.commons.pipe.sink.payload.iotconsensusv2.request.IoTConsensusV2RequestType; @@ -45,7 +48,6 @@ import org.apache.iotdb.consensus.pipe.IoTConsensusV2ServerImpl; import org.apache.iotdb.consensus.pipe.consensuspipe.ConsensusPipeName; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.exception.load.LoadFileException; import org.apache.iotdb.db.i18n.DataNodePipeMessages; import org.apache.iotdb.db.pipe.consensus.metric.IoTConsensusV2ReceiverMetrics; @@ -65,8 +67,6 @@ import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus; import org.apache.iotdb.db.storageengine.dataregion.utils.TableDiskUsageStatisticUtil; import org.apache.iotdb.db.storageengine.dataregion.utils.TsFileResourceUtils; import org.apache.iotdb.db.storageengine.load.LoadTsFileManager; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.apache.iotdb.rpc.RpcUtils; import org.apache.iotdb.rpc.TSStatusCode; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java index 55f46be8f99..c1c81a1200d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/receiver/protocol/thrift/IoTDBDataNodeReceiver.java @@ -22,6 +22,9 @@ package org.apache.iotdb.db.pipe.receiver.protocol.thrift; import org.apache.iotdb.common.rpc.thrift.TSStatus; import org.apache.iotdb.commons.audit.IAuditEntity; import org.apache.iotdb.commons.conf.IoTDBConstant; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.exception.pipe.PipeRuntimeOutOfMemoryCriticalException; import org.apache.iotdb.commons.path.PartialPath; @@ -45,7 +48,6 @@ import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema; import org.apache.iotdb.db.auth.AuthorityChecker; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.DataNodePipeMessages; import org.apache.iotdb.db.pipe.agent.PipeDataNodeAgent; import org.apache.iotdb.db.pipe.event.common.schema.PipeSchemaRegionSnapshotEvent; @@ -102,8 +104,6 @@ import org.apache.iotdb.db.queryengine.plan.statement.pipe.PipeEnrichedStatement import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache; import org.apache.iotdb.db.storageengine.load.active.ActiveLoadPathHelper; import org.apache.iotdb.db.storageengine.load.util.LoadUtil; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.apache.iotdb.db.tools.schema.SRStatementGenerator; import org.apache.iotdb.db.tools.schema.SchemaRegionSnapshotParser; import org.apache.iotdb.pipe.api.exception.PipeException; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/util/builder/PipeTsFileBuilder.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/util/builder/PipeTsFileBuilder.java index cd78f4fdbe4..f84c1fe63f1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/util/builder/PipeTsFileBuilder.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/sink/util/builder/PipeTsFileBuilder.java @@ -19,11 +19,11 @@ package org.apache.iotdb.db.pipe.sink.util.builder; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.DataNodePipeMessages; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.apache.iotdb.pipe.api.exception.PipeException; import org.apache.tsfile.common.constant.TsFileConstant; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index 784d4fa4771..2f04d225d08 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -29,6 +29,7 @@ import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory; import org.apache.iotdb.commons.conf.CommonDescriptor; import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.consensus.DataRegionId; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.file.SystemFileFactory; import org.apache.iotdb.commons.path.IFullPath; @@ -60,7 +61,6 @@ import org.apache.iotdb.db.consensus.DataRegionConsensusImpl; import org.apache.iotdb.db.exception.BatchProcessException; import org.apache.iotdb.db.exception.DataRegionException; import org.apache.iotdb.db.exception.DataTypeInconsistentException; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.exception.TsFileProcessorException; import org.apache.iotdb.db.exception.WriteProcessException; import org.apache.iotdb.db.exception.WriteProcessRejectException; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InnerSpaceCompactionTask.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InnerSpaceCompactionTask.java index 85614ac6457..94b8d7bb016 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InnerSpaceCompactionTask.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/execute/task/InnerSpaceCompactionTask.java @@ -19,10 +19,10 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction.execute.task; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.utils.PathUtils; import org.apache.iotdb.commons.utils.TestOnly; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.StorageEngineMessages; import org.apache.iotdb.db.service.metrics.CompactionMetrics; import org.apache.iotdb.db.service.metrics.FileMetrics; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SizeTieredCompactionSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SizeTieredCompactionSelector.java index 41ca9251eff..80b7541df51 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SizeTieredCompactionSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/compaction/selector/impl/SizeTieredCompactionSelector.java @@ -20,9 +20,9 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction.selector.impl; import org.apache.iotdb.commons.conf.IoTDBConstant; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.StorageEngineMessages; import org.apache.iotdb.db.storageengine.dataregion.compaction.execute.performer.ICompactionPerformer; import org.apache.iotdb.db.storageengine.dataregion.compaction.execute.task.InnerSpaceCompactionTask; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotLoader.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotLoader.java index 307930cbfbf..c32f2301289 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotLoader.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/SnapshotLoader.java @@ -20,14 +20,14 @@ package org.apache.iotdb.db.storageengine.dataregion.snapshot; import org.apache.iotdb.commons.conf.IoTDBConstant; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.StorageEngineMessages; import org.apache.iotdb.db.storageengine.StorageEngine; import org.apache.iotdb.db.storageengine.dataregion.DataRegion; import org.apache.iotdb.db.storageengine.dataregion.flush.CompressionRatio; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.apache.tsfile.external.commons.io.FileUtils; import org.slf4j.Logger; @@ -315,57 +315,69 @@ public class SnapshotLoader { } } + private File createLinksFromSnapshotToSourceDir( + String targetSuffix, + File file, + Map<String, String> fileTarget, + String fileKey, + String finalDir) + throws IOException { + File targetFile = + new File(finalDir + File.separator + targetSuffix + File.separator + file.getName()); + + try { + if (!targetFile.getParentFile().exists() && !targetFile.getParentFile().mkdirs()) { + throw new IOException( + String.format( + "Cannot create directory %s", targetFile.getParentFile().getAbsolutePath())); + } + + try { + Files.createLink(targetFile.toPath(), file.toPath()); + LOGGER.debug("Created hard link from {} to {}", file, targetFile); + fileTarget.put(fileKey, finalDir); + return targetFile; + } catch (IOException e) { + LOGGER.info("Cannot create link from {} to {}, fallback to copy", file, targetFile); + } + + Files.copy(file.toPath(), targetFile.toPath()); + fileTarget.put(fileKey, finalDir); + return targetFile; + } catch (Exception e) { + LOGGER.warn( + "Failed to process file {} in dir {}: {}", file.getName(), finalDir, e.getMessage(), e); + throw e; + } + } + private void createLinksFromSnapshotToSourceDir( - String targetSuffix, File[] files, FolderManager folderManager) - throws DiskSpaceInsufficientException, IOException { + String targetSuffix, File[] files, FolderManager folderManager) throws IOException { Map<String, String> fileTarget = new HashMap<>(); for (File file : files) { String fileKey = file.getName().split("\\.")[0]; String dataDir = fileTarget.get(fileKey); + if (dataDir != null) { + createLinksFromSnapshotToSourceDir(targetSuffix, file, fileTarget, fileKey, dataDir); + continue; + } + try { - folderManager.getNextWithRetry( - currentDataDir -> { - String effectiveDir = (dataDir != null) ? dataDir : currentDataDir; - File targetFile = - new File( - effectiveDir - + File.separator - + targetSuffix - + File.separator - + file.getName()); - - try { - if (!targetFile.getParentFile().exists() && !targetFile.getParentFile().mkdirs()) { - throw new IOException( - String.format( - "Cannot create directory %s", - targetFile.getParentFile().getAbsolutePath())); - } - - try { - Files.createLink(targetFile.toPath(), file.toPath()); - LOGGER.debug(StorageEngineMessages.CREATED_HARD_LINK, file, targetFile); - fileTarget.put(fileKey, effectiveDir); - return targetFile; - } catch (IOException e) { - LOGGER.info( - "Cannot create link from {} to {}, fallback to copy", file, targetFile); - } - - Files.copy(file.toPath(), targetFile.toPath()); - fileTarget.put(fileKey, effectiveDir); - return targetFile; - } catch (Exception e) { - LOGGER.warn( - "Failed to process file {} in dir {}: {}", - file.getName(), - effectiveDir, - e.getMessage(), - e); - throw e; - } - }); + String firstFolderOfSameDisk = + IoTDBDescriptor.getInstance().getConfig().isKeepSameDiskWhenLoadingSnapshot() + ? folderManager.getFirstFolderOfSameDisk(file.getAbsolutePath()) + : null; + + if (firstFolderOfSameDisk != null) { + createLinksFromSnapshotToSourceDir( + targetSuffix, file, fileTarget, fileKey, firstFolderOfSameDisk); + } else { + folderManager.getNextWithRetry( + currentDataDir -> + createLinksFromSnapshotToSourceDir( + targetSuffix, file, fileTarget, fileKey, currentDataDir)); + } } catch (Exception e) { throw new IOException( String.format( diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/generator/TsFileNameGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/generator/TsFileNameGenerator.java index 0fbbd5e386f..37c8f1a964f 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/generator/TsFileNameGenerator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/generator/TsFileNameGenerator.java @@ -20,12 +20,12 @@ package org.apache.iotdb.db.storageengine.dataregion.tsfile.generator; import org.apache.iotdb.commons.conf.IoTDBConstant; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.utils.TestOnly; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.StorageEngineMessages; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; import org.apache.iotdb.db.storageengine.rescon.disk.TierManager; import org.apache.tsfile.common.constant.TsFileConstant; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java index 307fab91445..de97bb313f6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/wal/allocation/AbstractNodeAllocationStrategy.java @@ -21,13 +21,13 @@ package org.apache.iotdb.db.storageengine.dataregion.wal.allocation; import org.apache.iotdb.commons.conf.CommonConfig; import org.apache.iotdb.commons.conf.CommonDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.StorageEngineMessages; import org.apache.iotdb.db.storageengine.dataregion.wal.node.IWALNode; import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALFakeNode; import org.apache.iotdb.db.storageengine.dataregion.wal.node.WALNode; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/LoadTsFileManager.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/LoadTsFileManager.java index c43f2b533ab..e3c6948563a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/LoadTsFileManager.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/LoadTsFileManager.java @@ -25,6 +25,9 @@ import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.consensus.ConsensusGroupId; import org.apache.iotdb.commons.consensus.index.ProgressIndex; import org.apache.iotdb.commons.consensus.index.impl.MinimumProgressIndex; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.file.SystemFileFactory; import org.apache.iotdb.commons.schema.table.TsFileTableSchemaUtil; import org.apache.iotdb.commons.schema.table.TsTable; @@ -37,7 +40,6 @@ import org.apache.iotdb.commons.utils.RetryUtils; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.consensus.DataRegionConsensusImpl; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.exception.load.LoadFileException; import org.apache.iotdb.db.i18n.StorageEngineMessages; import org.apache.iotdb.db.pipe.agent.PipeDataNodeAgent; @@ -54,8 +56,6 @@ import org.apache.iotdb.db.storageengine.load.active.ActiveLoadAgent; import org.apache.iotdb.db.storageengine.load.splitter.ChunkData; import org.apache.iotdb.db.storageengine.load.splitter.DeletionData; import org.apache.iotdb.db.storageengine.load.splitter.TsFileData; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.apache.iotdb.metrics.utils.MetricLevel; import com.github.benmanes.caffeine.cache.Cache; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java index e9216e9b555..b013c7e9ad4 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java @@ -19,7 +19,7 @@ package org.apache.iotdb.db.storageengine.load.disk; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.exception.load.LoadFileException; import java.io.File; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java index c56addc4bf9..c937f8fa966 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java @@ -19,7 +19,7 @@ package org.apache.iotdb.db.storageengine.load.disk; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.exception.load.LoadFileException; import org.apache.tsfile.fileSystem.FSFactoryProducer; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java index 8f572fd569b..9be9c98d079 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java @@ -19,7 +19,7 @@ package org.apache.iotdb.db.storageengine.load.disk; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.exception.load.LoadFileException; import org.apache.iotdb.db.i18n.StorageEngineMessages; import org.apache.iotdb.metrics.utils.FileStoreUtils; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/util/LoadUtil.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/util/LoadUtil.java index 098a6ac6b49..cafb1b0e700 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/util/LoadUtil.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/util/LoadUtil.java @@ -19,17 +19,17 @@ package org.apache.iotdb.db.storageengine.load.util; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.utils.RetryUtils; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.StorageEngineMessages; import org.apache.iotdb.db.storageengine.dataregion.modification.ModificationFile; import org.apache.iotdb.db.storageengine.dataregion.modification.v1.ModificationFileV1; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource; import org.apache.iotdb.db.storageengine.load.active.ActiveLoadPathHelper; import org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java index 6929b53c9c7..200be139664 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/TierManager.java @@ -20,14 +20,15 @@ package org.apache.iotdb.db.storageengine.rescon.disk; import org.apache.iotdb.commons.conf.CommonDescriptor; import org.apache.iotdb.commons.conf.IoTDBConstant; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.disk.strategy.MaxDiskUsableSpaceFirstStrategy; +import org.apache.iotdb.commons.disk.strategy.MinFolderOccupiedSpaceFirstStrategy; +import org.apache.iotdb.commons.disk.strategy.RandomOnDiskUsableSpaceStrategy; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.conf.IoTDBDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.i18n.StorageEngineMessages; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.MaxDiskUsableSpaceFirstStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.MinFolderOccupiedSpaceFirstStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.RandomOnDiskUsableSpaceStrategy; import org.apache.iotdb.metrics.utils.FileStoreUtils; import com.google.common.io.BaseEncoding; diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategyTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategyTest.java index 1a95ca32768..6343dcc1699 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategyTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategyTest.java @@ -18,12 +18,12 @@ */ package org.apache.iotdb.db.conf.directories.strategy; +import org.apache.iotdb.commons.disk.strategy.MaxDiskUsableSpaceFirstStrategy; +import org.apache.iotdb.commons.disk.strategy.MinFolderOccupiedSpaceFirstStrategy; +import org.apache.iotdb.commons.disk.strategy.RandomOnDiskUsableSpaceStrategy; +import org.apache.iotdb.commons.disk.strategy.SequenceStrategy; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.utils.JVMCommonUtils; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.MaxDiskUsableSpaceFirstStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.MinFolderOccupiedSpaceFirstStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.RandomOnDiskUsableSpaceStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.SequenceStrategy; import org.apache.iotdb.db.utils.constant.TestConstant; import org.junit.After; diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/TTLTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/TTLTest.java index c211bc360ad..06ec607a704 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/TTLTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/TTLTest.java @@ -24,6 +24,7 @@ import org.apache.iotdb.calc.exception.QueryProcessException; import org.apache.iotdb.commons.conf.CommonDescriptor; import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.consensus.DataRegionId; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.path.NonAlignedFullPath; @@ -327,7 +328,8 @@ public class TTLTest { throws StorageEngineException, WriteProcessException, IllegalPathException, - InterruptedException { + InterruptedException, + DiskSpaceInsufficientException { boolean isEnableCrossCompaction = IoTDBDescriptor.getInstance().getConfig().isEnableCrossSpaceCompaction(); IoTDBDescriptor.getInstance().getConfig().setEnableCrossSpaceCompaction(false); diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/BatchedCompactionWithTsFileSplitterTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/BatchedCompactionWithTsFileSplitterTest.java index 1ee72fa5f68..5c2bf1c8e43 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/BatchedCompactionWithTsFileSplitterTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/BatchedCompactionWithTsFileSplitterTest.java @@ -20,6 +20,7 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction; import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.path.MeasurementPath; @@ -97,7 +98,8 @@ public class BatchedCompactionWithTsFileSplitterTest extends AbstractCompactionT InterruptedException, MetadataException, PageException, - LoadFileException { + LoadFileException, + DiskSpaceInsufficientException { TsFileResource seqResource1 = generateSingleAlignedSeriesFile( "d0", @@ -132,7 +134,8 @@ public class BatchedCompactionWithTsFileSplitterTest extends AbstractCompactionT InterruptedException, MetadataException, PageException, - LoadFileException { + LoadFileException, + DiskSpaceInsufficientException { TsFileResource seqResource1 = generateSingleAlignedSeriesFile( "d0", @@ -167,7 +170,8 @@ public class BatchedCompactionWithTsFileSplitterTest extends AbstractCompactionT InterruptedException, MetadataException, PageException, - LoadFileException { + LoadFileException, + DiskSpaceInsufficientException { TsFileResource seqResource1 = generateSingleAlignedSeriesFile( "d0", @@ -206,7 +210,8 @@ public class BatchedCompactionWithTsFileSplitterTest extends AbstractCompactionT InterruptedException, MetadataException, PageException, - LoadFileException { + LoadFileException, + DiskSpaceInsufficientException { TsFileResource seqResource1 = generateSingleAlignedSeriesFile( "d0", @@ -319,7 +324,8 @@ public class BatchedCompactionWithTsFileSplitterTest extends AbstractCompactionT IOException, PageException, InterruptedException, - MetadataException { + MetadataException, + DiskSpaceInsufficientException { TsFileResource targetResource = TsFileNameGenerator.getInnerCompactionTargetFileResource(seqResources, true); diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/cross/CrossSpaceCompactionWithReadPointPerformerValidationTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/cross/CrossSpaceCompactionWithReadPointPerformerValidationTest.java index b05ab1e633e..7b0c88079d7 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/cross/CrossSpaceCompactionWithReadPointPerformerValidationTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/cross/CrossSpaceCompactionWithReadPointPerformerValidationTest.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction.cross; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.path.AlignedFullPath; @@ -2101,7 +2102,8 @@ public class CrossSpaceCompactionWithReadPointPerformerValidationTest WriteProcessException, StorageEngineException, InterruptedException, - MergeException { + MergeException, + DiskSpaceInsufficientException { registerTimeseriesInMManger(5, 10, true); createFiles(5, 10, 5, 1000, 0, 0, 100, 100, false, true); createFiles(1, 5, 10, 4500, 500, 500, 0, 100, false, false); diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionFileGeneratorUtils.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionFileGeneratorUtils.java index 2573a95d1da..fff273adf76 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionFileGeneratorUtils.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionFileGeneratorUtils.java @@ -20,10 +20,10 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction.utils; import org.apache.iotdb.commons.conf.IoTDBConstant; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.exception.IllegalPathException; import org.apache.iotdb.commons.path.MeasurementPath; import org.apache.iotdb.commons.path.PartialPath; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.iotdb.db.storageengine.dataregion.modification.ModEntry; import org.apache.iotdb.db.storageengine.dataregion.modification.ModificationFile; import org.apache.iotdb.db.storageengine.dataregion.modification.TreeDeletionEntry; diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/MultiTsFileDeviceIteratorTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/MultiTsFileDeviceIteratorTest.java index 1180247a2d3..b5010e60449 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/MultiTsFileDeviceIteratorTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/MultiTsFileDeviceIteratorTest.java @@ -19,6 +19,7 @@ package org.apache.iotdb.db.storageengine.dataregion.compaction.utils; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.path.AlignedFullPath; import org.apache.iotdb.commons.path.IFullPath; @@ -412,7 +413,8 @@ public class MultiTsFileDeviceIteratorTest extends AbstractCompactionTest { IOException, WriteProcessException, StorageEngineException, - InterruptedException { + InterruptedException, + DiskSpaceInsufficientException { TSFileDescriptor.getInstance().getConfig().setMaxDegreeOfIndexNode(3); int oldAlignedDeviceOffset = TsFileGeneratorUtils.alignDeviceOffset; TsFileGeneratorUtils.alignDeviceOffset = 0; @@ -566,7 +568,8 @@ public class MultiTsFileDeviceIteratorTest extends AbstractCompactionTest { IOException, WriteProcessException, StorageEngineException, - InterruptedException { + InterruptedException, + DiskSpaceInsufficientException { TSFileDescriptor.getInstance().getConfig().setMaxDegreeOfIndexNode(3); int oldAlignedDeviceOffset = TsFileGeneratorUtils.alignDeviceOffset; TsFileGeneratorUtils.alignDeviceOffset = 0; diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/IoTDBSnapshotTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/IoTDBSnapshotTest.java index 7976c14e87a..f2ec78777cd 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/IoTDBSnapshotTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/snapshot/IoTDBSnapshotTest.java @@ -19,6 +19,8 @@ package org.apache.iotdb.db.storageengine.dataregion.snapshot; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; import org.apache.iotdb.commons.utils.FileUtils; import org.apache.iotdb.db.conf.IoTDBDescriptor; import org.apache.iotdb.db.exception.DataRegionException; @@ -28,9 +30,7 @@ import org.apache.iotdb.db.storageengine.dataregion.DataRegion; import org.apache.iotdb.db.storageengine.dataregion.flush.CompressionRatio; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource; import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; import org.apache.iotdb.db.storageengine.rescon.disk.TierManager; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; import org.apache.iotdb.db.utils.EnvironmentUtils; import org.apache.tsfile.exception.write.WriteProcessException; @@ -40,17 +40,23 @@ import org.apache.tsfile.utils.TsFileGeneratorUtils; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.mockito.Mockito; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; +import java.nio.file.FileStore; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static org.apache.iotdb.consensus.iot.IoTConsensusServerImpl.SNAPSHOT_DIR_NAME; import static org.apache.tsfile.common.constant.TsFileConstant.PATH_SEPARATOR; +import static org.junit.Assert.assertEquals; public class IoTDBSnapshotTest { private String[][] testDataDirs = @@ -69,11 +75,12 @@ public class IoTDBSnapshotTest { FileUtils.recursivelyDeleteFolder("target" + File.separator + "tmp"); } - private List<TsFileResource> writeTsFiles() throws IOException, WriteProcessException { + private List<TsFileResource> writeTsFiles(String[] dataDirs) + throws IOException, WriteProcessException { List<TsFileResource> resources = new ArrayList<>(); for (int i = 0; i < 100; i++) { String filePath = - testDataDirs[0][i % 3] + dataDirs[i % dataDirs.length] + File.separator + "sequence" + File.separator @@ -112,7 +119,7 @@ public class IoTDBSnapshotTest { IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(testDataDirs); TierManager.getInstance().resetFolders(); try { - List<TsFileResource> resources = writeTsFiles(); + List<TsFileResource> resources = writeTsFiles(testDataDirs[0]); DataRegion region = new DataRegion(testSgName, "0"); region.getTsFileManager().addAll(resources, true); File snapshotDir = new File("target" + File.separator + "snapshot"); @@ -121,12 +128,12 @@ public class IoTDBSnapshotTest { new SnapshotTaker(region).takeFullSnapshot(snapshotDir.getAbsolutePath(), true); File[] files = snapshotDir.listFiles((dir, name) -> name.equals(SnapshotLogger.SNAPSHOT_LOG_NAME)); - Assert.assertEquals(1, files.length); + assertEquals(1, files.length); SnapshotLogAnalyzer analyzer = new SnapshotLogAnalyzer(files[0]); Assert.assertTrue(analyzer.isSnapshotComplete()); int cnt = analyzer.getTotalFileCountInSnapshot(); analyzer.close(); - Assert.assertEquals(200, cnt); + assertEquals(200, cnt); for (TsFileResource resource : resources) { Assert.assertTrue(resource.tryWriteLock()); } @@ -146,7 +153,7 @@ public class IoTDBSnapshotTest { IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(testDataDirs); TierManager.getInstance().resetFolders(); try { - List<TsFileResource> resources = writeTsFiles(); + List<TsFileResource> resources = writeTsFiles(testDataDirs[0]); resources.subList(50, 100).forEach(x -> x.setStatusForTest(TsFileResourceStatus.UNCLOSED)); DataRegion region = new DataRegion(testSgName, "0"); region.setAllowCompaction(false); @@ -157,13 +164,13 @@ public class IoTDBSnapshotTest { new SnapshotTaker(region).takeFullSnapshot(snapshotDir.getAbsolutePath(), true); File[] files = snapshotDir.listFiles((dir, name) -> name.equals(SnapshotLogger.SNAPSHOT_LOG_NAME)); - Assert.assertEquals(1, files.length); + assertEquals(1, files.length); SnapshotLogAnalyzer analyzer = new SnapshotLogAnalyzer(files[0]); int cnt = 0; Assert.assertTrue(analyzer.isSnapshotComplete()); cnt = analyzer.getTotalFileCountInSnapshot(); analyzer.close(); - Assert.assertEquals(100, cnt); + assertEquals(100, cnt); for (TsFileResource resource : resources) { Assert.assertTrue(resource.tryWriteLock()); } @@ -183,7 +190,7 @@ public class IoTDBSnapshotTest { IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(testDataDirs); TierManager.getInstance().resetFolders(); try { - List<TsFileResource> resources = writeTsFiles(); + List<TsFileResource> resources = writeTsFiles(testDataDirs[0]); DataRegion region = new DataRegion(testSgName, "0"); CompressionRatio.getInstance().updateRatio(100, 100, "0"); region.getTsFileManager().addAll(resources, true); @@ -199,8 +206,8 @@ public class IoTDBSnapshotTest { .loadSnapshotForStateMachine(); Assert.assertNotNull(dataRegion); List<TsFileResource> resource = dataRegion.getTsFileManager().getTsFileList(true); - Assert.assertEquals(100, resource.size()); - Assert.assertEquals( + assertEquals(100, resource.size()); + assertEquals( new Pair<>(100L, 100L), CompressionRatio.getInstance().getDataRegionRatioMap().get("0")); } finally { @@ -212,6 +219,86 @@ public class IoTDBSnapshotTest { } } + @Ignore("Need manual execution to specify different disks") + @Test + public void testLoadSnapshotNoHardLink() + throws IOException, WriteProcessException, DirectoryNotLegalException { + IoTDBDescriptor.getInstance().getConfig().setKeepSameDiskWhenLoadingSnapshot(true); + // initialize dirs + String[][] dataDirsForDB = new String[][] {{"C://snapshot_test", "D://snapshot_test"}}; + File snapshotDir = new File("D://snapshot_store//"); + if (snapshotDir.exists()) { + FileUtils.recursivelyDeleteFolder(snapshotDir.getAbsolutePath()); + } + for (String[] dirs : dataDirsForDB) { + for (String dir : dirs) { + if (new File(dir).exists()) { + FileUtils.recursivelyDeleteFolder(dir); + } + } + } + IoTDBDescriptor.getInstance().getConfig().setTierDataDirs(dataDirsForDB); + TierManager.getInstance().resetFolders(); + + // prepare files, files should be written into two folders + List<TsFileResource> resources = writeTsFiles(dataDirsForDB[0]); + DataRegion region = new DataRegion(testSgName, "0"); + region.getTsFileManager().addAll(resources, true); + + // take a snapshot into one disk + Assert.assertTrue(snapshotDir.exists() || snapshotDir.mkdirs()); + try { + Assert.assertTrue( + new SnapshotTaker(region).takeFullSnapshot(snapshotDir.getAbsolutePath(), true)); + File[] files = + snapshotDir.listFiles((dir, name) -> name.equals(SnapshotLogger.SNAPSHOT_LOG_NAME)); + // use loadWithoutLog + if (files != null && files.length > 0) { + files[0].delete(); + } + // move files to snapshot store (simulate snapshot transfer) + for (String dir : dataDirsForDB[0]) { + File internalSnapshotDir = new File(dir, SNAPSHOT_DIR_NAME); + if (internalSnapshotDir.exists()) { + for (File file : FileUtils.listFilesRecursively(internalSnapshotDir, f -> true)) { + if (file.isFile()) { + String absolutePath = file.getAbsolutePath(); + int snapshotIdIndex = absolutePath.indexOf("snapshot_store"); + int suffixIndex = snapshotIdIndex + "snapshot_store".length(); + String suffix = absolutePath.substring(suffixIndex); + File snapshotFile = new File(snapshotDir, suffix); + FileUtils.copyFile(file, snapshotFile); + } + } + } + } + + // load the snapshot + DataRegion dataRegion = + new SnapshotLoader(snapshotDir.getAbsolutePath(), testSgName, "0") + .loadSnapshotForStateMachine(); + Assert.assertNotNull(dataRegion); + resources = dataRegion.getTsFileManager().getTsFileList(true); + assertEquals(100, resources.size()); + + // files should not be moved to another disk + Path snapshotDirPath = snapshotDir.toPath(); + FileStore snapshotFileStore = Files.getFileStore(snapshotDirPath); + for (TsFileResource tsFileResource : resources) { + Path tsfilePath = tsFileResource.getTsFile().toPath(); + FileStore tsFileFileStore = Files.getFileStore(tsfilePath); + assertEquals(snapshotFileStore, tsFileFileStore); + } + } finally { + FileUtils.recursivelyDeleteFolder(snapshotDir.getAbsolutePath()); + for (String[] dirs : dataDirsForDB) { + for (String dir : dirs) { + FileUtils.recursivelyDeleteFolder(dir); + } + } + } + } + @Test public void testGetSnapshotFile() throws IOException { File tsFile = @@ -232,7 +319,7 @@ public class IoTDBSnapshotTest { Mockito.when(region.getDataRegionIdString()).thenReturn("0"); File snapshotFile = new SnapshotTaker(region).getSnapshotFilePathForTsFile(tsFile, "test-snapshotId"); - Assert.assertEquals( + assertEquals( new File( IoTDBDescriptor.getInstance().getConfig().getLocalDataDirs()[0] + File.separator diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManagerTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManagerTest.java index c8ad437a8c3..52f13c16e64 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManagerTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManagerTest.java @@ -19,8 +19,9 @@ package org.apache.iotdb.db.storageengine.rescon.disk; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.tsfile.fileSystem.FSFactoryProducer; import org.apache.tsfile.fileSystem.fsFactory.FSFactory; diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index 4d7b5bcea87..531cbac91a8 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -1699,6 +1699,12 @@ data_region_iot_max_memory_ratio_for_queue = 0.6 # Datatype: long region_migration_speed_limit_bytes_per_second = 50331648 +# When loading snapshot, try keeping TsFiles in the same disk as the snapshot dir. +# This may reduce file copies but may also result in a worse disk load-balance +# effectiveMode: hot_reload +# Datatype: boolean +keep_same_disk_when_loading_snapshot=false + #################### ### Blob Allocator Configuration #################### diff --git a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java index 080d30f0948..39f4a6ce931 100644 --- a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java +++ b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java @@ -107,6 +107,18 @@ public final class UtilMessages { public static final String UNEXPECTED_ERROR_CHECKING_DISK_SPACE = "Unexpected error checking disk space for {}"; + // ======================== FolderManager ======================== + + public static final String ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY = + "All folders are full, change system mode to read-only."; + public static final String FAILED_TO_PROCESS_FOLDER = "Failed to process folder {}"; + public static final String FAILED_TO_READ_FILE_STORE_PATH = + "Failed to read file store path '{}'"; + public static final String DISK_SPACE_INSUFFICIENT_READ_ONLY = + "Disk space is insufficient, change system mode to read-only."; + public static final String CANNOT_CALCULATE_OCCUPIED_SPACE = + "Cannot calculate occupied space of folder {}"; + // ======================== NodeUrlUtils ======================== public static final String BAD_CONFIG_NODE_URL = "Bad ConfigNode url: {}"; diff --git a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java index fab9dafe6d2..8fcc938dbfc 100644 --- a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java +++ b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java @@ -105,6 +105,18 @@ public final class UtilMessages { public static final String UNEXPECTED_ERROR_CHECKING_DISK_SPACE = "检查 {} 的磁盘空间时发生意外错误"; + // ======================== FolderManager ======================== + + public static final String ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY = + "所有文件夹空间均已耗尽,系统切换为只读模式。"; + public static final String FAILED_TO_PROCESS_FOLDER = "处理文件夹 {} 失败"; + public static final String FAILED_TO_READ_FILE_STORE_PATH = + "读取文件存储路径 '{}' 失败"; + public static final String DISK_SPACE_INSUFFICIENT_READ_ONLY = + "磁盘空间不足,系统切换为只读模式。"; + public static final String CANNOT_CALCULATE_OCCUPIED_SPACE = + "无法计算文件夹 {} 的已占用空间"; + // ======================== NodeUrlUtils ======================== public static final String BAD_CONFIG_NODE_URL = "ConfigNode URL 格式错误:{}"; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManager.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/FolderManager.java similarity index 72% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManager.java rename to iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/FolderManager.java index 77a332152ab..731dc66fa4a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/FolderManager.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/FolderManager.java @@ -17,22 +17,28 @@ * under the License. */ -package org.apache.iotdb.db.storageengine.rescon.disk; +package org.apache.iotdb.commons.disk; import org.apache.iotdb.commons.cluster.NodeStatus; import org.apache.iotdb.commons.conf.CommonDescriptor; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; -import org.apache.iotdb.db.i18n.StorageEngineMessages; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.DirectoryStrategyType; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.MaxDiskUsableSpaceFirstStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.MinFolderOccupiedSpaceFirstStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.RandomOnDiskUsableSpaceStrategy; -import org.apache.iotdb.db.storageengine.rescon.disk.strategy.SequenceStrategy; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategy; +import org.apache.iotdb.commons.disk.strategy.DirectoryStrategyType; +import org.apache.iotdb.commons.disk.strategy.MaxDiskUsableSpaceFirstStrategy; +import org.apache.iotdb.commons.disk.strategy.MinFolderOccupiedSpaceFirstStrategy; +import org.apache.iotdb.commons.disk.strategy.RandomOnDiskUsableSpaceStrategy; +import org.apache.iotdb.commons.disk.strategy.SequenceStrategy; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.commons.i18n.UtilMessages; +import org.apache.iotdb.commons.utils.JVMCommonUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.nio.file.FileStore; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -82,7 +88,7 @@ public class FolderManager { this.selectStrategy.setFolders(folders); this.selectStrategy.setFoldersStates(foldersStates); } catch (DiskSpaceInsufficientException e) { - logger.error(StorageEngineMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e); + logger.error(UtilMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e); CommonDescriptor.getInstance().getConfig().setNodeStatus(NodeStatus.ReadOnly); CommonDescriptor.getInstance().getConfig().setStatusReason(NodeStatus.DISK_FULL); throw e; @@ -98,7 +104,7 @@ public class FolderManager { try { return folders.get(selectStrategy.nextFolderIndex()); } catch (DiskSpaceInsufficientException e) { - logger.error(StorageEngineMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e); + logger.error(UtilMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e); CommonDescriptor.getInstance().getConfig().setNodeStatus(NodeStatus.ReadOnly); CommonDescriptor.getInstance().getConfig().setStatusReason(NodeStatus.DISK_FULL); throw e; @@ -129,7 +135,7 @@ public class FolderManager { try { folder = folders.get(selectStrategy.nextFolderIndex()); } catch (DiskSpaceInsufficientException e) { - logger.error(StorageEngineMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e); + logger.error(UtilMessages.ALL_FOLDERS_FULL_CHANGE_TO_READ_ONLY, e); CommonDescriptor.getInstance().getConfig().setNodeStatus(NodeStatus.ReadOnly); CommonDescriptor.getInstance().getConfig().setStatusReason(NodeStatus.DISK_FULL); throw e; @@ -138,7 +144,7 @@ public class FolderManager { return folderConsumer.apply(folder); } catch (Exception e) { updateFolderState(folder, FolderState.ABNORMAL); - logger.warn(StorageEngineMessages.FAILED_TO_PROCESS_FOLDER + folder); + logger.warn(UtilMessages.FAILED_TO_PROCESS_FOLDER, folder); } } throw new DiskSpaceInsufficientException(folders); @@ -147,4 +153,25 @@ public class FolderManager { public List<String> getFolders() { return folders; } + + public String getFirstFolderOfSameDisk(String pathStr) { + Path path = Paths.get(pathStr); + try { + FileStore fileStore = Files.getFileStore(path); + for (String folder : folders) { + if (foldersStates.getOrDefault(folder, FolderState.ABNORMAL) != FolderState.HEALTHY + || !JVMCommonUtils.hasSpace(folder)) { + continue; + } + Path folderPath = Paths.get(folder); + FileStore folderFileStore = Files.getFileStore(folderPath); + if (folderFileStore.equals(fileStore)) { + return folder; + } + } + } catch (IOException e) { + logger.warn(UtilMessages.FAILED_TO_READ_FILE_STORE_PATH, pathStr, e); + } + return null; + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategy.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategy.java similarity index 88% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategy.java rename to iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategy.java index 0408cf924a4..e8f53ffe4c2 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategy.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategy.java @@ -16,14 +16,14 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.db.storageengine.rescon.disk.strategy; +package org.apache.iotdb.commons.disk.strategy; import org.apache.iotdb.commons.cluster.NodeStatus; import org.apache.iotdb.commons.conf.CommonDescriptor; +import org.apache.iotdb.commons.disk.FolderManager; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.commons.i18n.UtilMessages; import org.apache.iotdb.commons.utils.JVMCommonUtils; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; -import org.apache.iotdb.db.i18n.StorageEngineMessages; -import org.apache.iotdb.db.storageengine.rescon.disk.FolderManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +33,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import static org.apache.iotdb.db.storageengine.rescon.disk.FolderManager.FolderState.HEALTHY; +import static org.apache.iotdb.commons.disk.FolderManager.FolderState.HEALTHY; /** * The basic class of all the strategies of multiple directories. If a user wants to define his own @@ -61,7 +61,7 @@ public abstract class DirectoryStrategy { } } if (!hasSpace) { - LOGGER.error(StorageEngineMessages.DISK_SPACE_INSUFFICIENT_READ_ONLY); + LOGGER.error(UtilMessages.DISK_SPACE_INSUFFICIENT_READ_ONLY); CommonDescriptor.getInstance().getConfig().setNodeStatus(NodeStatus.ReadOnly); throw new DiskSpaceInsufficientException(folders); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategyType.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategyType.java similarity index 93% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategyType.java rename to iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategyType.java index 195ad9c8e72..2d081dd87f5 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/DirectoryStrategyType.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/DirectoryStrategyType.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.db.storageengine.rescon.disk.strategy; +package org.apache.iotdb.commons.disk.strategy; public enum DirectoryStrategyType { SEQUENCE_STRATEGY, diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java similarity index 92% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java rename to iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java index dccedaad207..9158027b8a6 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MaxDiskUsableSpaceFirstStrategy.java @@ -16,10 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.db.storageengine.rescon.disk.strategy; +package org.apache.iotdb.commons.disk.strategy; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.utils.JVMCommonUtils; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; public class MaxDiskUsableSpaceFirstStrategy extends DirectoryStrategy { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java similarity index 87% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java rename to iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java index ea2d1909940..d7345eb505c 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/MinFolderOccupiedSpaceFirstStrategy.java @@ -16,11 +16,11 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.db.storageengine.rescon.disk.strategy; +package org.apache.iotdb.commons.disk.strategy; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.commons.i18n.UtilMessages; import org.apache.iotdb.commons.utils.JVMCommonUtils; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; -import org.apache.iotdb.db.i18n.StorageEngineMessages; import java.io.IOException; @@ -48,7 +48,7 @@ public class MinFolderOccupiedSpaceFirstStrategy extends DirectoryStrategy { try { space = JVMCommonUtils.getOccupiedSpace(folder); } catch (IOException e) { - LOGGER.error(StorageEngineMessages.CANNOT_CALC_OCCUPIED_SPACE, folder, e); + LOGGER.error(UtilMessages.CANNOT_CALCULATE_OCCUPIED_SPACE, folder, e); continue; } if (space < minSpace) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/RandomOnDiskUsableSpaceStrategy.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/RandomOnDiskUsableSpaceStrategy.java similarity index 94% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/RandomOnDiskUsableSpaceStrategy.java rename to iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/RandomOnDiskUsableSpaceStrategy.java index 30c5000396a..28264f142a1 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/RandomOnDiskUsableSpaceStrategy.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/RandomOnDiskUsableSpaceStrategy.java @@ -16,10 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.db.storageengine.rescon.disk.strategy; +package org.apache.iotdb.commons.disk.strategy; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.utils.JVMCommonUtils; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import java.security.SecureRandom; import java.util.ArrayList; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/SequenceStrategy.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/SequenceStrategy.java similarity index 95% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/SequenceStrategy.java rename to iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/SequenceStrategy.java index 881623a1882..6b0394e0768 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/rescon/disk/strategy/SequenceStrategy.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/disk/strategy/SequenceStrategy.java @@ -16,10 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.db.storageengine.rescon.disk.strategy; +package org.apache.iotdb.commons.disk.strategy; +import org.apache.iotdb.commons.exception.DiskSpaceInsufficientException; import org.apache.iotdb.commons.utils.JVMCommonUtils; -import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; import org.apache.tsfile.fileSystem.FSFactoryProducer; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/DiskSpaceInsufficientException.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/DiskSpaceInsufficientException.java similarity index 91% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/DiskSpaceInsufficientException.java rename to iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/DiskSpaceInsufficientException.java index f0b5d587559..20286caea06 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/DiskSpaceInsufficientException.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/exception/DiskSpaceInsufficientException.java @@ -16,13 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.iotdb.db.exception; +package org.apache.iotdb.commons.exception; import org.apache.iotdb.rpc.TSStatusCode; import java.util.List; -public class DiskSpaceInsufficientException extends StorageEngineException { +public class DiskSpaceInsufficientException extends IoTDBException { private static final long serialVersionUID = 9001643829368311032L;
