Skip to content

Commit e2cd299

Browse files
authored
When the config node can not find the configuration file, the set configuration command does not update other nodes' configuration (#14390)
* ignore undefined config items * modify ConfigManager * modify it * check exception msg
1 parent c4f1ba6 commit e2cd299

File tree

6 files changed

+91
-25
lines changed

6 files changed

+91
-25
lines changed

integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBSetConfigurationTableIT.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,41 @@ public static void tearDown() throws Exception {
5454
EnvFactory.getEnv().cleanClusterEnvironment();
5555
}
5656

57+
@Test
58+
public void testSetConfigurationWithUndefinedConfigKey() {
59+
String expectedExceptionMsg =
60+
"301: ignored config items: [a] because they are immutable or undefined.";
61+
try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
62+
Statement statement = connection.createStatement()) {
63+
executeAndExpectException(statement, "set configuration \"a\"='false'", expectedExceptionMsg);
64+
int configNodeNum = EnvFactory.getEnv().getConfigNodeWrapperList().size();
65+
int dataNodeNum = EnvFactory.getEnv().getDataNodeWrapperList().size();
66+
67+
for (int i = 0; i < configNodeNum; i++) {
68+
executeAndExpectException(
69+
statement, "set configuration a=\'false\' on " + i, expectedExceptionMsg);
70+
}
71+
for (int i = 0; i < dataNodeNum; i++) {
72+
int dnId = configNodeNum + i;
73+
executeAndExpectException(
74+
statement, "set configuration \"a\"='false' on " + dnId, expectedExceptionMsg);
75+
}
76+
} catch (Exception e) {
77+
Assert.fail(e.getMessage());
78+
}
79+
}
80+
81+
private void executeAndExpectException(
82+
Statement statement, String sql, String expectedContentInExceptionMsg) {
83+
try {
84+
statement.execute(sql);
85+
} catch (Exception e) {
86+
Assert.assertTrue(e.getMessage().contains(expectedContentInExceptionMsg));
87+
return;
88+
}
89+
Assert.fail();
90+
}
91+
5792
@Test
5893
public void testSetConfiguration() {
5994
try (Connection connection = EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
@@ -69,7 +104,7 @@ public void testSetConfiguration() {
69104
int dnId = configNodeNum + i;
70105
statement.execute("set configuration \"enable_cross_space_compaction\"='false' on " + dnId);
71106
statement.execute(
72-
"set configuration max_inner_compaction_candidate_file_num='1',max_cross_compaction_candidate_file_num='1' on "
107+
"set configuration inner_compaction_candidate_file_num='1',max_cross_compaction_candidate_file_num='1' on "
73108
+ dnId);
74109
}
75110
} catch (Exception e) {
@@ -91,7 +126,7 @@ public void testSetConfiguration() {
91126
nodeWrapper,
92127
"enable_seq_space_compaction=false",
93128
"enable_cross_space_compaction=false",
94-
"max_inner_compaction_candidate_file_num=1",
129+
"inner_compaction_candidate_file_num=1",
95130
"max_cross_compaction_candidate_file_num=1")));
96131
}
97132

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

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,28 +1666,41 @@ public TSStatus clearCache(final Set<Integer> clearCacheOptions) {
16661666
public TSStatus setConfiguration(TSetConfigurationReq req) {
16671667
TSStatus tsStatus = new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
16681668
int currentNodeId = CONF.getConfigNodeId();
1669-
if (req.getNodeId() < 0 || currentNodeId == req.getNodeId()) {
1670-
URL url = ConfigNodeDescriptor.getPropsUrl(CommonConfig.SYSTEM_CONFIG_NAME);
1671-
if (url == null || !new File(url.getFile()).exists()) {
1669+
if (currentNodeId != req.getNodeId()) {
1670+
tsStatus = confirmLeader();
1671+
if (tsStatus.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
16721672
return tsStatus;
16731673
}
1674-
File file = new File(url.getFile());
1674+
}
1675+
if (currentNodeId == req.getNodeId() || req.getNodeId() < 0) {
1676+
URL url = ConfigNodeDescriptor.getPropsUrl(CommonConfig.SYSTEM_CONFIG_NAME);
1677+
boolean configurationFileFound = (url != null && new File(url.getFile()).exists());
16751678
TrimProperties properties = new TrimProperties();
16761679
properties.putAll(req.getConfigs());
1677-
try {
1678-
ConfigurationFileUtils.updateConfigurationFile(file, properties);
1679-
} catch (Exception e) {
1680-
return RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR, e.getMessage());
1680+
1681+
if (configurationFileFound) {
1682+
File file = new File(url.getFile());
1683+
try {
1684+
ConfigurationFileUtils.updateConfigurationFile(file, properties);
1685+
} catch (Exception e) {
1686+
tsStatus = RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR, e.getMessage());
1687+
}
1688+
} else {
1689+
String msg =
1690+
"Unable to find the configuration file. Some modifications are made only in memory.";
1691+
tsStatus = RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR, msg);
1692+
LOGGER.warn(msg);
16811693
}
16821694
ConfigNodeDescriptor.getInstance().loadHotModifiedProps(properties);
1683-
if (CONF.getConfigNodeId() == req.getNodeId()) {
1695+
if (currentNodeId == req.getNodeId()) {
16841696
return tsStatus;
16851697
}
16861698
}
1687-
tsStatus = confirmLeader();
1688-
return tsStatus.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()
1689-
? RpcUtils.squashResponseStatusList(nodeManager.setConfiguration(req))
1690-
: tsStatus;
1699+
List<TSStatus> statusListOfOtherNodes = nodeManager.setConfiguration(req);
1700+
List<TSStatus> statusList = new ArrayList<>(statusListOfOtherNodes.size() + 1);
1701+
statusList.add(tsStatus);
1702+
statusList.addAll(statusListOfOtherNodes);
1703+
return RpcUtils.squashResponseStatusList(statusList);
16911704
}
16921705

16931706
@Override

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2944,7 +2944,7 @@ public synchronized void loadHotModifiedProps() throws QueryProcessException {
29442944
try (InputStream inputStream = url.openStream()) {
29452945
LOGGER.info("Start to reload config file {}", url);
29462946
commonProperties.load(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
2947-
ConfigurationFileUtils.getConfigurationDefaultValue();
2947+
ConfigurationFileUtils.loadConfigurationDefaultValueFromTemplate();
29482948
loadHotModifiedProps(commonProperties);
29492949
} catch (Exception e) {
29502950
LOGGER.warn("Fail to reload config file {}", url, e);

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,11 +1142,14 @@ public SettableFuture<ConfigTaskResult> setConfiguration(TSetConfigurationReq re
11421142

11431143
TSStatus tsStatus = new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
11441144
List<String> ignoredConfigItems =
1145-
ConfigurationFileUtils.filterImmutableConfigItems(req.getConfigs());
1145+
ConfigurationFileUtils.filterInvalidConfigItems(req.getConfigs());
11461146
TSStatus warningTsStatus = null;
11471147
if (!ignoredConfigItems.isEmpty()) {
11481148
warningTsStatus = new TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode());
1149-
warningTsStatus.setMessage("ignored config items: " + ignoredConfigItems);
1149+
warningTsStatus.setMessage(
1150+
"ignored config items: "
1151+
+ ignoredConfigItems
1152+
+ " because they are immutable or undefined.");
11501153
if (req.getConfigs().isEmpty()) {
11511154
future.setException(new IoTDBException(warningTsStatus.message, warningTsStatus.code));
11521155
return future;

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/StorageEngine.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,10 @@ public TSStatus setConfiguration(TSetConfigurationReq req) {
662662
URL configFileUrl = IoTDBDescriptor.getPropsUrl(CommonConfig.SYSTEM_CONFIG_NAME);
663663
if (configFileUrl == null || !(new File(configFileUrl.getFile()).exists())) {
664664
// configuration file not exist, update in mem
665+
String msg =
666+
"Unable to find the configuration file. Some modifications are made only in memory.";
667+
tsStatus = RpcUtils.getStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR, msg);
668+
LOGGER.warn(msg);
665669
try {
666670
IoTDBDescriptor.getInstance().loadHotModifiedProps(properties);
667671
IoTDBDescriptor.getInstance().reloadMetricProperties(properties);

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/ConfigurationFileUtils.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ public static String readConfigFileContent(URL url) throws IOException {
158158
return readConfigLines(f);
159159
}
160160

161-
public static void getConfigurationDefaultValue() throws IOException {
161+
public static void loadConfigurationDefaultValueFromTemplate() throws IOException {
162162
if (configuration2DefaultValue != null) {
163163
return;
164164
}
@@ -185,6 +185,7 @@ public static void getConfigurationDefaultValue() throws IOException {
185185
}
186186
}
187187
} catch (IOException e) {
188+
configuration2DefaultValue = null;
188189
logger.warn("Failed to read configuration template", e);
189190
throw e;
190191
}
@@ -197,7 +198,7 @@ public static String getConfigurationDefaultValue(String parameterName) throws I
197198
if (configuration2DefaultValue != null) {
198199
return configuration2DefaultValue.get(parameterName);
199200
} else {
200-
getConfigurationDefaultValue();
201+
loadConfigurationDefaultValueFromTemplate();
201202
return configuration2DefaultValue.getOrDefault(parameterName, null);
202203
}
203204
}
@@ -225,14 +226,24 @@ public static String readConfigurationTemplateFile() throws IOException {
225226
return content.toString();
226227
}
227228

228-
public static List<String> filterImmutableConfigItems(Map<String, String> configItems) {
229+
public static List<String> filterInvalidConfigItems(Map<String, String> configItems) {
230+
boolean successLoadDefaultValueMap = true;
231+
try {
232+
loadConfigurationDefaultValueFromTemplate();
233+
} catch (IOException e) {
234+
successLoadDefaultValueMap = false;
235+
}
236+
229237
List<String> ignoredConfigItems = new ArrayList<>();
230-
for (String ignoredKey : ignoreConfigKeys) {
231-
if (configItems.containsKey(ignoredKey)) {
232-
configItems.remove(ignoredKey);
233-
ignoredConfigItems.add(ignoredKey);
238+
for (String key : configItems.keySet()) {
239+
if (ignoreConfigKeys.contains(key)) {
240+
ignoredConfigItems.add(key);
241+
}
242+
if (successLoadDefaultValueMap && !configuration2DefaultValue.containsKey(key)) {
243+
ignoredConfigItems.add(key);
234244
}
235245
}
246+
ignoredConfigItems.forEach(configItems::remove);
236247
return ignoredConfigItems;
237248
}
238249

0 commit comments

Comments
 (0)