Skip to content

Commit d2545fb

Browse files
CRZbulabulaHTHou
authored andcommitted
[To dev/1.3][Bug fix] The partition table is cleaned incorrectly when set only device TTL for tree mode (#17123) (#17126)
1 parent 032df7c commit d2545fb

5 files changed

Lines changed: 121 additions & 3 deletions

File tree

integration-test/src/test/java/org/apache/iotdb/confignode/it/partition/IoTDBPartitionTableAutoCleanIT.java

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class IoTDBPartitionTableAutoCleanIT {
4848

4949
private static final int TEST_REPLICATION_FACTOR = 1;
5050
private static final long TEST_TIME_PARTITION_INTERVAL = 604800000;
51-
private static final long TEST_TTL_CHECK_INTERVAL = 5_000;
51+
private static final long TEST_TTL_CHECK_INTERVAL_IN_MS = 5_00;
5252

5353
private static final TTimePartitionSlot TEST_CURRENT_TIME_SLOT =
5454
new TTimePartitionSlot()
@@ -66,7 +66,7 @@ public void setUp() throws Exception {
6666
.setSchemaReplicationFactor(TEST_REPLICATION_FACTOR)
6767
.setDataReplicationFactor(TEST_REPLICATION_FACTOR)
6868
.setTimePartitionInterval(TEST_TIME_PARTITION_INTERVAL)
69-
.setTTLCheckInterval(TEST_TTL_CHECK_INTERVAL);
69+
.setTTLCheckInterval(TEST_TTL_CHECK_INTERVAL_IN_MS);
7070

7171
// Init 1C1D environment
7272
EnvFactory.getEnv().initClusterEnvironment(1, 1);
@@ -132,4 +132,57 @@ public void testAutoCleanPartitionTableForTreeModel() throws Exception {
132132
}
133133
Assert.fail("The PartitionTable in the ConfigNode is not auto cleaned!");
134134
}
135+
136+
@Test
137+
public void testAutoCleanTakesNoEffectsForTreeDeviceTTL() throws Exception {
138+
try (Connection connection = EnvFactory.getEnv().getConnection();
139+
Statement statement = connection.createStatement()) {
140+
// Create databases and insert test data
141+
for (int i = 0; i < 3; i++) {
142+
String databaseName = String.format("%s%d", TREE_DATABASE_PREFIX, i);
143+
statement.execute(String.format("CREATE DATABASE %s", databaseName));
144+
statement.execute(
145+
String.format(
146+
"CREATE TIMESERIES %s.s WITH DATATYPE=INT64,ENCODING=PLAIN", databaseName));
147+
// Insert expired data
148+
statement.execute(
149+
String.format(
150+
"INSERT INTO %s(timestamp, s) VALUES (%d, %d)",
151+
databaseName, TEST_CURRENT_TIME_SLOT.getStartTime() - TEST_TTL * 2, -1));
152+
// Insert existed data
153+
statement.execute(
154+
String.format(
155+
"INSERT INTO %s(timestamp, s) VALUES (%d, %d)",
156+
databaseName, TEST_CURRENT_TIME_SLOT.getStartTime(), 1));
157+
// Create an empty device and set a TTL.
158+
// This TTL should not trigger the auto cleaner,
159+
// since the database does not have a TTL.
160+
statement.execute(
161+
String.format(
162+
"CREATE TIMESERIES %s.m.empty WITH DATATYPE=INT64,ENCODING=PLAIN", databaseName));
163+
statement.execute(String.format("SET TTL TO %s.m.** %d", databaseName, TEST_TTL));
164+
}
165+
}
166+
167+
TDataPartitionReq req = new TDataPartitionReq();
168+
for (int i = 0; i < 3; i++) {
169+
req.putToPartitionSlotsMap(String.format("%s%d", TREE_DATABASE_PREFIX, i), new TreeMap<>());
170+
}
171+
try (SyncConfigNodeIServiceClient client =
172+
(SyncConfigNodeIServiceClient) EnvFactory.getEnv().getLeaderConfigNodeConnection()) {
173+
for (int retry = 0; retry < 10; retry++) {
174+
// Ensure the partitions are not cleaned
175+
boolean partitionTableAutoCleaned = false;
176+
TDataPartitionTableResp resp = client.getDataPartitionTable(req);
177+
if (TSStatusCode.SUCCESS_STATUS.getStatusCode() == resp.getStatus().getCode()) {
178+
partitionTableAutoCleaned =
179+
resp.getDataPartitionTable().entrySet().stream()
180+
.flatMap(e1 -> e1.getValue().entrySet().stream())
181+
.allMatch(e2 -> e2.getValue().size() == 1);
182+
}
183+
Assert.assertFalse(partitionTableAutoCleaned);
184+
TimeUnit.SECONDS.sleep(1);
185+
}
186+
}
187+
}
135188
}

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/TTLManager.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,20 @@ public int getTTLCount() {
129129
return ttlInfo.getTTLCount();
130130
}
131131

132+
/**
133+
* Get the maximum ttl of the corresponding database level.
134+
*
135+
* @param database the path of the database.
136+
* @return the maximum ttl of the corresponding database level.
137+
*/
138+
public long getDatabaseLevelTTL(final String database) {
139+
final long ttl = ttlInfo.getDatabaseLevelTTL(database);
140+
return ttl == Long.MAX_VALUE || ttl < 0
141+
? ttl
142+
: CommonDateTimeUtils.convertMilliTimeWithPrecision(
143+
ttl, CommonDescriptor.getInstance().getConfig().getTimestampPrecision());
144+
}
145+
132146
/**
133147
* Get the maximum ttl of the subtree of the corresponding database.
134148
*

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/TTLInfo.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,23 @@ public int getTTLCount() {
157157
}
158158
}
159159

160+
/**
161+
* Get the maximum ttl of the corresponding database level.
162+
*
163+
* @param database the path of the database.
164+
* @return the maximum ttl of the corresponding database level.
165+
*/
166+
public long getDatabaseLevelTTL(final String database) {
167+
lock.readLock().lock();
168+
try {
169+
return ttlCache.getDatabaseLevelTTL(database);
170+
} catch (IllegalPathException e) {
171+
return TTLCache.NULL_TTL;
172+
} finally {
173+
lock.readLock().unlock();
174+
}
175+
}
176+
160177
/**
161178
* Get the maximum ttl of the subtree of the corresponding database.
162179
*

iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/PartitionTableAutoCleaner.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ protected void periodicExecute(Env env) {
6060
List<String> databases = configManager.getClusterSchemaManager().getDatabaseNames();
6161
Map<String, Long> databaseTTLMap = new TreeMap<>();
6262
for (String database : databases) {
63-
long databaseTTL = configManager.getTTLManager().getDatabaseMaxTTL(database);
63+
long databaseTTL = configManager.getTTLManager().getDatabaseLevelTTL(database);
64+
if (0 < databaseTTL && databaseTTL < Long.MAX_VALUE) {
65+
// For tree mode, the auto cleaner takes effect only when the database-level TTL is set.
66+
// Subsequently, we employ the maximum TTL among all time series in this database.
67+
databaseTTL = configManager.getTTLManager().getDatabaseMaxTTL(database);
68+
}
6469
databaseTTLMap.put(database, databaseTTL);
6570
}
6671
LOGGER.info(

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/ttl/TTLCache.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,35 @@ public long getLastNodeTTL(String[] nodes) {
171171
return node.ttl;
172172
}
173173

174+
/**
175+
* Get the maximum ttl of the corresponding database level.
176+
*
177+
* @param database the path of the database.
178+
* @return the maximum ttl of the corresponding database level.
179+
* @throws IllegalPathException if the database path is illegal.
180+
*/
181+
public long getDatabaseLevelTTL(String database) throws IllegalPathException {
182+
long curTTL = NULL_TTL;
183+
// Get global TTL root.** if exists
184+
CacheNode curNode = ttlCacheTree.searchChild(IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD);
185+
if (curNode != null && curNode.ttl < Long.MAX_VALUE) {
186+
curTTL = curNode.ttl;
187+
}
188+
// Compare database TTL if exists
189+
curNode = ttlCacheTree.searchChild(database);
190+
if (curNode != null && curNode.ttl < Long.MAX_VALUE) {
191+
curTTL = Math.max(curTTL, curNode.ttl);
192+
}
193+
// Compare database.** TTL if exists
194+
curNode =
195+
ttlCacheTree.searchChild(
196+
database + IoTDBConstant.PATH_SEPARATOR + IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD);
197+
if (curNode != null && curNode.ttl < Long.MAX_VALUE) {
198+
curTTL = Math.max(curTTL, curNode.ttl);
199+
}
200+
return curTTL;
201+
}
202+
174203
/**
175204
* Get the maximum ttl of the subtree of the corresponding database.
176205
*

0 commit comments

Comments
 (0)