From 59f66f6a2544ef91c905b43d354a7181fd730174 Mon Sep 17 00:00:00 2001 From: Yi Tao Date: Thu, 26 Sep 2019 12:54:22 +0800 Subject: [PATCH] [IOTDB-188] Delete storage group (#416) * add delete storage group interface in session --- .../UserGuide/7-Session API/1-Session API.md | 154 +++++++----------- .../UserGuide/7-Session API/1-Session API.md | 154 ++++++------------ .../adapter/IoTDBConfigDynamicAdapter.java | 3 - .../apache/iotdb/db/engine/StorageEngine.java | 6 + .../storagegroup/StorageGroupProcessor.java | 18 ++ .../org/apache/iotdb/db/metadata/MGraph.java | 22 ++- .../apache/iotdb/db/metadata/MManager.java | 81 +++++++-- .../org/apache/iotdb/db/metadata/MNode.java | 16 +- .../org/apache/iotdb/db/metadata/MTree.java | 45 +++-- .../db/metadata/MetadataOperationType.java | 3 +- .../apache/iotdb/db/monitor/StatMonitor.java | 9 +- .../apache/iotdb/db/qp/QueryProcessor.java | 1 + .../db/qp/executor/QueryProcessExecutor.java | 9 +- .../apache/iotdb/db/qp/logical/Operator.java | 2 +- .../db/qp/logical/sys/MetadataOperator.java | 9 +- .../db/qp/physical/sys/MetadataPlan.java | 2 + .../iotdb/db/service/TSServiceImpl.java | 18 ++ .../db/sync/receiver/SyncServiceImpl.java | 10 +- .../db/engine/MetadataManagerHelper.java | 9 +- .../iotdb/db/engine/merge/MergeTest.java | 2 +- .../modification/DeletionFileNodeTest.java | 4 +- .../modification/DeletionQueryTest.java | 4 +- .../FileNodeManagerBenchmark.java | 2 +- .../apache/iotdb/db/metadata/MGraphTest.java | 12 +- .../db/metadata/MManagerAdvancedTest.java | 14 +- .../iotdb/db/metadata/MManagerBasicTest.java | 49 +++--- .../db/metadata/MManagerImproveTest.java | 2 +- .../iotdb/db/metadata/MetadataTest.java | 16 +- .../iotdb/db/qp/QueryProcessorTest.java | 4 +- .../iotdb/db/writelog/PerformanceTest.java | 2 +- service-rpc/src/main/thrift/rpc.thrift | 4 +- .../org/apache/iotdb/session/Session.java | 14 ++ .../apache/iotdb/session/IoTDBSessionIT.java | 49 ++++++ 33 files changed, 427 insertions(+), 322 deletions(-) diff --git a/docs/Documentation-CHN/UserGuide/7-Session API/1-Session API.md b/docs/Documentation-CHN/UserGuide/7-Session API/1-Session API.md index dfc1efdd81..b5023f8ad5 100644 --- a/docs/Documentation-CHN/UserGuide/7-Session API/1-Session API.md +++ b/docs/Documentation-CHN/UserGuide/7-Session API/1-Session API.md @@ -7,9 +7,9 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -28,9 +28,14 @@ * JDK >= 1.8 * Maven >= 3.1 +## 仅在client模块中打包 + +在根目录下运行: +> mvn clean package -pl client -am -Dmaven.test.skip=true + ## 安装到本地 maven 库 -In root directory: +在根目录下运行: > mvn clean install -pl session -am -Dmaven.test.skip=true ## 在 maven 中使用 session 接口 @@ -46,99 +51,56 @@ In root directory: ``` ## Session 接口使用示例 +下面将给出Session对应的接口的简要介绍和对应参数: +### 启动Session的相关命令: -```Java -import java.util.ArrayList; -import java.util.List; -import org.apache.iotdb.session.IoTDBSessionException; -import org.apache.iotdb.session.Session; -import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType; -import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; -import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding; -import org.apache.iotdb.tsfile.write.record.RowBatch; -import org.apache.iotdb.tsfile.write.schema.MeasurementSchema; -import org.apache.iotdb.tsfile.write.schema.Schema; - -public class SessionExample { - - private static Session session; - - public static void main(String[] args) throws IoTDBSessionException { - session = new Session("127.0.0.1", 6667, "root", "root"); - session.open(); - - session.setStorageGroup("root.sg1"); - session.createTimeseries("root.sg1.d1.s1", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY); - session.createTimeseries("root.sg1.d1.s2", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY); - session.createTimeseries("root.sg1.d1.s3", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY); - - insert(); - insertRowBatch(); - deleteData(); - deleteTimeseries(); - session.close(); - } - - private static void insert() throws IoTDBSessionException { - String deviceId = "root.sg1.d1"; - List measurements = new ArrayList<>(); - measurements.add("s1"); - measurements.add("s2"); - measurements.add("s3"); - for (long time = 0; time < 100; time++) { - List values = new ArrayList<>(); - values.add("1"); - values.add("2"); - values.add("3"); - session.insert(deviceId, time, measurements, values); - } - } - - private static void insertRowBatch() throws IoTDBSessionException { - Schema schema = new Schema(); - schema.registerMeasurement(new MeasurementSchema("s1", TSDataType.INT64, TSEncoding.RLE)); - schema.registerMeasurement(new MeasurementSchema("s2", TSDataType.INT64, TSEncoding.RLE)); - schema.registerMeasurement(new MeasurementSchema("s3", TSDataType.INT64, TSEncoding.RLE)); - - RowBatch rowBatch = schema.createRowBatch("root.sg1.d1", 100); - - long[] timestamps = rowBatch.timestamps; - Object[] values = rowBatch.values; - - for (long time = 0; time < 100; time++) { - int row = rowBatch.batchSize++; - timestamps[row] = time; - for (int i = 0; i < 3; i++) { - long[] sensor = (long[]) values[i]; - sensor[row] = i; - } - if (rowBatch.batchSize == rowBatch.getMaxBatchSize()) { - session.insertBatch(rowBatch); - rowBatch.reset(); - } - } - - if (rowBatch.batchSize != 0) { - session.insertBatch(rowBatch); - rowBatch.reset(); - } - } - - private static void deleteData() throws IoTDBSessionException { - String path = "root.sg1.d1.s1"; - long deleteTime = 99; - session.deleteData(path, deleteTime); - } - - private static void deleteTimeseries() throws IoTDBSessionException { - List paths = new ArrayList<>(); - paths.add("root.sg1.d1.s1"); - paths.add("root.sg1.d1.s2"); - paths.add("root.sg1.d1.s3"); - session.deleteTimeseries(paths); - } -} -``` +* 初始化Session + ​ Session(String host, int port) + Session(String host, String port, String username, String password) + Session(String host, int port, String username, String password) + +* 开启Session + ​ Session.open() + +* 关闭Session + ​ Session.close() + +### Session的相关数据操作命令 + +* 设置存储组 + + ​ TSStatus setStorageGroup(String storageGroupId) + +* 删除单个或多个存储组 + + ​ TSStatus deleteStorageGroup(String storageGroup) + TSStatus deleteStorageGroups(List storageGroups) + +* 创建单个时间序列 + + ​ TSStatus createTimeseries(String path, TSDataType dataType, TSEncoding encoding, CompressionType compressor) + +* 删除一个或多个时间序列 + + ​ TSStatus deleteTimeseries(String path) + TSStatus deleteTimeseries(List paths) + +* 删除某一特定时间前的时间序列 + + ​ TSStatus deleteData(String path, long time) + TSStatus deleteData(List paths, long time) + +* 插入时序数据 + + ​ TSStatus insert(String deviceId, long time, List measurements, List values) + +* 批量插入时序数据 + + ​ TSExecuteBatchStatementResp insertBatch(RowBatch rowBatch) + +### 示例代码 + + 浏览上述接口的详细信息,请参阅代码session/src/main/java/org/apache/iotdb/session/Session.java -> The code is in example/session/src/main/java/org/apache/iotdb/session/SessionExample.java \ No newline at end of file + 使用上述接口的示例代码在example/session/src/main/java/org/apache/iotdb/SessionExample.java,在此文件中包含了开启session和执行批量插入等操作 \ No newline at end of file diff --git a/docs/Documentation/UserGuide/7-Session API/1-Session API.md b/docs/Documentation/UserGuide/7-Session API/1-Session API.md index 0bf86ba8a0..c8fef86517 100644 --- a/docs/Documentation/UserGuide/7-Session API/1-Session API.md +++ b/docs/Documentation/UserGuide/7-Session API/1-Session API.md @@ -7,9 +7,9 @@ to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @@ -51,103 +51,55 @@ In root directory: ``` -## Examples with Session - -This chapter provides an example of how to open an IoTDB session, execute a batch insertion. - -Requires that you include the packages containing the Client classes needed for database programming. - -```Java -import java.util.ArrayList; -import java.util.List; -import org.apache.iotdb.session.IoTDBSessionException; -import org.apache.iotdb.session.Session; -import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType; -import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; -import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding; -import org.apache.iotdb.tsfile.write.record.RowBatch; -import org.apache.iotdb.tsfile.write.schema.MeasurementSchema; -import org.apache.iotdb.tsfile.write.schema.Schema; - -public class SessionExample { - - private static Session session; - - public static void main(String[] args) throws IoTDBSessionException { - session = new Session("127.0.0.1", 6667, "root", "root"); - session.open(); - - session.setStorageGroup("root.sg1"); - session.createTimeseries("root.sg1.d1.s1", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY); - session.createTimeseries("root.sg1.d1.s2", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY); - session.createTimeseries("root.sg1.d1.s3", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY); - - insert(); - insertRowBatch(); - deleteData(); - deleteTimeseries(); - session.close(); - } - - private static void insert() throws IoTDBSessionException { - String deviceId = "root.sg1.d1"; - List measurements = new ArrayList<>(); - measurements.add("s1"); - measurements.add("s2"); - measurements.add("s3"); - for (long time = 0; time < 100; time++) { - List values = new ArrayList<>(); - values.add("1"); - values.add("2"); - values.add("3"); - session.insert(deviceId, time, measurements, values); - } - } - - private static void insertRowBatch() throws IoTDBSessionException { - Schema schema = new Schema(); - schema.registerMeasurement(new MeasurementSchema("s1", TSDataType.INT64, TSEncoding.RLE)); - schema.registerMeasurement(new MeasurementSchema("s2", TSDataType.INT64, TSEncoding.RLE)); - schema.registerMeasurement(new MeasurementSchema("s3", TSDataType.INT64, TSEncoding.RLE)); - - RowBatch rowBatch = schema.createRowBatch("root.sg1.d1", 100); - - long[] timestamps = rowBatch.timestamps; - Object[] values = rowBatch.values; - - for (long time = 0; time < 100; time++) { - int row = rowBatch.batchSize++; - timestamps[row] = time; - for (int i = 0; i < 3; i++) { - long[] sensor = (long[]) values[i]; - sensor[row] = i; - } - if (rowBatch.batchSize == rowBatch.getMaxBatchSize()) { - session.insertBatch(rowBatch); - rowBatch.reset(); - } - } - - if (rowBatch.batchSize != 0) { - session.insertBatch(rowBatch); - rowBatch.reset(); - } - } - - private static void deleteData() throws IoTDBSessionException { - String path = "root.sg1.d1.s1"; - long deleteTime = 99; - session.deleteData(path, deleteTime); - } - - private static void deleteTimeseries() throws IoTDBSessionException { - List paths = new ArrayList<>(); - paths.add("root.sg1.d1.s1"); - paths.add("root.sg1.d1.s2"); - paths.add("root.sg1.d1.s3"); - session.deleteTimeseries(paths); - } -} -``` +## Examples with Session interfaces + +Here we show the commonly used interfaces and their parameters in the Session: + +### Run the Session + +* Initialize Session + Session(String host, int port) + Session(String host, String port, String username, String password) + Session(String host, int port, String username, String password) + +* Open Session + ​ Session.open() + +* Close Session + ​ Session.close() + +### Operate the Session + +* Set a storage group + + ​ TSStatus setStorageGroup(String storageGroupId) + +* Delete one or several storage groups + + ​ TSStatus deleteStorageGroup(String storageGroup) + TSStatus deleteStorageGroups(List storageGroups) + +* Create a timeseries under a existing storage group + ​ TSStatus createTimeseries(String path, TSDataType dataType, TSEncoding encoding, CompressionType compressor) + +* Delete one or several timeseries + ​ TSStatus deleteTimeseries(String path) + TSStatus deleteTimeseries(List paths) + +* Delete one or several timeseries before a certain timestamp + ​ TSStatus deleteData(String path, long time) + TSStatus deleteData(List paths, long time) + +* Insert data in existing timeseries + + ​ TSStatus insert(String deviceId, long time, List measurements, List values) + +* Batch insertion of timeseries + + ​ TSExecuteBatchStatementResp insertBatch(RowBatch rowBatch) + +### Sample code + +To get more information of the following interfaces, please view session/src/main/java/org/apache/iotdb/session/Session.java -> The code is in example/session/src/main/java/org/apache/iotdb/session/SessionExample.java \ No newline at end of file +The sample code of using these interfaces is in example/session/src/main/java/org/apache/iotdb/SessionExample.java,which provides an example of how to open an IoTDB session, execute a batch insertion. \ No newline at end of file diff --git a/server/src/main/java/org/apache/iotdb/db/conf/adapter/IoTDBConfigDynamicAdapter.java b/server/src/main/java/org/apache/iotdb/db/conf/adapter/IoTDBConfigDynamicAdapter.java index cb4bae1c58..41dd543019 100644 --- a/server/src/main/java/org/apache/iotdb/db/conf/adapter/IoTDBConfigDynamicAdapter.java +++ b/server/src/main/java/org/apache/iotdb/db/conf/adapter/IoTDBConfigDynamicAdapter.java @@ -208,9 +208,6 @@ public class IoTDBConfigDynamicAdapter implements IDynamicAdapter { * PrimitiveArrayPool.ARRAY_SIZE * Long.BYTES * 2; } - /** - * TODO: Currently IoTDB only supports to add a storage group. - */ @Override public void addOrDeleteStorageGroup(int diff) throws ConfigAdjusterException { totalStorageGroup += diff; diff --git a/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java b/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java index fed82c0783..d0f8fa77ca 100644 --- a/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java +++ b/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java @@ -346,4 +346,10 @@ public class StorageEngine implements IService { return true; } + public void deleteStorageGroup(String storageGroupName) { + deleteAllDataFilesInOneStorageGroup(storageGroupName); + StorageGroupProcessor processor = processorMap.remove(storageGroupName); + processor.deleteFolder(systemDir); + } + } diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java index 5377adf886..70ac9c7c10 100755 --- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java +++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java @@ -527,6 +527,24 @@ public class StorageGroupProcessor { } } + /** + * delete the storageGroup's own folder in folder data/system/storage_groups + */ + public void deleteFolder(String systemDir) { + waitForAllCurrentTsFileProcessorsClosed(); + writeLock(); + try { + File storageGroupFolder = SystemFileFactory.INSTANCE.getFile(systemDir, storageGroupName); + if (storageGroupFolder.exists()) { + FileUtils.deleteDirectory(storageGroupFolder); + } + } catch (IOException e) { + logger.error("Cannot delete the folder in storage group {}, because", storageGroupName, e); + } finally { + writeUnlock(); + } + } + public void syncDeleteDataFiles() { waitForAllCurrentTsFileProcessorsClosed(); writeLock(); diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MGraph.java b/server/src/main/java/org/apache/iotdb/db/metadata/MGraph.java index 1dedc80632..9a7a5cc830 100644 --- a/server/src/main/java/org/apache/iotdb/db/metadata/MGraph.java +++ b/server/src/main/java/org/apache/iotdb/db/metadata/MGraph.java @@ -152,21 +152,29 @@ public class MGraph implements Serializable { } /** - * Set storage level for current Metadata Tree. + * Set storage group for current Metadata Tree. * * @param path Format: root.node.(node)* */ - void setStorageLevel(String path) throws PathErrorException { + void setStorageGroup(String path) throws PathErrorException { mtree.setStorageGroup(path); } /** - * Check whether the input path is storage level for current Metadata Tree or not. + * Delete storage group from current Metadata Tree. + * + * @param path Format: root.node + */ + void deleteStorageGroup(String path) throws PathErrorException { + mtree.deleteStorageGroup(path); + } + /** + * Check whether the input path is storage group for current Metadata Tree or not. * * @param path Format: root.node.(node)* * @apiNote :for cluster */ - boolean checkStorageLevel(String path) { + boolean checkStorageGroup(String path) { return mtree.checkStorageGroup(path); } @@ -289,9 +297,9 @@ public class MGraph implements Serializable { } /** - * Calculate the count of storage-level nodes included in given seriesPath. + * Calculate the count of storage-group nodes included in given seriesPath. * - * @return The total count of storage-level nodes. + * @return The total count of storage-group nodes. */ int getFileCountForOneType(String path) throws PathErrorException { return mtree.getFileCountForOneType(path); @@ -299,7 +307,7 @@ public class MGraph implements Serializable { /** * Get the file name for given seriesPath Notice: This method could be called if and only if the - * seriesPath includes one node whose {@code isStorageLevel} is true. + * seriesPath includes one node whose {@code isStorageGroup} is true. */ String getStorageGroupNameByPath(String path) throws PathErrorException { return mtree.getStorageGroupNameByPath(path); diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java index 05c9331c42..c8c6bfa3ca 100644 --- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java +++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java @@ -30,7 +30,6 @@ import org.apache.iotdb.db.exception.MetadataErrorException; import org.apache.iotdb.db.exception.PathErrorException; import org.apache.iotdb.db.monitor.MonitorConstants; import org.apache.iotdb.db.utils.RandomDeleteCache; -import org.apache.iotdb.tsfile.common.conf.TSFileConfig; import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor; import org.apache.iotdb.tsfile.exception.cache.CacheException; import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType; @@ -209,8 +208,15 @@ public class MManager { case MetadataOperationType.DELETE_PATH_FROM_MTREE: deletePaths(Collections.singletonList(new Path(args[1]))); break; - case MetadataOperationType.SET_STORAGE_LEVEL_TO_MTREE: - setStorageLevelToMTree(args[1]); + case MetadataOperationType.SET_STORAGE_GROUP_TO_MTREE: + setStorageGroupToMTree(args[1]); + break; + case MetadataOperationType.DELETE_STORAGE_GROUP_FROM_MTREE: + List storageGroups = new ArrayList<>(); + for (int l = 1; l < args.length; l++){ + storageGroups.add(new Path(args[l])); + } + deleteStorageGroupsFromMTree(storageGroups); break; case MetadataOperationType.ADD_A_PTREE: addAPTree(args[1]); @@ -519,19 +525,19 @@ public class MManager { } /** - * function for setting storage level of the given path to mTree. + * function for setting storage group of the given path to mTree. */ - public void setStorageLevelToMTree(String path) throws MetadataErrorException { + public void setStorageGroupToMTree(String path) throws MetadataErrorException { lock.writeLock().lock(); try { checkAndGetDataTypeCache.clear(); mNodeCache.clear(); IoTDBConfigDynamicAdapter.getInstance().addOrDeleteStorageGroup(1); - mgraph.setStorageLevel(path); + mgraph.setStorageGroup(path); seriesNumberInStorageGroups.put(path, 0); if (writeToLog) { BufferedWriter writer = getLogWriter(); - writer.write(MetadataOperationType.SET_STORAGE_LEVEL_TO_MTREE + "," + path); + writer.write(MetadataOperationType.SET_STORAGE_GROUP_TO_MTREE + "," + path); writer.newLine(); writer.flush(); } @@ -550,14 +556,57 @@ public class MManager { } /** - * function for checking if the given path is storage level of mTree or not. + * function for deleting storage groups of the given path from mTree. + * the log format is like "delete_storage_group,sg1,sg2,sg3" + */ + public boolean deleteStorageGroupsFromMTree(List deletePathList) throws MetadataErrorException { + List pathList = new ArrayList<>(); + String jointPath = ""; + for (Path storagePath : deletePathList) { + pathList.add(storagePath.getFullPath()); + jointPath = jointPath + "," + storagePath.getFullPath(); + } + lock.writeLock().lock(); + try { + if (writeToLog) { + BufferedWriter writer = getLogWriter(); + writer.write(MetadataOperationType.DELETE_STORAGE_GROUP_FROM_MTREE + jointPath); + writer.newLine(); + writer.flush(); + } + for (String delStorageGroup : pathList) { + try { + checkAndGetDataTypeCache.clear(); + mNodeCache.clear(); + IoTDBConfigDynamicAdapter.getInstance().addOrDeleteStorageGroup(-1); + mgraph.deleteStorageGroup(delStorageGroup); + seriesNumberInStorageGroups.remove(delStorageGroup); + } catch (PathErrorException e){ + try { + IoTDBConfigDynamicAdapter.getInstance().addOrDeleteStorageGroup(1); + } catch (ConfigAdjusterException ex){ + throw new MetadataErrorException(ex); + } + throw new MetadataErrorException(e); + } + } + } catch (IOException | ConfigAdjusterException e){ + throw new MetadataErrorException(e); + } finally { + lock.writeLock().unlock(); + } + return true; + } + + /** + * function for checking if the given path is storage group of mTree or not. * * @apiNote :for cluster */ - boolean checkStorageLevelOfMTree(String path) { + boolean checkStorageGroupOfMTree(String path) { lock.readLock().lock(); try { - return mgraph.checkStorageLevel(path); + return mgraph.checkStorageGroup(path); } finally { lock.readLock().unlock(); } @@ -845,9 +894,9 @@ public class MManager { } /** - * Calculate the count of storage-level nodes included in given seriesPath. + * Calculate the count of storage-group nodes included in given seriesPath. * - * @return The total count of storage-level nodes. + * @return The total count of storage-group nodes. */ // future feature @SuppressWarnings("unused") @@ -863,7 +912,7 @@ public class MManager { /** * Get the file name for given seriesPath Notice: This method could be called if and only if the - * seriesPath includes one node whose {@code isStorageLevel} is true. + * seriesPath includes one node whose {@code isStorageGroup} is true. * * @return A String represented the file name */ @@ -1114,7 +1163,7 @@ public class MManager { } /** - * Check whether given seriesPath contains a MNode whose {@code MNode.isStorageLevel} is true. + * Check whether given seriesPath contains a MNode whose {@code MNode.isStorageGroup} is true. */ public boolean checkFileLevel(List path) throws PathErrorException { @@ -1186,11 +1235,11 @@ public class MManager { /** * Check whether {@code seriesPath} exists and whether {@code seriesPath} has been set storage - * level. + * group. * * @return {@link PathCheckRet} */ - PathCheckRet checkPathStorageLevelAndGetDataType(String path) throws PathErrorException { + PathCheckRet checkPathStorageGroupAndGetDataType(String path) throws PathErrorException { try { return checkAndGetDataTypeCache.get(path); } catch (CacheException e) { diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/MNode.java index 433b7d53be..4d92cdbbad 100644 --- a/server/src/main/java/org/apache/iotdb/db/metadata/MNode.java +++ b/server/src/main/java/org/apache/iotdb/db/metadata/MNode.java @@ -39,8 +39,8 @@ public class MNode implements Serializable { private String name; // Whether current node is a leaf in the Metadata Tree private boolean isLeaf; - // Whether current node is Storage Level in the Metadata Tree - private boolean isStorageLevel; + // Whether current node is Storage group in the Metadata Tree + private boolean isStorageGroup; // Map for the schema in this storage group private Map schemaMap; private Map numSchemaMap; @@ -59,7 +59,7 @@ public class MNode implements Serializable { this.setName(name); this.parent = parent; this.isLeaf = isLeaf; - this.isStorageLevel = false; + this.isStorageGroup = false; if (!isLeaf) { children = new LinkedHashMap<>(); } @@ -71,15 +71,15 @@ public class MNode implements Serializable { this.schema = new MeasurementSchema(name, dataType, encoding, type); } - public boolean isStorageLevel() { - return isStorageLevel; + public boolean isStorageGroup() { + return isStorageGroup; } /** - * function for setting storage level. + * function for setting storage group. */ - public void setStorageLevel(boolean b) { - this.isStorageLevel = b; + public void setStorageGroup(boolean b) { + this.isStorageGroup = b; if (b) { schemaMap = new HashMap<>(); numSchemaMap = new HashMap<>(); diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java index e3f6431e7d..77753d4334 100644 --- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java +++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java @@ -101,7 +101,7 @@ public class MTree implements Serializable { int i = 1; while (i < nodeNames.length - 1) { String nodeName = nodeNames[i]; - if (cur.isStorageLevel()) { + if (cur.isStorageGroup()) { levelPath = cur.getDataFileName(); } if (!cur.hasChild(nodeName)) { @@ -197,7 +197,7 @@ public class MTree implements Serializable { if (temp == null) { // add one child node cur.addChild(nodeNames[i], new MNode(nodeNames[i], cur, false)); - } else if (temp.isStorageLevel()) { + } else if (temp.isStorageGroup()) { // before set storage group should check the seriesPath exist or not // throw exception throw new PathErrorException( @@ -215,10 +215,23 @@ public class MTree implements Serializable { path)); } cur = cur.getChild(nodeNames[i]); - cur.setStorageLevel(true); + cur.setStorageGroup(true); setDataFileName(path, cur); } + public void deleteStorageGroup(String path) throws PathErrorException { + MNode cur = getNodeByPath(path); + if (!cur.isStorageGroup()) { + throw new PathErrorException(String.format("The path %s is not a deletable storage group", path)); + } + cur.getParent().deleteChild(cur.getName()); + cur = cur.getParent(); + while (cur != null && !MetadataConstant.ROOT.equals(cur.getName()) && cur.getChildren().size() == 0) { + cur.getParent().deleteChild(cur.getName()); + cur = cur.getParent(); + } + } + /** * Check whether the input path is storage group or not * @param path input path @@ -234,14 +247,14 @@ public class MTree implements Serializable { int i = 1; while (i < nodeNames.length - 1) { MNode temp = cur.getChild(nodeNames[i]); - if (temp == null || temp.isStorageLevel()) { + if (temp == null || temp.isStorageGroup()) { return false; } cur = cur.getChild(nodeNames[i]); i++; } MNode temp = cur.getChild(nodeNames[i]); - return temp != null && temp.isStorageLevel(); + return temp != null && temp.isStorageGroup(); } /** @@ -294,13 +307,13 @@ public class MTree implements Serializable { // if the storage group node is deleted, the dataFileName should be // return String dataFileName = null; - if (cur.isStorageLevel()) { + if (cur.isStorageGroup()) { dataFileName = cur.getDataFileName(); } cur.getParent().deleteChild(cur.getName()); cur = cur.getParent(); while (cur != null && !MetadataConstant.ROOT.equals(cur.getName()) && cur.getChildren().size() == 0) { - if (cur.isStorageLevel()) { + if (cur.isStorageGroup()) { dataFileName = cur.getDataFileName(); return dataFileName; } @@ -461,7 +474,7 @@ public class MTree implements Serializable { String.format(NO_CHILD_ERROR,cur.getName(),nodes[i])); } cur = cur.getChild(nodes[i]); - if (cur.isStorageLevel()) { + if (cur.isStorageGroup()) { fileLevelChecked = true; } } @@ -536,13 +549,13 @@ public class MTree implements Serializable { throw new PathErrorException( String.format(NOT_SERIES_PATH, path)); - } else if (cur.isStorageLevel()) { + } else if (cur.isStorageGroup()) { return cur.getDataFileName(); } else { cur = cur.getChild(nodes[i]); } } - if (cur.isStorageLevel()) { + if (cur.isStorageGroup()) { return cur.getDataFileName(); } throw new PathErrorException( @@ -571,7 +584,7 @@ public class MTree implements Serializable { */ private void findFileName(MNode node, String[] nodes, int idx, String parent, ArrayList paths) { - if (node.isStorageLevel()) { + if (node.isStorageGroup()) { paths.add(node.getDataFileName()); return; } @@ -605,13 +618,13 @@ public class MTree implements Serializable { throw new PathErrorException( String.format(NOT_SERIES_PATH, path)); - } else if (cur.isStorageLevel()) { + } else if (cur.isStorageGroup()) { return cur.getDataFileName(); } else { cur = cur.getChild(nodes[i]); } } - if (cur.isStorageLevel()) { + if (cur.isStorageGroup()) { return cur.getDataFileName(); } throw new PathErrorException( @@ -631,7 +644,7 @@ public class MTree implements Serializable { for (int i = 1; i <= nodes.length; i++) { if (cur == null) { return false; - } else if (cur.isStorageLevel()) { + } else if (cur.isStorageGroup()) { return true; } else { cur = cur.getChild(nodes[i]); @@ -715,7 +728,7 @@ public class MTree implements Serializable { private int getFileCountForOneNode(MNode node) { - if (node.isStorageLevel()) { + if (node.isStorageGroup()) { return 1; } int sum = 0; @@ -755,7 +768,7 @@ public class MTree implements Serializable { } private void findStorageGroup(MNode node, String path, HashSet res) { - if (node.isStorageLevel()) { + if (node.isStorageGroup()) { res.add(path); return; } diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MetadataOperationType.java b/server/src/main/java/org/apache/iotdb/db/metadata/MetadataOperationType.java index 2e52efffec..0ed030414c 100644 --- a/server/src/main/java/org/apache/iotdb/db/metadata/MetadataOperationType.java +++ b/server/src/main/java/org/apache/iotdb/db/metadata/MetadataOperationType.java @@ -26,7 +26,7 @@ public class MetadataOperationType { public static final String ADD_PATH_TO_MTREE = "0"; public static final String DELETE_PATH_FROM_MTREE = "1"; - public static final String SET_STORAGE_LEVEL_TO_MTREE = "2"; + public static final String SET_STORAGE_GROUP_TO_MTREE = "2"; public static final String ADD_A_PTREE = "3"; public static final String ADD_A_PATH_TO_PTREE = "4"; public static final String DELETE_PATH_FROM_PTREE = "5"; @@ -34,4 +34,5 @@ public class MetadataOperationType { public static final String UNLINK_MNODE_FROM_PTREE = "7"; public static final String ADD_INDEX_TO_PATH = "8"; public static final String DELETE_INDEX_FROM_PATH = "9"; + public static final String DELETE_STORAGE_GROUP_FROM_MTREE = "10"; } diff --git a/server/src/main/java/org/apache/iotdb/db/monitor/StatMonitor.java b/server/src/main/java/org/apache/iotdb/db/monitor/StatMonitor.java index 951b655801..130c1be71f 100644 --- a/server/src/main/java/org/apache/iotdb/db/monitor/StatMonitor.java +++ b/server/src/main/java/org/apache/iotdb/db/monitor/StatMonitor.java @@ -41,7 +41,6 @@ import org.apache.iotdb.db.monitor.collector.FileSize; import org.apache.iotdb.db.qp.physical.crud.InsertPlan; import org.apache.iotdb.db.service.IService; import org.apache.iotdb.db.service.ServiceType; -import org.apache.iotdb.tsfile.common.conf.TSFileConfig; import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor; import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; @@ -87,10 +86,10 @@ public class StatMonitor implements IService { try { String prefix = MonitorConstants.STAT_STORAGE_GROUP_PREFIX; if (!mmanager.pathExist(prefix)) { - mmanager.setStorageLevelToMTree(prefix); + mmanager.setStorageGroupToMTree(prefix); } } catch (MetadataErrorException e) { - logger.error("MManager cannot set storage level to MTree.", e); + logger.error("MManager cannot set storage group to MTree.", e); } } } @@ -144,10 +143,10 @@ public class StatMonitor implements IService { String prefix = MonitorConstants.STAT_STORAGE_GROUP_PREFIX; try { if (!mManager.pathExist(prefix)) { - mManager.setStorageLevelToMTree(prefix); + mManager.setStorageGroupToMTree(prefix); } } catch (Exception e) { - logger.error("MManager cannot set storage level to MTree.", e); + logger.error("MManager cannot set storage group to MTree.", e); } } diff --git a/server/src/main/java/org/apache/iotdb/db/qp/QueryProcessor.java b/server/src/main/java/org/apache/iotdb/db/qp/QueryProcessor.java index ebb30c2f39..59525bd785 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/QueryProcessor.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/QueryProcessor.java @@ -131,6 +131,7 @@ public class QueryProcessor { case AUTHOR: case METADATA: case SET_STORAGE_GROUP: + case DELETE_STORAGE_GROUP: case CREATE_TIMESERIES: case DELETE_TIMESERIES: case PROPERTY: diff --git a/server/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java b/server/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java index 1c58ea7000..be3f5a2197 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/QueryProcessExecutor.java @@ -113,6 +113,7 @@ public class QueryProcessExecutor extends AbstractQueryProcessExecutor { case DELETE_TIMESERIES: case CREATE_TIMESERIES: case SET_STORAGE_GROUP: + case DELETE_STORAGE_GROUP: case METADATA: MetadataPlan metadata = (MetadataPlan) plan; return operateMetadata(metadata); @@ -397,7 +398,13 @@ public class QueryProcessExecutor extends AbstractQueryProcessExecutor { } break; case SET_STORAGE_GROUP: - mManager.setStorageLevelToMTree(path.getFullPath()); + mManager.setStorageGroupToMTree(path.getFullPath()); + break; + case DELETE_STORAGE_GROUP: + mManager.deleteStorageGroupsFromMTree(deletePathList); + for (Path storageGroupPath : deletePathList) { + storageEngine.deleteStorageGroup(storageGroupPath.getFullPath()); + } break; default: throw new ProcessorException("unknown namespace type:" + namespaceType); diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java index cab4ed4f3a..28af9580a4 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/Operator.java @@ -73,6 +73,6 @@ public abstract class Operator { GRANT_USER_PRIVILEGE, REVOKE_USER_PRIVILEGE, GRANT_USER_ROLE, REVOKE_USER_ROLE, CREATE_ROLE, DELETE_ROLE, GRANT_ROLE_PRIVILEGE, REVOKE_ROLE_PRIVILEGE, LIST_USER, LIST_ROLE, LIST_USER_PRIVILEGE, LIST_ROLE_PRIVILEGE, LIST_USER_ROLES, LIST_ROLE_USERS, - GRANT_WATERMARK_EMBEDDING, REVOKE_WATERMARK_EMBEDDING + GRANT_WATERMARK_EMBEDDING, REVOKE_WATERMARK_EMBEDDING, DELETE_STORAGE_GROUP, } } diff --git a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/MetadataOperator.java b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/MetadataOperator.java index 2a80f6b387..c0dfeb4955 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/MetadataOperator.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/logical/sys/MetadataOperator.java @@ -46,6 +46,9 @@ public class MetadataOperator extends RootOperator { super(tokenIntType); namespaceType = type; switch (type) { + case DELETE_STORAGE_GROUP: + operatorType = OperatorType.DELETE_STORAGE_GROUP; + break; case SET_STORAGE_GROUP: operatorType = OperatorType.SET_STORAGE_GROUP; break; @@ -113,7 +116,7 @@ public class MetadataOperator extends RootOperator { } public enum NamespaceType { - ADD_PATH, DELETE_PATH, SET_STORAGE_GROUP; + ADD_PATH, DELETE_PATH, SET_STORAGE_GROUP, DELETE_STORAGE_GROUP; /** * deserialize short number. @@ -129,6 +132,8 @@ public class MetadataOperator extends RootOperator { return DELETE_PATH; case 2: return SET_STORAGE_GROUP; + case 3: + return DELETE_STORAGE_GROUP; default: return null; } @@ -147,6 +152,8 @@ public class MetadataOperator extends RootOperator { return 1; case SET_STORAGE_GROUP: return 2; + case DELETE_STORAGE_GROUP: + return 3; default: return -1; } diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/MetadataPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/MetadataPlan.java index 4b3866d7a7..d4c51ec856 100644 --- a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/MetadataPlan.java +++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/MetadataPlan.java @@ -201,6 +201,8 @@ public class MetadataPlan extends PhysicalPlan { case DELETE_PATH: setOperatorType(Operator.OperatorType.DELETE_TIMESERIES); break; + case DELETE_STORAGE_GROUP: + setOperatorType(Operator.OperatorType.DELETE_STORAGE_GROUP); default: break; } diff --git a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java index 41ceed3581..afbf30663c 100644 --- a/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java +++ b/server/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java @@ -1149,6 +1149,24 @@ public class TSServiceImpl implements TSIService.Iface, ServerContext { return new TSStatus(executePlan(plan)); } + @Override + public TSStatus deleteStorageGroups(List storageGroups) { + if (!checkLogin()) { + logger.info(INFO_NOT_LOGIN, IoTDBConstant.GLOBAL_DB_NAME); + return new TSStatus(getStatus(TSStatusCode.NOT_LOGIN_ERROR)); + } + List storageGroupList = new ArrayList<>(); + for (String storageGroup: storageGroups) { + storageGroupList.add(new Path(storageGroup)); + } + MetadataPlan plan = new MetadataPlan(MetadataOperator.NamespaceType.DELETE_STORAGE_GROUP, storageGroupList); + TSStatus status = checkAuthority(plan); + if (status != null) { + return new TSStatus(status); + } + return new TSStatus(executePlan(plan)); + } + @Override public TSStatus createTimeseries(TSCreateTimeseriesReq req) { if (!checkLogin()) { diff --git a/server/src/main/java/org/apache/iotdb/db/sync/receiver/SyncServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/sync/receiver/SyncServiceImpl.java index a2fa8c6bad..53ce023c70 100644 --- a/server/src/main/java/org/apache/iotdb/db/sync/receiver/SyncServiceImpl.java +++ b/server/src/main/java/org/apache/iotdb/db/sync/receiver/SyncServiceImpl.java @@ -287,8 +287,8 @@ public class SyncServiceImpl implements SyncService.Iface { case MetadataOperationType.DELETE_PATH_FROM_MTREE: metadataManger.deletePaths(Collections.singletonList(new Path(args[1]))); break; - case MetadataOperationType.SET_STORAGE_LEVEL_TO_MTREE: - metadataManger.setStorageLevelToMTree(args[1]); + case MetadataOperationType.SET_STORAGE_GROUP_TO_MTREE: + metadataManger.setStorageGroupToMTree(args[1]); break; case MetadataOperationType.ADD_A_PTREE: metadataManger.addAPTree(args[1]); @@ -305,6 +305,12 @@ public class SyncServiceImpl implements SyncService.Iface { case MetadataOperationType.UNLINK_MNODE_FROM_PTREE: metadataManger.unlinkMNodeFromPTree(args[1], args[2]); break; + case MetadataOperationType.DELETE_STORAGE_GROUP_FROM_MTREE: + List storageGroups = new ArrayList<>(); + for (int l = 1; l < args.length; l++){ + storageGroups.add(new Path(args[l])); + } + metadataManger.deleteStorageGroupsFromMTree(storageGroups); default: logger.error("Unrecognizable command {}", cmd); } diff --git a/server/src/test/java/org/apache/iotdb/db/engine/MetadataManagerHelper.java b/server/src/test/java/org/apache/iotdb/db/engine/MetadataManagerHelper.java index 842f44d54e..8da1c4367e 100644 --- a/server/src/test/java/org/apache/iotdb/db/engine/MetadataManagerHelper.java +++ b/server/src/test/java/org/apache/iotdb/db/engine/MetadataManagerHelper.java @@ -20,7 +20,6 @@ package org.apache.iotdb.db.engine; import java.util.Collections; import org.apache.iotdb.db.metadata.MManager; -import org.apache.iotdb.tsfile.common.conf.TSFileConfig; import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor; import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; @@ -36,9 +35,9 @@ public class MetadataManagerHelper { mmanager.init(); mmanager.clear(); try { - mmanager.setStorageLevelToMTree("root.vehicle.d0"); - mmanager.setStorageLevelToMTree("root.vehicle.d1"); - mmanager.setStorageLevelToMTree("root.vehicle.d2"); + mmanager.setStorageGroupToMTree("root.vehicle.d0"); + mmanager.setStorageGroupToMTree("root.vehicle.d1"); + mmanager.setStorageGroupToMTree("root.vehicle.d2"); CompressionType compressionType =CompressionType.valueOf( TSFileDescriptor.getInstance().getConfig().getCompressor()); @@ -98,7 +97,7 @@ public class MetadataManagerHelper { mmanager = MManager.getInstance(); mmanager.clear(); try { - mmanager.setStorageLevelToMTree("root.vehicle"); + mmanager.setStorageGroupToMTree("root.vehicle"); CompressionType compressionType =CompressionType.valueOf(TSFileDescriptor.getInstance().getConfig().getCompressor()); mmanager.addPathToMTree(new Path("root.vehicle.d0.s0"), TSDataType.valueOf("INT32"), TSEncoding.valueOf("RLE"), compressionType, Collections.emptyMap()); diff --git a/server/src/test/java/org/apache/iotdb/db/engine/merge/MergeTest.java b/server/src/test/java/org/apache/iotdb/db/engine/merge/MergeTest.java index 59dad16afe..34bce41863 100644 --- a/server/src/test/java/org/apache/iotdb/db/engine/merge/MergeTest.java +++ b/server/src/test/java/org/apache/iotdb/db/engine/merge/MergeTest.java @@ -102,7 +102,7 @@ abstract class MergeTest { for (int i = 0; i < deviceNum; i++) { deviceIds[i] = MERGE_TEST_SG + PATH_SEPARATOR + "device" + i; } - MManager.getInstance().setStorageLevelToMTree(MERGE_TEST_SG); + MManager.getInstance().setStorageGroupToMTree(MERGE_TEST_SG); for (String device : deviceIds) { for (MeasurementSchema measurementSchema : measurementSchemas) { MManager.getInstance().addPathToMTree( diff --git a/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionFileNodeTest.java b/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionFileNodeTest.java index b759816ec0..66b3db6479 100644 --- a/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionFileNodeTest.java +++ b/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionFileNodeTest.java @@ -43,7 +43,6 @@ import org.apache.iotdb.db.qp.physical.crud.InsertPlan; import org.apache.iotdb.db.query.control.QueryResourceManager; import org.apache.iotdb.db.utils.EnvironmentUtils; import org.apache.iotdb.db.utils.TimeValuePair; -import org.apache.iotdb.tsfile.common.conf.TSFileConfig; import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor; import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; @@ -54,7 +53,6 @@ import org.apache.iotdb.tsfile.write.record.TSRecord; import org.apache.iotdb.tsfile.write.record.datapoint.DoubleDataPoint; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; public class DeletionFileNodeTest { @@ -76,7 +74,7 @@ public class DeletionFileNodeTest { PathErrorException, IOException, StorageEngineException, StartupException { EnvironmentUtils.envSetUp(); - MManager.getInstance().setStorageLevelToMTree(processorName); + MManager.getInstance().setStorageGroupToMTree(processorName); for (int i = 0; i < 10; i++) { MManager.getInstance().addPathToMTree(processorName + "." + measurements[i], dataType, encoding); diff --git a/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionQueryTest.java b/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionQueryTest.java index 6cfeb82e8e..d455cffcd4 100644 --- a/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionQueryTest.java +++ b/server/src/test/java/org/apache/iotdb/db/engine/modification/DeletionQueryTest.java @@ -35,7 +35,6 @@ import org.apache.iotdb.db.metadata.MManager; import org.apache.iotdb.db.qp.physical.crud.InsertPlan; import org.apache.iotdb.db.query.executor.EngineQueryRouter; import org.apache.iotdb.db.utils.EnvironmentUtils; -import org.apache.iotdb.tsfile.common.conf.TSFileConfig; import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor; import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; @@ -48,7 +47,6 @@ import org.apache.iotdb.tsfile.write.record.TSRecord; import org.apache.iotdb.tsfile.write.record.datapoint.DoubleDataPoint; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; public class DeletionQueryTest { @@ -71,7 +69,7 @@ public class DeletionQueryTest { PathErrorException, IOException, StorageEngineException, StartupException { EnvironmentUtils.envSetUp(); - MManager.getInstance().setStorageLevelToMTree(processorName); + MManager.getInstance().setStorageGroupToMTree(processorName); for (int i = 0; i < 10; i++) { MManager.getInstance().addPathToMTree(processorName + "." + measurements[i], dataType, encoding); diff --git a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/FileNodeManagerBenchmark.java b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/FileNodeManagerBenchmark.java index 7d1604229e..9549475c73 100644 --- a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/FileNodeManagerBenchmark.java +++ b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/FileNodeManagerBenchmark.java @@ -64,7 +64,7 @@ public class FileNodeManagerBenchmark { private static void prepare() throws MetadataErrorException, PathErrorException, IOException { MManager manager = MManager.getInstance(); - manager.setStorageLevelToMTree(prefix); + manager.setStorageGroupToMTree(prefix); for (String device : devices) { for (String measurement : measurements) { manager.addPathToMTree(device + "." + measurement, TSDataType.INT64.toString(), diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MGraphTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/MGraphTest.java index 3e1883519a..c5995b50b0 100644 --- a/server/src/test/java/org/apache/iotdb/db/metadata/MGraphTest.java +++ b/server/src/test/java/org/apache/iotdb/db/metadata/MGraphTest.java @@ -45,26 +45,26 @@ public class MGraphTest { MGraph root2 = new MGraph("root"); MGraph root3 = new MGraph("root"); try { - root.setStorageLevel("root.a.d0"); + root.setStorageGroup("root.a.d0"); root.addPathToMTree("root.a.d0.s0", "INT32", "RLE"); root.addPathToMTree("root.a.d0.s1", "INT32", "RLE"); - root.setStorageLevel("root.a.d1"); + root.setStorageGroup("root.a.d1"); root.addPathToMTree("root.a.d1.s0", "INT32", "RLE"); root.addPathToMTree("root.a.d1.s1", "INT32", "RLE"); - root.setStorageLevel("root.a.b.d0"); + root.setStorageGroup("root.a.b.d0"); root.addPathToMTree("root.a.b.d0.s0", "INT32", "RLE"); - root1.setStorageLevel("root.a.d0"); + root1.setStorageGroup("root.a.d0"); root1.addPathToMTree("root.a.d0.s0", "INT32", "RLE"); root1.addPathToMTree("root.a.d0.s1", "INT32", "RLE"); - root2.setStorageLevel("root.a.d1"); + root2.setStorageGroup("root.a.d1"); root2.addPathToMTree("root.a.d1.s0", "INT32", "RLE"); root2.addPathToMTree("root.a.d1.s1", "INT32", "RLE"); - root3.setStorageLevel("root.a.b.d0"); + root3.setStorageGroup("root.a.b.d0"); root3.addPathToMTree("root.a.b.d0.s0", "INT32", "RLE"); String[] metadatas = new String[3]; diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerAdvancedTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerAdvancedTest.java index 94bfd40cbe..29ed209645 100644 --- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerAdvancedTest.java +++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerAdvancedTest.java @@ -44,9 +44,9 @@ public class MManagerAdvancedTest { EnvironmentUtils.envSetUp(); mmanager = MManager.getInstance(); - mmanager.setStorageLevelToMTree("root.vehicle.d0"); - mmanager.setStorageLevelToMTree("root.vehicle.d1"); - mmanager.setStorageLevelToMTree("root.vehicle.d2"); + mmanager.setStorageGroupToMTree("root.vehicle.d0"); + mmanager.setStorageGroupToMTree("root.vehicle.d1"); + mmanager.setStorageGroupToMTree("root.vehicle.d2"); mmanager.addPathToMTree("root.vehicle.d0.s0", "INT32", "RLE"); mmanager.addPathToMTree("root.vehicle.d0.s1", "INT64", "RLE"); @@ -105,14 +105,14 @@ public class MManagerAdvancedTest { mmanager.addPathToMTree("root.vehicle.d2.s3", "TEXT", "PLAIN"); Assert.assertEquals(TSDataType.INT32, - mmanager.checkPathStorageLevelAndGetDataType("root.vehicle.d0.s0").getDataType()); + mmanager.checkPathStorageGroupAndGetDataType("root.vehicle.d0.s0").getDataType()); Assert.assertEquals(TSDataType.INT64, - mmanager.checkPathStorageLevelAndGetDataType("root.vehicle.d0.s1").getDataType()); + mmanager.checkPathStorageGroupAndGetDataType("root.vehicle.d0.s1").getDataType()); Assert.assertEquals(false, - mmanager.checkPathStorageLevelAndGetDataType("root.vehicle.d0.s100").isSuccessfully()); + mmanager.checkPathStorageGroupAndGetDataType("root.vehicle.d0.s100").isSuccessfully()); Assert.assertEquals(null, - mmanager.checkPathStorageLevelAndGetDataType("root.vehicle.d0.s100").getDataType()); + mmanager.checkPathStorageGroupAndGetDataType("root.vehicle.d0.s100").getDataType()); MNode node = mmanager.getNodeByDeviceIdFromCache("root.vehicle.d0"); Assert.assertEquals(TSDataType.INT32, node.getChild("s0").getSchema().getType()); diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java index a01a5a7e95..7c13ae1331 100644 --- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java +++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java @@ -29,7 +29,6 @@ import java.util.List; import org.apache.iotdb.db.exception.MetadataErrorException; import org.apache.iotdb.db.exception.PathErrorException; import org.apache.iotdb.db.utils.EnvironmentUtils; -import org.apache.iotdb.tsfile.common.conf.TSFileConfig; import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor; import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType; import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType; @@ -64,14 +63,14 @@ public class MManagerBasicTest { assertFalse(manager.pathExist("root.laptop")); try { - manager.setStorageLevelToMTree("root.laptop.d1"); + manager.setStorageGroupToMTree("root.laptop.d1"); } catch (MetadataErrorException e) { e.printStackTrace(); fail(e.getMessage()); } try { - manager.setStorageLevelToMTree("root.laptop"); + manager.setStorageGroupToMTree("root.laptop"); } catch (MetadataErrorException e) { Assert.assertEquals( "org.apache.iotdb.db.exception.PathErrorException: The seriesPath of" @@ -152,7 +151,7 @@ public class MManagerBasicTest { } try { - manager.setStorageLevelToMTree("root.laptop.d2"); + manager.setStorageGroupToMTree("root.laptop.d2"); } catch (MetadataErrorException e) { Assert.assertEquals( String.format("The seriesPath of %s already exist, it can't be set to the storage group", @@ -260,25 +259,25 @@ public class MManagerBasicTest { } @Test - public void testSetStorageLevelAndExist() { + public void testSetStorageGroupAndExist() { MManager manager = MManager.getInstance(); try { - assertFalse(manager.checkStorageLevelOfMTree("root")); - assertFalse(manager.checkStorageLevelOfMTree("root1.laptop.d2")); - - manager.setStorageLevelToMTree("root.laptop.d1"); - assertTrue(manager.checkStorageLevelOfMTree("root.laptop.d1")); - assertFalse(manager.checkStorageLevelOfMTree("root.laptop.d2")); - assertFalse(manager.checkStorageLevelOfMTree("root.laptop")); - assertFalse(manager.checkStorageLevelOfMTree("root.laptop.d1.s1")); - - manager.setStorageLevelToMTree("root.laptop.d2"); - assertTrue(manager.checkStorageLevelOfMTree("root.laptop.d1")); - assertTrue(manager.checkStorageLevelOfMTree("root.laptop.d2")); - assertFalse(manager.checkStorageLevelOfMTree("root.laptop.d3")); - assertFalse(manager.checkStorageLevelOfMTree("root.laptop")); + assertFalse(manager.checkStorageGroupOfMTree("root")); + assertFalse(manager.checkStorageGroupOfMTree("root1.laptop.d2")); + + manager.setStorageGroupToMTree("root.laptop.d1"); + assertTrue(manager.checkStorageGroupOfMTree("root.laptop.d1")); + assertFalse(manager.checkStorageGroupOfMTree("root.laptop.d2")); + assertFalse(manager.checkStorageGroupOfMTree("root.laptop")); + assertFalse(manager.checkStorageGroupOfMTree("root.laptop.d1.s1")); + + manager.setStorageGroupToMTree("root.laptop.d2"); + assertTrue(manager.checkStorageGroupOfMTree("root.laptop.d1")); + assertTrue(manager.checkStorageGroupOfMTree("root.laptop.d2")); + assertFalse(manager.checkStorageGroupOfMTree("root.laptop.d3")); + assertFalse(manager.checkStorageGroupOfMTree("root.laptop")); } catch (MetadataErrorException e) { e.printStackTrace(); fail(e.getMessage()); @@ -290,8 +289,8 @@ public class MManagerBasicTest { MManager manager = MManager.getInstance(); try { - manager.setStorageLevelToMTree("root.laptop.d1"); - manager.setStorageLevelToMTree("root.laptop.d2"); + manager.setStorageGroupToMTree("root.laptop.d1"); + manager.setStorageGroupToMTree("root.laptop.d2"); manager.addPathToMTree(new Path("root.laptop.d1.s1"), TSDataType.INT32, TSEncoding.PLAIN, CompressionType.GZIP, null); manager.addPathToMTree(new Path("root.laptop.d2.s1"), TSDataType.INT32, TSEncoding.PLAIN, @@ -322,14 +321,14 @@ public class MManagerBasicTest { assertTrue(manager.getAllFileNamesByPath("root.vehicle.device").isEmpty()); assertTrue(manager.getAllFileNamesByPath("root.vehicle.device.sensor").isEmpty()); - manager.setStorageLevelToMTree("root.vehicle"); + manager.setStorageGroupToMTree("root.vehicle"); assertFalse(manager.getAllFileNamesByPath("root.vehicle").isEmpty()); assertFalse(manager.getAllFileNamesByPath("root.vehicle.device").isEmpty()); assertFalse(manager.getAllFileNamesByPath("root.vehicle.device.sensor").isEmpty()); assertTrue(manager.getAllFileNamesByPath("root.vehicle1").isEmpty()); assertTrue(manager.getAllFileNamesByPath("root.vehicle1.device").isEmpty()); - manager.setStorageLevelToMTree("root.vehicle1.device"); + manager.setStorageGroupToMTree("root.vehicle1.device"); assertTrue(manager.getAllFileNamesByPath("root.vehicle1.device1").isEmpty()); assertTrue(manager.getAllFileNamesByPath("root.vehicle1.device2").isEmpty()); assertTrue(manager.getAllFileNamesByPath("root.vehicle1.device3").isEmpty()); @@ -344,14 +343,14 @@ public class MManagerBasicTest { public void testMaximalSeriesNumberAmongStorageGroup() throws MetadataErrorException { MManager manager = MManager.getInstance(); assertEquals(0, manager.getMaximalSeriesNumberAmongStorageGroups()); - manager.setStorageLevelToMTree("root.laptop"); + manager.setStorageGroupToMTree("root.laptop"); assertEquals(0, manager.getMaximalSeriesNumberAmongStorageGroups()); manager.addPathToMTree("root.laptop.d1.s1", TSDataType.INT32, TSEncoding.PLAIN, CompressionType.GZIP, null); manager.addPathToMTree("root.laptop.d1.s2", TSDataType.INT32, TSEncoding.PLAIN, CompressionType.GZIP, null); assertEquals(2, manager.getMaximalSeriesNumberAmongStorageGroups()); - manager.setStorageLevelToMTree("root.vehicle"); + manager.setStorageGroupToMTree("root.vehicle"); manager.addPathToMTree("root.vehicle.d1.s1", TSDataType.INT32, TSEncoding.PLAIN, CompressionType.GZIP, null); assertEquals(2, manager.getMaximalSeriesNumberAmongStorageGroups()); diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java index ade6040b2a..33911b77b9 100644 --- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java +++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java @@ -46,7 +46,7 @@ public class MManagerImproveTest { public void setUp() throws Exception { EnvironmentUtils.envSetUp(); mManager = MManager.getInstance(); - mManager.setStorageLevelToMTree("root.t1.v2"); + mManager.setStorageGroupToMTree("root.t1.v2"); for (int j = 0; j < DEVICE_NUM; j++) { for (int i = 0; i < TIMESERIES_NUM; i++) { diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MetadataTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/MetadataTest.java index 4a79db2730..56098dbda7 100644 --- a/server/src/test/java/org/apache/iotdb/db/metadata/MetadataTest.java +++ b/server/src/test/java/org/apache/iotdb/db/metadata/MetadataTest.java @@ -45,34 +45,34 @@ public class MetadataTest { MManager manager = MManager.getInstance(); try { - manager.setStorageLevelToMTree("root.t.d1"); + manager.setStorageGroupToMTree("root.t.d1"); manager.addPathToMTree("root.t.d1.s0", "INT32", "RLE"); manager.addPathToMTree("root.t.d1.s1", "DOUBLE", "RLE"); - manager.setStorageLevelToMTree("root.t.d2"); + manager.setStorageGroupToMTree("root.t.d2"); manager.addPathToMTree("root.t.d2.s1", "DOUBLE", "RLE"); Metadata metadata1 = manager.getMetadata(); manager.clear(); - manager.setStorageLevelToMTree("root.t.d3"); + manager.setStorageGroupToMTree("root.t.d3"); manager.addPathToMTree("root.t.d3.s1", "DOUBLE", "RLE"); manager.addPathToMTree("root.t.d3.s2", "TEXT", "RLE"); - manager.setStorageLevelToMTree("root.t1.d1"); + manager.setStorageGroupToMTree("root.t1.d1"); manager.addPathToMTree("root.t1.d1.s1", "DOUBLE", "RLE"); manager.addPathToMTree("root.t1.d1.s2", "TEXT", "RLE"); Metadata metadata2 = manager.getMetadata(); manager.clear(); - manager.setStorageLevelToMTree("root.t.d1"); + manager.setStorageGroupToMTree("root.t.d1"); manager.addPathToMTree("root.t.d1.s0", "INT32", "RLE"); manager.addPathToMTree("root.t.d1.s1", "DOUBLE", "RLE"); - manager.setStorageLevelToMTree("root.t.d2"); + manager.setStorageGroupToMTree("root.t.d2"); manager.addPathToMTree("root.t.d2.s1", "DOUBLE", "RLE"); - manager.setStorageLevelToMTree("root.t.d3"); + manager.setStorageGroupToMTree("root.t.d3"); manager.addPathToMTree("root.t.d3.s1", "DOUBLE", "RLE"); manager.addPathToMTree("root.t.d3.s2", "TEXT", "RLE"); - manager.setStorageLevelToMTree("root.t1.d1"); + manager.setStorageGroupToMTree("root.t1.d1"); manager.addPathToMTree("root.t1.d1.s1", "DOUBLE", "RLE"); manager.addPathToMTree("root.t1.d1.s2", "TEXT", "RLE"); Metadata metadata = manager.getMetadata(); diff --git a/server/src/test/java/org/apache/iotdb/db/qp/QueryProcessorTest.java b/server/src/test/java/org/apache/iotdb/db/qp/QueryProcessorTest.java index c77ea83a35..3d5a6a8261 100644 --- a/server/src/test/java/org/apache/iotdb/db/qp/QueryProcessorTest.java +++ b/server/src/test/java/org/apache/iotdb/db/qp/QueryProcessorTest.java @@ -48,8 +48,8 @@ public class QueryProcessorTest { @Before public void setUp() throws Exception { EnvironmentUtils.envSetUp(); - mManager.setStorageLevelToMTree("root.vehicle"); - mManager.setStorageLevelToMTree("root.vehicle1"); + mManager.setStorageGroupToMTree("root.vehicle"); + mManager.setStorageGroupToMTree("root.vehicle1"); mManager.addPathToMTree("root.vehicle.device1.sensor1", TSDataType.valueOf("INT32"), TSEncoding.valueOf("RLE"), compressionType, Collections .emptyMap()); diff --git a/server/src/test/java/org/apache/iotdb/db/writelog/PerformanceTest.java b/server/src/test/java/org/apache/iotdb/db/writelog/PerformanceTest.java index d692b248ce..101456929d 100644 --- a/server/src/test/java/org/apache/iotdb/db/writelog/PerformanceTest.java +++ b/server/src/test/java/org/apache/iotdb/db/writelog/PerformanceTest.java @@ -124,7 +124,7 @@ public class PerformanceTest { tempProcessorStore.createNewFile(); try { - MManager.getInstance().setStorageLevelToMTree("root.logTestDevice"); + MManager.getInstance().setStorageGroupToMTree("root.logTestDevice"); } catch (MetadataErrorException ignored) { } MManager.getInstance().addPathToMTree("root.logTestDevice.s1", diff --git a/service-rpc/src/main/thrift/rpc.thrift b/service-rpc/src/main/thrift/rpc.thrift index 79ff7575fd..a3f838b8c0 100644 --- a/service-rpc/src/main/thrift/rpc.thrift +++ b/service-rpc/src/main/thrift/rpc.thrift @@ -300,7 +300,9 @@ service TSIService { TSStatus createTimeseries(1:TSCreateTimeseriesReq req); - TSStatus deleteTimeseries(1:list path) + TSStatus deleteTimeseries(1:list path) + + TSStatus deleteStorageGroups(1:list storageGroup); TSStatus insertRow(1:TSInsertReq req); diff --git a/session/src/main/java/org/apache/iotdb/session/Session.java b/session/src/main/java/org/apache/iotdb/session/Session.java index 03f130bcb9..0ad5508de8 100644 --- a/session/src/main/java/org/apache/iotdb/session/Session.java +++ b/session/src/main/java/org/apache/iotdb/session/Session.java @@ -235,6 +235,20 @@ public class Session { } } + public synchronized TSStatus deleteStorageGroup(String storageGroup) throws IoTDBSessionException { + List groups = new ArrayList<>(); + groups.add(storageGroup); + return deleteStorageGroups(groups); + } + + public synchronized TSStatus deleteStorageGroups(List storageGroup) throws IoTDBSessionException { + try { + return checkAndReturn(client.deleteStorageGroups(storageGroup)); + } catch (TException e) { + throw new IoTDBSessionException(e); + } + } + public synchronized TSStatus createTimeseries(String path, TSDataType dataType, TSEncoding encoding, CompressionType compressor) throws IoTDBSessionException { TSCreateTimeseriesReq request = new TSCreateTimeseriesReq(); request.setPath(path); diff --git a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java index 839f27f6ea..05d1c91ade 100644 --- a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java +++ b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionIT.java @@ -21,6 +21,9 @@ package org.apache.iotdb.session; import java.sql.*; import java.util.ArrayList; import java.util.List; +import java.io.File; + +import org.apache.iotdb.db.exception.ProcessorException; import org.apache.iotdb.db.service.IoTDB; import org.apache.iotdb.jdbc.Config; import org.apache.iotdb.session.utils.EnvironmentUtils; @@ -35,6 +38,8 @@ import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.assertEquals; + public class IoTDBSessionIT { private IoTDB daemon; @@ -72,6 +77,12 @@ public class IoTDBSessionIT { query2(); + // Add another storage group to test the deletion of storage group + session.setStorageGroup("root.sg2"); + session.createTimeseries("root.sg2.d1.s1", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY); + + deleteStorageGroupTest(); + session.close(); } @@ -190,4 +201,42 @@ public class IoTDBSessionIT { Assert.assertEquals(resultStr.toString(), standard); } } + + public void deleteStorageGroupTest() throws ClassNotFoundException, SQLException, IoTDBSessionException { + try { + session.deleteStorageGroup("root.sg1.d1.s1"); + } catch (IoTDBSessionException e) { + assertEquals("The path root.sg1.d1.s1 is not a deletable storage group", e.getMessage()); + } + session.deleteStorageGroup("root.sg1"); + File folder = new File("data/system/storage_groups/root.sg1/"); + assertEquals(folder.exists(), false); + session.setStorageGroup("root.sg1.d1"); + session.createTimeseries("root.sg1.d1.s1", TSDataType.INT64, TSEncoding.RLE, CompressionType.SNAPPY); + // using the query result as the QueryTest to verify the deletion and the new insertion + Class.forName(Config.JDBC_DRIVER_NAME); + String standard = "Time\n" + "root.sg1.d1.s1\n" + "root.sg2.d1.s1\n"; + try (Connection connection = DriverManager + .getConnection(Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root"); + Statement statement = connection.createStatement()) { + ResultSet resultSet = statement.executeQuery("select * from root"); + final ResultSetMetaData metaData = resultSet.getMetaData(); + final int colCount = metaData.getColumnCount(); + StringBuilder resultStr = new StringBuilder(); + for (int i = 0; i < colCount; i++) { + resultStr.append(metaData.getColumnLabel(i + 1) + "\n"); + } + while (resultSet.next()) { + for (int i = 1; i <= colCount; i++) { + resultStr.append(resultSet.getString(i)).append(","); + } + resultStr.append("\n"); + } + Assert.assertEquals(resultStr.toString(), standard); + List storageGroups = new ArrayList<>(); + storageGroups.add("root.sg1.d1"); + storageGroups.add("root.sg2"); + session.deleteStorageGroups(storageGroups); + } + } } -- GitLab