Skip to content

Commit f8b8f82

Browse files
CRZbulabulaJackieTien97
authored andcommitted
Uncomment commented set-configuration-able items in the config template (fix enable_topology_probing & topology_probing_* hot/restart reload) (#17933)
1 parent 8c0566a commit f8b8f82

3 files changed

Lines changed: 125 additions & 6 deletions

File tree

‎integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBSetConfigurationIT.java‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,35 @@ public void testSetConfiguration() {
8888
"enable_cross_space_compaction=false")));
8989
}
9090

91+
/**
92+
* Regression test for V2-995: the topology-probing config items were left commented out in the
93+
* template, so {@code getConfigurationItemsFromTemplate} never recorded them as known defaults
94+
* and {@code set configuration} rejected them as "immutable or undefined". After uncommenting
95+
* them, {@code set configuration} must accept and persist them: {@code enable_topology_probing}
96+
* (hot_reload) and {@code topology_probing_base_interval_in_ms} / {@code
97+
* topology_probing_timeout_ratio} (restart).
98+
*/
99+
@Test
100+
public void testSetTopologyProbingConfiguration() {
101+
try (Connection connection = EnvFactory.getEnv().getConnection();
102+
Statement statement = connection.createStatement()) {
103+
statement.execute("set configuration \"enable_topology_probing\"=\"true\"");
104+
statement.execute("set configuration \"topology_probing_base_interval_in_ms\"=\"3000\"");
105+
statement.execute("set configuration \"topology_probing_timeout_ratio\"=\"0.4\"");
106+
} catch (Exception e) {
107+
Assert.fail(e.getMessage());
108+
}
109+
Assert.assertTrue(
110+
EnvFactory.getEnv().getConfigNodeWrapperList().stream()
111+
.allMatch(
112+
nodeWrapper ->
113+
checkConfigFileContains(
114+
nodeWrapper,
115+
"enable_topology_probing=true",
116+
"topology_probing_base_interval_in_ms=3000",
117+
"topology_probing_timeout_ratio=0.4")));
118+
}
119+
91120
@Test
92121
public void testSetClusterName() throws Exception {
93122
// set cluster name on cn and dn
@@ -207,6 +236,14 @@ public void testSetDefaultSGLevel() throws SQLException {
207236
"509: An error occurred when executing getDeviceToDatabase():root.db1 is not a legal path, because it is no longer than default sg level: 3",
208237
e.getMessage());
209238
}
239+
} finally {
240+
// This test leaves default_database_level=-1 baked into the cluster's config file. Because
241+
// tests in this class share one cluster and run in random order, a later 'set configuration'
242+
// test would otherwise fail its hot-reload while re-validating the leftover illegal value
243+
// ("Illegal defaultDatabaseLevel: -1, should >= 1"). Restore a clean cluster before leaving.
244+
EnvFactory.getEnv().cleanClusterEnvironment();
245+
EnvFactory.getEnv().getConfig().getCommonConfig().setDefaultDatabaseLevel(1);
246+
EnvFactory.getEnv().initClusterEnvironment();
210247
}
211248
}
212249
}

‎iotdb-core/datanode/src/test/java/org/apache/iotdb/db/utils/ConfigurationFileUtilsTest.java‎

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,26 @@
1919

2020
package org.apache.iotdb.db.utils;
2121

22+
import org.apache.iotdb.commons.conf.CommonConfig;
2223
import org.apache.iotdb.commons.conf.ConfigurationFileUtils;
2324
import org.apache.iotdb.db.utils.constant.TestConstant;
2425

2526
import org.junit.After;
2627
import org.junit.Assert;
2728
import org.junit.Test;
2829

30+
import java.io.BufferedReader;
2931
import java.io.File;
3032
import java.io.FileReader;
3133
import java.io.IOException;
34+
import java.io.InputStream;
35+
import java.io.InputStreamReader;
3236
import java.nio.file.Files;
37+
import java.util.HashSet;
3338
import java.util.Map;
3439
import java.util.Objects;
3540
import java.util.Properties;
41+
import java.util.Set;
3642

3743
public class ConfigurationFileUtilsTest {
3844

@@ -89,6 +95,82 @@ public void checkIoTDBSystemTemplateFileFormat() throws IOException {
8995
}
9096
}
9197

98+
/**
99+
* Regression guard for V2-995: a configuration item whose {@code effectiveMode} allows {@code set
100+
* configuration} (i.e. anything except {@code FIRST_START}) must have its {@code key=value} line
101+
* left uncommented in the template. {@code getConfigurationItemsFromTemplate} only parses
102+
* uncommented lines, so a commented item never enters {@code configuration2DefaultValue}; {@code
103+
* filterInvalidConfigItems} then treats it as undefined and {@code set configuration} rejects it
104+
* with "immutable or undefined" — silently disabling the advertised dynamic-config entry point.
105+
* This was the root cause for {@code enable_topology_probing} (hot_reload) and the two {@code
106+
* topology_probing_*} items (restart).
107+
*/
108+
@Test
109+
public void checkSettableItemsAreUncommentedInTemplate() throws IOException {
110+
// Keys whose value line appears uncommented at least once. Some keys (e.g. dn_data_dirs) list a
111+
// commented Windows-path variant next to an uncommented Unix-path variant; only the uncommented
112+
// one is parsed, so such keys are fine and must not be flagged.
113+
Set<String> uncommentedKeys = new HashSet<>();
114+
// Keys with a commented value line whose enclosing block declares a settable effectiveMode.
115+
Set<String> commentedSettableKeys = new HashSet<>();
116+
try (InputStream inputStream =
117+
ConfigurationFileUtilsTest.class
118+
.getClassLoader()
119+
.getResourceAsStream(CommonConfig.SYSTEM_CONFIG_TEMPLATE_NAME);
120+
BufferedReader reader =
121+
new BufferedReader(new InputStreamReader(Objects.requireNonNull(inputStream)))) {
122+
String line;
123+
ConfigurationFileUtils.EffectiveModeType currentMode = null;
124+
while ((line = reader.readLine()) != null) {
125+
line = line.trim();
126+
if (line.isEmpty()) {
127+
// Blank line separates configuration blocks; reset the accumulated effectiveMode.
128+
currentMode = null;
129+
continue;
130+
}
131+
if (line.startsWith("# effectiveMode:")) {
132+
currentMode =
133+
ConfigurationFileUtils.EffectiveModeType.getEffectiveMode(
134+
line.substring("# effectiveMode:".length()).trim());
135+
continue;
136+
}
137+
// Detect the (possibly commented) "key=value" line that closes a block.
138+
String stripped = line.startsWith("#") ? line.substring(1).trim() : line;
139+
int equalsIndex = stripped.indexOf('=');
140+
boolean isValueLine =
141+
equalsIndex > 0 && stripped.substring(0, equalsIndex).trim().matches("[a-zA-Z0-9_.]+");
142+
if (!isValueLine) {
143+
continue;
144+
}
145+
String key = stripped.substring(0, equalsIndex).trim();
146+
if (line.startsWith("#")) {
147+
// FIRST_START items are intentionally rejected by 'set configuration'; UNKNOWN items have
148+
// no declared mode. Only flag items that 'set configuration' is supposed to accept.
149+
if (isSettableByConfiguration(currentMode)) {
150+
commentedSettableKeys.add(key);
151+
}
152+
} else {
153+
uncommentedKeys.add(key);
154+
}
155+
// A value line ends the current block's effectiveMode scope.
156+
currentMode = null;
157+
}
158+
}
159+
commentedSettableKeys.removeAll(uncommentedKeys);
160+
Assert.assertTrue(
161+
"configuration items settable via 'set configuration' must be uncommented in the template "
162+
+ "so the command can reach them instead of rejecting them as undefined; "
163+
+ "commented settable items found: "
164+
+ commentedSettableKeys,
165+
commentedSettableKeys.isEmpty());
166+
}
167+
168+
private static boolean isSettableByConfiguration(ConfigurationFileUtils.EffectiveModeType mode) {
169+
return mode == ConfigurationFileUtils.EffectiveModeType.HOT_RELOAD
170+
|| mode == ConfigurationFileUtils.EffectiveModeType.RESTART
171+
|| mode == ConfigurationFileUtils.EffectiveModeType.FIRST_START_OR_SET_CONFIGURATION;
172+
}
173+
92174
private void generateFile(File file, String content) throws IOException {
93175
Files.write(file.toPath(), content.getBytes());
94176
}

‎iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ cn_max_client_count_for_each_node_in_client_manager=1000
512512
# 0 means no idle clients will be retained, connections are destroyed immediately upon return.
513513
# effectiveMode: restart
514514
# Datatype: int
515-
# cn_max_idle_client_count_for_each_node_in_client_manager=1000
515+
cn_max_idle_client_count_for_each_node_in_client_manager=1000
516516

517517
# The maximum session idle time. unit: ms
518518
# Idle sessions are the ones that performs neither query or non-query operations for a period of time
@@ -571,7 +571,7 @@ dn_max_client_count_for_each_node_in_client_manager=1000
571571
# 0 means no idle clients will be retained, connections are destroyed immediately upon return.
572572
# effectiveMode: restart
573573
# Datatype: int
574-
# dn_max_idle_client_count_for_each_node_in_client_manager=1000
574+
dn_max_idle_client_count_for_each_node_in_client_manager=1000
575575

576576
####################
577577
### REST Service Configuration
@@ -686,7 +686,7 @@ data_region_per_data_node=0
686686
# 3. PGP (Partite-Graph Placement; based on the PGP paper, with database-aware balance)
687687
# effectiveMode: restart
688688
# Datatype: String
689-
# region_group_allocate_policy=GCR
689+
region_group_allocate_policy=GCR
690690

691691
# Whether to enable auto leader balance for Ratis consensus protocol.
692692
# The ConfigNode-leader will balance the leader of Ratis-RegionGroups by leader_distribution_policy if set true.
@@ -747,17 +747,17 @@ failure_detector_phi_acceptable_pause_in_ms=10000
747747
# Whether to enable topology probing between DataNodes
748748
# effectiveMode: hot_reload
749749
# Datatype: Boolean
750-
# enable_topology_probing=false
750+
enable_topology_probing=false
751751

752752
# Base interval in ms for topology probing between DataNodes
753753
# effectiveMode: restart
754754
# Datatype: long
755-
# topology_probing_base_interval_in_ms=5000
755+
topology_probing_base_interval_in_ms=5000
756756

757757
# Ratio of probing timeout to probing interval (must be less than 1.0)
758758
# effectiveMode: restart
759759
# Datatype: double
760-
# topology_probing_timeout_ratio=0.5
760+
topology_probing_timeout_ratio=0.5
761761

762762
# Disk remaining threshold at which DataNode is set to ReadOnly status
763763
# effectiveMode: restart

0 commit comments

Comments
 (0)