Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,21 @@

import org.apache.iotdb.commons.utils.KillPoint.KillNode;
import org.apache.iotdb.confignode.it.regionmigration.IoTDBRegionOperationReliabilityITFramework;
import org.apache.iotdb.it.env.EnvFactory;
import org.apache.iotdb.it.framework.IoTDBTestRunner;
import org.apache.iotdb.itbase.category.ClusterIT;

import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import static org.apache.iotdb.util.MagicUtils.makeItCloseQuietly;

@Category({ClusterIT.class})
@RunWith(IoTDBTestRunner.class)
public class IoTDBRegionMigrateNormalITForIoTV2BatchIT
Expand All @@ -41,4 +49,30 @@ public void normal1C2DTest() throws Exception {
public void normal3C3DTest() throws Exception {
successTest(2, 3, 3, 3, noKillPoints(), noKillPoints(), KillNode.ALL_NODES);
}

@Test
public void migrateRegionWithDegradedTimeIndexTest() throws Exception {
// set TsFileResource memory to 0 to trigger degrading
EnvFactory.getEnv().getConfig().getCommonConfig().setQueryMemoryProportion("1:1:1:1:1:1:0");

successTest(1, 1, 1, 2, noKillPoints(), noKillPoints(), KillNode.ALL_NODES);

try (final Connection connection = makeItCloseQuietly(EnvFactory.getEnv().getConnection());
final Statement statement = makeItCloseQuietly(connection.createStatement())) {
assertCounts(statement, 1, 1);
statement.execute("INSERT INTO root.sg.d1(timestamp,speed,temperature) values(101, 3, 4)");
assertCounts(statement, 2, 2);
}
}

private static void assertCounts(
final Statement statement, final long expectedSpeedCount, final long expectedTemperatureCount)
throws Exception {
try (final ResultSet resultSet =
statement.executeQuery("select count(speed), count(temperature) from root.sg.d1")) {
Assert.assertTrue(resultSet.next());
Assert.assertEquals(expectedSpeedCount, resultSet.getLong(1));
Assert.assertEquals(expectedTemperatureCount, resultSet.getLong(2));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@

private void serializeTo(BufferedOutputStream outputStream) throws IOException {
ReadWriteIOUtils.write(VERSION_NUMBER, outputStream);
timeIndex.serialize(outputStream);
getTimeIndexForSerialization().serialize(outputStream);

ReadWriteIOUtils.write(maxPlanIndex, outputStream);
ReadWriteIOUtils.write(minPlanIndex, outputStream);
Expand Down Expand Up @@ -317,6 +317,14 @@
ReadWriteIOUtils.write(isGeneratedByPipe, outputStream);
}

private ITimeIndex getTimeIndexForSerialization() throws IOException {
if (!(timeIndex instanceof FileTimeIndex) || !resourceFileExists()) {
return timeIndex;
}

return buildDeviceTimeIndex();
}

/** deserialize from disk */
public void deserialize() throws IOException {
try (InputStream inputStream = fsFactory.getBufferedInputStream(file + RESOURCE_SUFFIX)) {
Expand Down Expand Up @@ -694,20 +702,13 @@
throws IOException {
readLock();
try {
if (!resourceFileExists()) {
throw new IOException(StorageEngineMessages.RESOURCE_FILE_NOT_FOUND);
}
try (InputStream inputStream =
FSFactoryProducer.getFSFactory()
.getBufferedInputStream(file.getPath() + RESOURCE_SUFFIX)) {
ReadWriteIOUtils.readByte(inputStream);
ITimeIndex timeIndexFromResourceFile =
ITimeIndex.createTimeIndex(inputStream, deserializer);
if (!(timeIndexFromResourceFile instanceof ArrayDeviceTimeIndex)) {
throw new IOException(
StorageEngineMessages.CANNOT_BUILD_DEVICE_TIME_INDEX + file.getPath());
try {
ITimeIndex timeIndexFromResourceFile = deserializeTimeIndexFromResourceFile(deserializer);
if (timeIndexFromResourceFile instanceof ArrayDeviceTimeIndex) {

Check warning on line 707 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this instanceof check and cast with 'instanceof ArrayDeviceTimeIndex arraydevicetimeindex'

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ9BUG0sjrK77bPwl7iM&open=AZ9BUG0sjrK77bPwl7iM&pullRequest=18155
return (ArrayDeviceTimeIndex) timeIndexFromResourceFile;
}
return (ArrayDeviceTimeIndex) timeIndexFromResourceFile;
throw new IOException(
StorageEngineMessages.CANNOT_BUILD_DEVICE_TIME_INDEX + file.getPath());
} catch (Exception e) {
throw new IOException(
String.format(
Expand All @@ -721,7 +722,19 @@
}
}

private ITimeIndex deserializeTimeIndexFromResourceFile(IDeviceID.Deserializer deserializer)
throws IOException {
if (!resourceFileExists()) {
throw new IOException(StorageEngineMessages.RESOURCE_FILE_NOT_FOUND);
}
try (InputStream inputStream =
FSFactoryProducer.getFSFactory().getBufferedInputStream(file.getPath() + RESOURCE_SUFFIX)) {
ReadWriteIOUtils.readByte(inputStream);
return ITimeIndex.createTimeIndex(inputStream, deserializer);
}
}

public ArrayDeviceTimeIndex buildDeviceTimeIndex() throws IOException {

Check warning on line 737 in iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/tsfile/TsFileResource.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

All overloaded methods should be placed next to each other. Placing non-overloaded methods in between overloaded methods with the same type is a violation. Previous overloaded method located at line '701'.

See more on https://sonarcloud.io/project/issues?id=apache_iotdb&issues=AZ9BUG0sjrK77bPwl7iN&open=AZ9BUG0sjrK77bPwl7iN&pullRequest=18155
return buildDeviceTimeIndex(IDeviceID.Deserializer.DEFAULT_DESERIALIZER);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void tearDown() throws IOException {
if (file.exists()) {
FileUtils.delete(file);
}
File resourceFile = new File(file.getName() + TsFileResource.RESOURCE_SUFFIX);
File resourceFile = new File(file.getPath() + TsFileResource.RESOURCE_SUFFIX);
if (resourceFile.exists()) {
FileUtils.delete(resourceFile);
}
Expand All @@ -108,7 +108,22 @@ public void testSerializeAndDeserialize() throws IOException {
}

@Test
public void testDegradeAndFileTimeIndex() {
public void testSerializeDegradedTimeIndex() throws IOException {
tsFileResource.serialize();
tsFileResource.degradeTimeIndex();

tsFileResource.serialize();

TsFileResource derTsFileResource = new TsFileResource(file);
derTsFileResource.deserialize();
Assert.assertEquals(
ITimeIndex.ARRAY_DEVICE_TIME_INDEX_TYPE, derTsFileResource.getTimeIndexType());
Assert.assertEquals(deviceToIndex.keySet(), derTsFileResource.getDevices());
}

@Test
public void testDegradeAndFileTimeIndex() throws IOException {
tsFileResource.serialize();
Assert.assertEquals(ITimeIndex.ARRAY_DEVICE_TIME_INDEX_TYPE, tsFileResource.getTimeIndexType());
tsFileResource.degradeTimeIndex();
Assert.assertEquals(ITimeIndex.FILE_TIME_INDEX_TYPE, tsFileResource.getTimeIndexType());
Expand Down
Loading