Skip to content

Commit 0507f0b

Browse files
authored
Load: Stablized the IoTDBLoadTsFileWithModIT (#17787)
1 parent ddeb23b commit 0507f0b

1 file changed

Lines changed: 249 additions & 0 deletions

File tree

Lines changed: 249 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
package org.apache.iotdb.db.it;
21+
22+
import org.apache.iotdb.commons.exception.IllegalPathException;
23+
import org.apache.iotdb.commons.path.MeasurementPath;
24+
import org.apache.iotdb.db.exception.DataRegionException;
25+
import org.apache.iotdb.db.storageengine.dataregion.modification.Deletion;
26+
import org.apache.iotdb.db.storageengine.dataregion.modification.ModificationFile;
27+
import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResource;
28+
import org.apache.iotdb.db.storageengine.dataregion.tsfile.TsFileResourceStatus;
29+
import org.apache.iotdb.db.storageengine.dataregion.wal.recover.file.SealedTsFileRecoverPerformer;
30+
import org.apache.iotdb.it.env.EnvFactory;
31+
import org.apache.iotdb.it.framework.IoTDBTestRunner;
32+
import org.apache.iotdb.itbase.category.ClusterIT;
33+
import org.apache.iotdb.itbase.category.LocalStandaloneIT;
34+
import org.apache.iotdb.itbase.exception.InconsistentDataException;
35+
36+
import org.apache.tsfile.enums.TSDataType;
37+
import org.apache.tsfile.exception.write.WriteProcessException;
38+
import org.apache.tsfile.read.common.Path;
39+
import org.apache.tsfile.write.TsFileWriter;
40+
import org.apache.tsfile.write.record.Tablet;
41+
import org.apache.tsfile.write.schema.MeasurementSchema;
42+
import org.junit.AfterClass;
43+
import org.junit.Assert;
44+
import org.junit.BeforeClass;
45+
import org.junit.Test;
46+
import org.junit.experimental.categories.Category;
47+
import org.junit.runner.RunWith;
48+
49+
import java.io.File;
50+
import java.io.IOException;
51+
import java.nio.file.Files;
52+
import java.sql.Connection;
53+
import java.sql.ResultSet;
54+
import java.sql.SQLException;
55+
import java.sql.Statement;
56+
import java.util.Collections;
57+
58+
@RunWith(IoTDBTestRunner.class)
59+
@Category({LocalStandaloneIT.class, ClusterIT.class})
60+
public class IoTDBLoadTsFileWithModIT {
61+
private static File tmpDir;
62+
63+
@BeforeClass
64+
public static void setUp() throws Exception {
65+
tmpDir = new File(Files.createTempDirectory("load").toUri());
66+
EnvFactory.getEnv().initClusterEnvironment();
67+
}
68+
69+
@AfterClass
70+
public static void tearDown() throws Exception {
71+
try {
72+
if (tmpDir != null && tmpDir.exists()) {
73+
File[] files = tmpDir.listFiles();
74+
if (files != null) {
75+
for (File file : files) {
76+
try {
77+
Files.delete(file.toPath());
78+
} catch (IOException ignored) {
79+
// ignore
80+
}
81+
}
82+
}
83+
try {
84+
Files.delete(tmpDir.toPath());
85+
} catch (IOException ignored) {
86+
// ignore
87+
}
88+
}
89+
} finally {
90+
EnvFactory.getEnv().cleanClusterEnvironment();
91+
}
92+
}
93+
94+
private static void clearTmpDir() {
95+
if (tmpDir == null || !tmpDir.exists()) {
96+
return;
97+
}
98+
File[] files = tmpDir.listFiles();
99+
if (files == null) {
100+
return;
101+
}
102+
for (File file : files) {
103+
try {
104+
Files.delete(file.toPath());
105+
} catch (IOException ignored) {
106+
// ignore
107+
}
108+
}
109+
}
110+
111+
private static void executeQuietly(Statement statement, String sql) {
112+
try {
113+
statement.execute(sql);
114+
} catch (SQLException ignored) {
115+
// ignore
116+
}
117+
}
118+
119+
private static void cleanupTestDb() {
120+
try (Connection connection = EnvFactory.getEnv().getConnection();
121+
Statement statement = connection.createStatement()) {
122+
executeQuietly(statement, "DELETE DATABASE root.test.**");
123+
executeQuietly(statement, "DELETE DATABASE root.test");
124+
} catch (SQLException ignored) {
125+
// ignore
126+
}
127+
}
128+
129+
private void generateFileWithModFile()
130+
throws IOException, WriteProcessException, IllegalPathException, DataRegionException {
131+
TsFileResource resource = generateFile();
132+
try (ModificationFile modFile = ModificationFile.getNormalMods(resource)) {
133+
modFile.write(new Deletion(new MeasurementPath("root.test.d1.de.s1"), Long.MAX_VALUE, 1, 2));
134+
}
135+
}
136+
137+
private TsFileResource generateFile()
138+
throws WriteProcessException, IOException, DataRegionException {
139+
File tsfile = new File(tmpDir, "1-1-0-0.tsfile");
140+
try (TsFileWriter writer = new TsFileWriter(tsfile)) {
141+
writer.registerAlignedTimeseries(
142+
new Path("root.test.d1.de"),
143+
Collections.singletonList(new MeasurementSchema("s1", TSDataType.BOOLEAN)));
144+
Tablet tablet =
145+
new Tablet(
146+
"root.test.d1.de",
147+
Collections.singletonList(new MeasurementSchema("s1", TSDataType.BOOLEAN)));
148+
for (int i = 0; i < 5; i++) {
149+
int rowIndex = tablet.rowSize++;
150+
tablet.addTimestamp(rowIndex, i);
151+
tablet.addValue("s1", rowIndex, true);
152+
}
153+
writer.writeAligned(tablet);
154+
}
155+
// generate resource file
156+
TsFileResource resource = new TsFileResource(tsfile);
157+
try (SealedTsFileRecoverPerformer performer = new SealedTsFileRecoverPerformer(resource)) {
158+
performer.recover();
159+
}
160+
resource.setStatusForTest(TsFileResourceStatus.NORMAL);
161+
resource.deserialize();
162+
return resource;
163+
}
164+
165+
@Test
166+
public void testWithNewModFile()
167+
throws SQLException,
168+
IOException,
169+
DataRegionException,
170+
WriteProcessException,
171+
IllegalPathException {
172+
try {
173+
generateFileWithModFile();
174+
try (final Connection connection = EnvFactory.getEnv().getConnection();
175+
final Statement statement = connection.createStatement()) {
176+
177+
statement.execute(String.format("load \'%s\'", tmpDir.getAbsolutePath()));
178+
179+
try (final ResultSet resultSet =
180+
statement.executeQuery("select count(s1) as c from root.test.d1.de")) {
181+
Assert.assertTrue(resultSet.next());
182+
Assert.assertEquals(3, resultSet.getLong("c"));
183+
}
184+
}
185+
} finally {
186+
clearTmpDir();
187+
cleanupTestDb();
188+
}
189+
}
190+
191+
@Test
192+
public void testWithNewModFileAndLoadAttributes()
193+
throws SQLException,
194+
IOException,
195+
DataRegionException,
196+
WriteProcessException,
197+
IllegalPathException {
198+
try {
199+
generateFileWithModFile();
200+
final String databaseName = "root.test.d1";
201+
202+
try (final Connection connection = EnvFactory.getEnv().getConnection();
203+
final Statement statement = connection.createStatement()) {
204+
205+
statement.execute(
206+
String.format(
207+
"load \'%s\' with ("
208+
+ "'database-level'='2',"
209+
+ "'verify'='true',"
210+
+ "'on-success'='none',"
211+
+ "'async'='true')",
212+
tmpDir.getAbsolutePath()));
213+
214+
boolean databaseFound = false;
215+
for (int i = 0; i < 10; i++) {
216+
try (final ResultSet resultSet = statement.executeQuery("show databases")) {
217+
while (resultSet.next()) {
218+
final String currentDatabase = resultSet.getString(1);
219+
if (databaseName.equalsIgnoreCase(currentDatabase)) {
220+
databaseFound = true;
221+
break;
222+
}
223+
}
224+
} catch (InconsistentDataException ignored) {
225+
// Async load propagates the new database metadata to different DataNodes at
226+
// slightly different times, so "show databases" may be inconsistent transiently.
227+
}
228+
229+
if (databaseFound) {
230+
break;
231+
}
232+
233+
try {
234+
Thread.sleep(1000);
235+
} catch (InterruptedException e) {
236+
Thread.currentThread().interrupt();
237+
break;
238+
}
239+
}
240+
Assert.assertTrue(
241+
"The `database-level` parameter is not working; the generated database does not contain 'root.test.d1'.",
242+
databaseFound);
243+
}
244+
} finally {
245+
clearTmpDir();
246+
cleanupTestDb();
247+
}
248+
}
249+
}

0 commit comments

Comments
 (0)