You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ja...@apache.org on 2022/10/24 07:40:55 UTC

[iotdb] branch master updated: [IOTDB-4717] Refactor UDFRegistrationService for new Cluster (#7700)

This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new d913886a80 [IOTDB-4717] Refactor UDFRegistrationService for new Cluster (#7700)
d913886a80 is described below

commit d913886a8099a4acda1c6d6234dfc407effd2f46
Author: Liao Lanyu <14...@qq.com>
AuthorDate: Mon Oct 24 15:40:47 2022 +0800

    [IOTDB-4717] Refactor UDFRegistrationService for new Cluster (#7700)
---
 .../iotdb/confignode/persistence/UDFInfo.java      |  16 +-
 .../iotdb/confignode/service/ConfigNode.java       |   2 -
 docs/UserGuide/Alert/Alerting.md                   |   1 -
 docs/zh/UserGuide/Alert/Alerting.md                |   6 +-
 .../iotdb/trigger/ClusterAlertingExample.java      |   2 +-
 .../iotdb/db/it/udf/IoTDBUDFManagementIT.java      |   8 +-
 .../apache/iotdb/commons/service/ServiceType.java  |   1 -
 ...trationInformation.java => UDFInformation.java} |  29 +-
 .../org/apache/iotdb/commons/udf/UDFTable.java     |  29 +-
 .../commons/udf/service/UDFExecutableManager.java  |   8 +-
 .../commons/udf/service/UDFManagementService.java  | 280 +++++++++++
 .../udf/service/UDFRegistrationService.java        | 513 ---------------------
 .../operator/process/TransformOperator.java        |   6 +-
 .../executor/StandaloneConfigTaskExecutor.java     |   9 +-
 .../config/metadata/ShowFunctionsTask.java         |   7 +-
 .../mpp/transformation/dag/udf/UDTFExecutor.java   |   4 +-
 .../dag/udf/UDTFInformationInferrer.java           |   4 +-
 .../apache/iotdb/db/qp/executor/PlanExecutor.java  |  18 +-
 .../apache/iotdb/db/query/dataset/UDTFDataSet.java |   6 +-
 .../java/org/apache/iotdb/db/service/DataNode.java |   5 -
 .../java/org/apache/iotdb/db/service/IoTDB.java    |   8 -
 .../java/org/apache/iotdb/db/service/NewIoTDB.java |   8 -
 .../impl/DataNodeInternalRPCServiceImpl.java       |  15 +-
 .../iotdb/db/qp/physical/PhysicalPlanTest.java     |  27 +-
 .../apache/iotdb/db/utils/EnvironmentUtils.java    |  10 +-
 ...nException.java => UDFManagementException.java} |   6 +-
 26 files changed, 392 insertions(+), 636 deletions(-)

diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/UDFInfo.java b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/UDFInfo.java
index ff96b23d3f..b5a23690e6 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/UDFInfo.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/UDFInfo.java
@@ -22,9 +22,10 @@ package org.apache.iotdb.confignode.persistence;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.executable.ExecutableResource;
 import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
+import org.apache.iotdb.commons.udf.UDFInformation;
 import org.apache.iotdb.commons.udf.service.UDFClassLoader;
 import org.apache.iotdb.commons.udf.service.UDFExecutableManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.confignode.conf.ConfigNodeConfig;
 import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
 import org.apache.iotdb.confignode.consensus.request.write.function.CreateFunctionPlan;
@@ -46,19 +47,18 @@ public class UDFInfo implements SnapshotProcessor {
       ConfigNodeDescriptor.getInstance().getConf();
 
   private final UDFExecutableManager udfExecutableManager;
-  private final UDFRegistrationService udfRegistrationService;
+  private final UDFManagementService udfRegistrationService;
 
   public UDFInfo() {
     udfExecutableManager =
         UDFExecutableManager.setupAndGetInstance(
             CONFIG_NODE_CONF.getTemporaryLibDir(), CONFIG_NODE_CONF.getUdfLibDir());
-    udfRegistrationService =
-        UDFRegistrationService.setupAndGetInstance(CONFIG_NODE_CONF.getSystemUdfDir());
+    udfRegistrationService = UDFManagementService.getInstance();
   }
 
   public synchronized void validateBeforeRegistration(
       String functionName, String className, List<String> uris) throws Exception {
-    udfRegistrationService.validate(functionName, className);
+    udfRegistrationService.validate(new UDFInformation(functionName, className));
 
     if (uris.isEmpty()) {
       fetchExecutablesAndCheckInstantiation(className);
@@ -94,7 +94,7 @@ public class UDFInfo implements SnapshotProcessor {
     final List<String> uris = req.getUris();
 
     try {
-      udfRegistrationService.register(functionName, className, uris, udfExecutableManager, true);
+      udfRegistrationService.register(new UDFInformation(functionName, className));
       return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
     } catch (Exception e) {
       final String errorMessage =
@@ -124,13 +124,11 @@ public class UDFInfo implements SnapshotProcessor {
 
   @Override
   public synchronized boolean processTakeSnapshot(File snapshotDir) throws IOException {
-    return udfExecutableManager.processTakeSnapshot(snapshotDir)
-        && udfRegistrationService.processTakeSnapshot(snapshotDir);
+    return udfExecutableManager.processTakeSnapshot(snapshotDir);
   }
 
   @Override
   public synchronized void processLoadSnapshot(File snapshotDir) throws IOException {
     udfExecutableManager.processLoadSnapshot(snapshotDir);
-    udfRegistrationService.processLoadSnapshot(snapshotDir);
   }
 }
diff --git a/confignode/src/main/java/org/apache/iotdb/confignode/service/ConfigNode.java b/confignode/src/main/java/org/apache/iotdb/confignode/service/ConfigNode.java
index cbbb791fdf..a4101036a4 100644
--- a/confignode/src/main/java/org/apache/iotdb/confignode/service/ConfigNode.java
+++ b/confignode/src/main/java/org/apache/iotdb/confignode/service/ConfigNode.java
@@ -27,7 +27,6 @@ import org.apache.iotdb.commons.service.JMXService;
 import org.apache.iotdb.commons.service.RegisterManager;
 import org.apache.iotdb.commons.udf.service.UDFClassLoaderManager;
 import org.apache.iotdb.commons.udf.service.UDFExecutableManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
 import org.apache.iotdb.confignode.client.ConfigNodeRequestType;
 import org.apache.iotdb.confignode.client.sync.SyncConfigNodeClientPool;
 import org.apache.iotdb.confignode.conf.ConfigNodeConfig;
@@ -194,7 +193,6 @@ public class ConfigNode implements ConfigNodeMBean {
     registerManager.register(
         UDFExecutableManager.setupAndGetInstance(CONF.getTemporaryLibDir(), CONF.getUdfLibDir()));
     registerManager.register(UDFClassLoaderManager.setupAndGetInstance(CONF.getUdfLibDir()));
-    registerManager.register(UDFRegistrationService.setupAndGetInstance(CONF.getSystemUdfDir()));
 
     registerManager.register(MetricService.getInstance());
     LOGGER.info("Successfully setup internal services.");
diff --git a/docs/UserGuide/Alert/Alerting.md b/docs/UserGuide/Alert/Alerting.md
index cfdcacb41e..139fc6cdd2 100644
--- a/docs/UserGuide/Alert/Alerting.md
+++ b/docs/UserGuide/Alert/Alerting.md
@@ -356,7 +356,6 @@ public class ClusterAlertingExample implements Trigger {
     }
     return true;
   }
-  }
 }
 ```
 
diff --git a/docs/zh/UserGuide/Alert/Alerting.md b/docs/zh/UserGuide/Alert/Alerting.md
index 4bf2ba75ee..90061480a8 100644
--- a/docs/zh/UserGuide/Alert/Alerting.md
+++ b/docs/zh/UserGuide/Alert/Alerting.md
@@ -333,15 +333,17 @@ public class ClusterAlertingExample implements Trigger {
     return true;
   }
 }
+```
+
 ### 创建 trigger
 
 如下的 sql 语句在 `root.ln.wf01.wt01.temperature` 
 时间序列上注册了名为 `root-ln-wf01-wt01-alert`、
-运行逻辑由 `org.apache.iotdb.trigger.AlertingExample` 
+运行逻辑由 `org.apache.iotdb.trigger.ClusterAlertingExample` 
 类定义的触发器。
 
 ``` sql
-  CREATE STATELSS TRIGGER `root-ln-wf01-wt01-alert`
+  CREATE STATELESS TRIGGER `root-ln-wf01-wt01-alert`
   AFTER INSERT
   ON root.ln.wf01.wt01.temperature
   AS "org.apache.iotdb.trigger.ClusterAlertingExample"
diff --git a/example/trigger/src/main/java/org/apache/iotdb/trigger/ClusterAlertingExample.java b/example/trigger/src/main/java/org/apache/iotdb/trigger/ClusterAlertingExample.java
index 057142505f..2837845b23 100644
--- a/example/trigger/src/main/java/org/apache/iotdb/trigger/ClusterAlertingExample.java
+++ b/example/trigger/src/main/java/org/apache/iotdb/trigger/ClusterAlertingExample.java
@@ -41,7 +41,7 @@ public class ClusterAlertingExample implements Trigger {
   private final AlertManagerHandler alertManagerHandler = new AlertManagerHandler();
 
   private final AlertManagerConfiguration alertManagerConfiguration =
-      new AlertManagerConfiguration("http://192.168.130.8:9093/api/v2/alerts");
+      new AlertManagerConfiguration("http://127.0.0.1:9093/api/v2/alerts");
 
   private String alertname;
 
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFManagementIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFManagementIT.java
index cd1c058bf4..c13767022a 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFManagementIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFManagementIT.java
@@ -220,10 +220,10 @@ public class IoTDBUDFManagementIT {
       statement.execute("drop function udf");
 
       try {
+        // drop UDF that does not exist will not throw exception now.
         statement.execute("drop function udf");
-        fail();
       } catch (SQLException throwable) {
-        assertTrue(throwable.getMessage().contains("does not exist"));
+        fail();
       }
     }
   }
@@ -232,10 +232,10 @@ public class IoTDBUDFManagementIT {
   public void testDropFunction2() { // drop
     try (Connection connection = EnvFactory.getEnv().getConnection();
         Statement statement = connection.createStatement()) {
+      // drop UDF that does not exist will not throw exception now.
       statement.execute("drop function udf");
-      fail();
     } catch (SQLException throwable) {
-      assertTrue(throwable.getMessage().contains("does not exist"));
+      fail();
     }
   }
 
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/service/ServiceType.java b/node-commons/src/main/java/org/apache/iotdb/commons/service/ServiceType.java
index 670fddf37f..4e90e93a3b 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/service/ServiceType.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/service/ServiceType.java
@@ -42,7 +42,6 @@ public enum ServiceType {
   PERFORMANCE_STATISTIC_SERVICE("PERFORMANCE_STATISTIC_SERVICE", "PERFORMANCE_STATISTIC_SERVICE"),
   TVLIST_ALLOCATOR_SERVICE("TVList Allocator", ""),
   UDF_CLASSLOADER_MANAGER_SERVICE("UDF Classloader Manager Service", ""),
-  UDF_REGISTRATION_SERVICE("UDF Registration Service", ""),
   UDF_EXECUTABLE_MANAGER_SERVICE("UDF Executable Manager Service", ""),
   TEMPORARY_QUERY_DATA_FILE_SERVICE("Temporary Query Data File Service", ""),
   TRIGGER_REGISTRATION_SERVICE_OLD("Old Standalone Trigger Registration Service", ""),
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFRegistrationInformation.java b/node-commons/src/main/java/org/apache/iotdb/commons/udf/UDFInformation.java
similarity index 79%
rename from node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFRegistrationInformation.java
rename to node-commons/src/main/java/org/apache/iotdb/commons/udf/UDFInformation.java
index 872b0883f1..1e945651ff 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFRegistrationInformation.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/udf/UDFInformation.java
@@ -17,31 +17,30 @@
  * under the License.
  */
 
-package org.apache.iotdb.commons.udf.service;
+package org.apache.iotdb.commons.udf;
 
+import org.apache.iotdb.commons.udf.service.UDFClassLoader;
 import org.apache.iotdb.udf.api.UDTF;
 
 import java.lang.reflect.InvocationTargetException;
-import java.util.List;
 
-public class UDFRegistrationInformation {
+public class UDFInformation {
 
   private final String functionName;
   private final String className;
-  private final List<String> uris;
-  private final boolean isBuiltin;
+  private boolean isBuiltin;
 
   private Class<?> functionClass;
 
-  public UDFRegistrationInformation(
-      String functionName,
-      String className,
-      List<String> uris,
-      boolean isBuiltin,
-      Class<?> functionClass) {
-    this.functionName = functionName;
+  public UDFInformation(String functionName, String className) {
+    this.functionName = functionName.toUpperCase();
+    this.className = className;
+  }
+
+  public UDFInformation(
+      String functionName, String className, boolean isBuiltin, Class<?> functionClass) {
+    this.functionName = functionName.toUpperCase();
     this.className = className;
-    this.uris = uris;
     this.isBuiltin = isBuiltin;
     this.functionClass = functionClass;
   }
@@ -54,10 +53,6 @@ public class UDFRegistrationInformation {
     return className;
   }
 
-  public List<String> getUris() {
-    return uris;
-  }
-
   public boolean isBuiltin() {
     return isBuiltin;
   }
diff --git a/udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFRegistrationException.java b/node-commons/src/main/java/org/apache/iotdb/commons/udf/UDFTable.java
similarity index 50%
copy from udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFRegistrationException.java
copy to node-commons/src/main/java/org/apache/iotdb/commons/udf/UDFTable.java
index c8e5b14460..9d7482266f 100644
--- a/udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFRegistrationException.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/udf/UDFTable.java
@@ -17,16 +17,31 @@
  * under the License.
  */
 
-package org.apache.iotdb.udf.api.exception;
+package org.apache.iotdb.commons.udf;
 
-public class UDFRegistrationException extends UDFException {
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
-  public UDFRegistrationException(String message, Throwable cause) {
-    super(message);
-    this.initCause(cause);
+public class UDFTable {
+  private final Map<String, UDFInformation> udfInformationMap;
+
+  public UDFTable() {
+    udfInformationMap = new ConcurrentHashMap<>();
+  }
+
+  public void addUDFInformation(String functionName, UDFInformation udfInformation) {
+    udfInformationMap.put(functionName.toUpperCase(), udfInformation);
+  }
+
+  public UDFInformation removeUDFInformation(String functionName) {
+    return udfInformationMap.remove(functionName.toUpperCase());
+  }
+
+  public UDFInformation getUDFInformation(String functionName) {
+    return udfInformationMap.get(functionName.toUpperCase());
   }
 
-  public UDFRegistrationException(String message) {
-    super(message);
+  public UDFInformation[] getAllUDFInformation() {
+    return udfInformationMap.values().toArray(new UDFInformation[0]);
   }
 }
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFExecutableManager.java b/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFExecutableManager.java
index 6ea6f840c0..82fd892a19 100644
--- a/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFExecutableManager.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFExecutableManager.java
@@ -91,7 +91,11 @@ public class UDFExecutableManager extends ExecutableManager implements IService,
   public boolean processTakeSnapshot(File snapshotDir) throws IOException {
     return SnapshotUtils.takeSnapshotForDir(
             temporaryLibRoot,
-            snapshotDir.getAbsolutePath() + File.separator + "ext" + File.separator + "temporary")
+            snapshotDir.getAbsolutePath()
+                + File.separator
+                + "ext"
+                + File.separator
+                + "udf_temporary")
         && SnapshotUtils.takeSnapshotForDir(
             libRoot,
             snapshotDir.getAbsolutePath() + File.separator + "ext" + File.separator + "udf");
@@ -100,7 +104,7 @@ public class UDFExecutableManager extends ExecutableManager implements IService,
   @Override
   public void processLoadSnapshot(File snapshotDir) throws IOException {
     SnapshotUtils.loadSnapshotForDir(
-        snapshotDir.getAbsolutePath() + File.separator + "ext" + File.separator + "temporary",
+        snapshotDir.getAbsolutePath() + File.separator + "ext" + File.separator + "udf_temporary",
         temporaryLibRoot);
     SnapshotUtils.loadSnapshotForDir(
         snapshotDir.getAbsolutePath() + File.separator + "ext" + File.separator + "udf", libRoot);
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFManagementService.java b/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFManagementService.java
new file mode 100644
index 0000000000..0086d6d17b
--- /dev/null
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFManagementService.java
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.commons.udf.service;
+
+import org.apache.iotdb.commons.executable.ExecutableResource;
+import org.apache.iotdb.commons.udf.UDFInformation;
+import org.apache.iotdb.commons.udf.UDFTable;
+import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
+import org.apache.iotdb.commons.udf.builtin.BuiltinTimeSeriesGeneratingFunction;
+import org.apache.iotdb.commons.utils.TestOnly;
+import org.apache.iotdb.udf.api.UDF;
+import org.apache.iotdb.udf.api.exception.UDFManagementException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class UDFManagementService {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(UDFManagementService.class);
+
+  private final ReentrantLock lock;
+  private final UDFTable udfTable;
+
+  private UDFManagementService() {
+    lock = new ReentrantLock();
+    udfTable = new UDFTable();
+    registerBuiltinTimeSeriesGeneratingFunctions();
+  }
+
+  public void acquireLock() {
+    lock.lock();
+  }
+
+  public void releaseLock() {
+    lock.unlock();
+  }
+
+  /** invoked by config leader for validation before registration */
+  public void validate(UDFInformation udfInformation) {
+    try {
+      acquireLock();
+      validateFunctionName(udfInformation);
+      checkIfRegistered(udfInformation);
+    } finally {
+      releaseLock();
+    }
+  }
+
+  public void register(UDFInformation udfInformation) throws UDFManagementException {
+    try {
+      acquireLock();
+      validateFunctionName(udfInformation);
+      checkIfRegistered(udfInformation);
+      doRegister(udfInformation);
+    } finally {
+      releaseLock();
+    }
+  }
+
+  private static void validateFunctionName(UDFInformation udfInformation)
+      throws UDFManagementException {
+    String functionName = udfInformation.getFunctionName();
+    String className = udfInformation.getClassName();
+    if (!BuiltinAggregationFunction.getNativeFunctionNames().contains(functionName.toLowerCase())) {
+      return;
+    }
+
+    String errorMessage =
+        String.format(
+            "Failed to register UDF %s(%s), because the given function name conflicts with the built-in function name",
+            functionName, className);
+
+    LOGGER.warn(errorMessage);
+    throw new UDFManagementException(errorMessage);
+  }
+
+  private void checkIfRegistered(UDFInformation udfInformation) throws UDFManagementException {
+    String functionName = udfInformation.getFunctionName();
+    String className = udfInformation.getClassName();
+    UDFInformation information = udfTable.getUDFInformation(functionName);
+    if (information == null) {
+      return;
+    }
+
+    String errorMessage;
+    if (information.isBuiltin()) {
+      errorMessage =
+          String.format(
+              "Failed to register UDF %s(%s), because the given function name is the same as a built-in UDF function name.",
+              functionName, className);
+    } else {
+      if (information.getClassName().equals(className)) {
+        errorMessage =
+            String.format(
+                "Failed to register UDF %s(%s), because a UDF %s(%s) with the same function name and the class name has already been registered.",
+                functionName, className, information.getFunctionName(), information.getClassName());
+      } else {
+        errorMessage =
+            String.format(
+                "Failed to register UDF %s(%s), because a UDF %s(%s) with the same function name but a different class name has already been registered.",
+                functionName, className, information.getFunctionName(), information.getClassName());
+      }
+    }
+
+    LOGGER.warn(errorMessage);
+    throw new UDFManagementException(errorMessage);
+  }
+
+  private void downloadExecutableResources(
+      String functionName,
+      String className,
+      List<String> uris,
+      UDFExecutableManager udfExecutableManager)
+      throws UDFManagementException {
+    if (uris.isEmpty()) {
+      return;
+    }
+
+    try {
+      final ExecutableResource resource = udfExecutableManager.request(uris);
+      try {
+        udfExecutableManager.removeUDFJarFromExtLibDir(functionName);
+        udfExecutableManager.moveTempDirToExtLibDir(resource, functionName);
+      } catch (Exception innerException) {
+        udfExecutableManager.removeUDFJarFromExtLibDir(functionName);
+        udfExecutableManager.removeFromTemporaryLibRoot(resource);
+        throw innerException;
+      }
+    } catch (Exception outerException) {
+      String errorMessage =
+          String.format(
+              "Failed to register UDF %s(%s) because failed to fetch UDF executables(%s)",
+              functionName.toUpperCase(), className, uris);
+      LOGGER.warn(errorMessage, outerException);
+      throw new UDFManagementException(errorMessage, outerException);
+    }
+  }
+
+  private void doRegister(UDFInformation udfInformation) throws UDFManagementException {
+    String functionName = udfInformation.getFunctionName();
+    String className = udfInformation.getClassName();
+    try {
+      UDFClassLoader currentActiveClassLoader =
+          UDFClassLoaderManager.getInstance().updateAndGetActiveClassLoader();
+      updateAllRegisteredClasses(currentActiveClassLoader);
+
+      Class<?> functionClass = Class.forName(className, true, currentActiveClassLoader);
+      functionClass.getDeclaredConstructor().newInstance();
+      udfTable.addUDFInformation(
+          functionName, new UDFInformation(functionName, className, false, functionClass));
+    } catch (IOException
+        | InstantiationException
+        | InvocationTargetException
+        | NoSuchMethodException
+        | IllegalAccessException
+        | ClassNotFoundException e) {
+      String errorMessage =
+          String.format(
+              "Failed to register UDF %s(%s), because its instance can not be constructed successfully. Exception: %s",
+              functionName.toUpperCase(), className, e);
+      LOGGER.warn(errorMessage, e);
+      throw new UDFManagementException(errorMessage);
+    }
+  }
+
+  private void updateAllRegisteredClasses(UDFClassLoader activeClassLoader)
+      throws ClassNotFoundException {
+    for (UDFInformation information : getAllUDFInformation()) {
+      if (!information.isBuiltin()) {
+        information.updateFunctionClass(activeClassLoader);
+      }
+    }
+  }
+
+  public void deregister(String functionName) throws UDFManagementException {
+    try {
+      acquireLock();
+      UDFInformation information = udfTable.getUDFInformation(functionName);
+      if (information != null && information.isBuiltin()) {
+        String errorMessage =
+            String.format(
+                "Built-in function %s can not be deregistered.", functionName.toUpperCase());
+        LOGGER.warn(errorMessage);
+        throw new UDFManagementException(errorMessage);
+      }
+
+      udfTable.removeUDFInformation(functionName);
+    } finally {
+      releaseLock();
+    }
+  }
+
+  public UDF reflect(String functionName) {
+    UDFInformation information = udfTable.getUDFInformation(functionName);
+    if (information == null) {
+      String errorMessage =
+          String.format(
+              "Failed to reflect UDF instance, because UDF %s has not been registered.",
+              functionName.toUpperCase());
+      LOGGER.warn(errorMessage);
+      throw new RuntimeException(errorMessage);
+    }
+
+    if (!information.isBuiltin()) {
+      Thread.currentThread()
+          .setContextClassLoader(UDFClassLoaderManager.getInstance().getActiveClassLoader());
+    }
+
+    try {
+      return (UDF) information.getFunctionClass().getDeclaredConstructor().newInstance();
+    } catch (InstantiationException
+        | InvocationTargetException
+        | NoSuchMethodException
+        | IllegalAccessException e) {
+      String errorMessage =
+          String.format(
+              "Failed to reflect UDF %s(%s) instance, because %s",
+              functionName, information.getClassName(), e);
+      LOGGER.warn(errorMessage, e);
+      throw new RuntimeException(errorMessage);
+    }
+  }
+
+  public UDFInformation[] getAllUDFInformation() {
+    return udfTable.getAllUDFInformation();
+  }
+
+  private void registerBuiltinTimeSeriesGeneratingFunctions() {
+    for (BuiltinTimeSeriesGeneratingFunction builtinTimeSeriesGeneratingFunction :
+        BuiltinTimeSeriesGeneratingFunction.values()) {
+      String functionName = builtinTimeSeriesGeneratingFunction.getFunctionName();
+      udfTable.addUDFInformation(
+          functionName,
+          new UDFInformation(
+              functionName,
+              builtinTimeSeriesGeneratingFunction.getClassName(),
+              true,
+              builtinTimeSeriesGeneratingFunction.getFunctionClass()));
+    }
+  }
+
+  @TestOnly
+  public void deregisterAll() throws UDFManagementException {
+    for (UDFInformation information : getAllUDFInformation()) {
+      if (!information.isBuiltin()) {
+        deregister(information.getFunctionName());
+      }
+    }
+  }
+
+  private static class UDFManagementServiceHolder {
+    private static final UDFManagementService INSTANCE = new UDFManagementService();
+  }
+
+  public static UDFManagementService getInstance() {
+    return UDFManagementServiceHolder.INSTANCE;
+  }
+}
diff --git a/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFRegistrationService.java b/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFRegistrationService.java
deleted file mode 100644
index 14bb0b510e..0000000000
--- a/node-commons/src/main/java/org/apache/iotdb/commons/udf/service/UDFRegistrationService.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.iotdb.commons.udf.service;
-
-import org.apache.iotdb.commons.exception.StartupException;
-import org.apache.iotdb.commons.executable.ExecutableResource;
-import org.apache.iotdb.commons.file.SystemFileFactory;
-import org.apache.iotdb.commons.service.IService;
-import org.apache.iotdb.commons.service.ServiceType;
-import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
-import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
-import org.apache.iotdb.commons.udf.builtin.BuiltinTimeSeriesGeneratingFunction;
-import org.apache.iotdb.commons.utils.TestOnly;
-import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
-import org.apache.iotdb.udf.api.UDF;
-import org.apache.iotdb.udf.api.exception.UDFRegistrationException;
-
-import org.apache.commons.io.FileUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-public class UDFRegistrationService implements IService, SnapshotProcessor {
-
-  private static final Logger LOGGER = LoggerFactory.getLogger(UDFRegistrationService.class);
-
-  private final String ulogFileDir;
-  private final String logFileName;
-  private final String temporaryLogFileName;
-
-  private final ReentrantLock registrationLock;
-  private ConcurrentHashMap<String, UDFRegistrationInformation> registrationInformation;
-
-  private final ReentrantReadWriteLock logWriterLock;
-  private UDFLogWriter logWriter;
-
-  private UDFRegistrationService(String ulogFileDir) {
-    this.ulogFileDir = ulogFileDir;
-    logFileName = ulogFileDir + "ulog.txt";
-    temporaryLogFileName = logFileName + ".tmp";
-
-    registrationLock = new ReentrantLock();
-    registrationInformation = new ConcurrentHashMap<>();
-    logWriterLock = new ReentrantReadWriteLock();
-  }
-
-  public void acquireRegistrationLock() {
-    registrationLock.lock();
-  }
-
-  public void releaseRegistrationLock() {
-    registrationLock.unlock();
-  }
-
-  /** invoked by config leader for validation before registration */
-  public void validate(String functionName, String className) {
-    functionName = functionName.toUpperCase();
-    validateFunctionName(functionName, className);
-    checkIfRegistered(functionName, className);
-  }
-
-  public void register(String functionName, String className, boolean writeToTemporaryLogFile)
-      throws UDFRegistrationException {
-    functionName = functionName.toUpperCase();
-    validateFunctionName(functionName, className);
-    checkIfRegistered(functionName, className);
-    doRegister(functionName, className, Collections.emptyList());
-    tryAppendRegistrationLog(
-        functionName, className, Collections.emptyList(), writeToTemporaryLogFile);
-  }
-
-  public void register(
-      String functionName,
-      String className,
-      List<String> uris,
-      UDFExecutableManager udfExecutableManager,
-      boolean writeToTemporaryLogFile)
-      throws UDFRegistrationException {
-    functionName = functionName.toUpperCase();
-    validateFunctionName(functionName, className);
-    checkIfRegistered(functionName, className);
-    downloadExecutableResources(functionName, className, uris, udfExecutableManager);
-    doRegister(functionName, className, uris);
-    tryAppendRegistrationLog(functionName, className, uris, writeToTemporaryLogFile);
-  }
-
-  private static void validateFunctionName(String functionName, String className)
-      throws UDFRegistrationException {
-    if (!BuiltinAggregationFunction.getNativeFunctionNames().contains(functionName.toLowerCase())) {
-      return;
-    }
-
-    String errorMessage =
-        String.format(
-            "Failed to register UDF %s(%s), because the given function name conflicts with the built-in function name",
-            functionName, className);
-
-    LOGGER.warn(errorMessage);
-    throw new UDFRegistrationException(errorMessage);
-  }
-
-  private void checkIfRegistered(String functionName, String className)
-      throws UDFRegistrationException {
-    UDFRegistrationInformation information = registrationInformation.get(functionName);
-    if (information == null) {
-      return;
-    }
-
-    String errorMessage;
-    if (information.isBuiltin()) {
-      errorMessage =
-          String.format(
-              "Failed to register UDF %s(%s), because the given function name is the same as a built-in UDF function name.",
-              functionName, className);
-    } else {
-      if (information.getClassName().equals(className)) {
-        errorMessage =
-            String.format(
-                "Failed to register UDF %s(%s), because a UDF %s(%s) with the same function name and the class name has already been registered.",
-                functionName, className, information.getFunctionName(), information.getClassName());
-      } else {
-        errorMessage =
-            String.format(
-                "Failed to register UDF %s(%s), because a UDF %s(%s) with the same function name but a different class name has already been registered.",
-                functionName, className, information.getFunctionName(), information.getClassName());
-      }
-    }
-
-    LOGGER.warn(errorMessage);
-    throw new UDFRegistrationException(errorMessage);
-  }
-
-  private void downloadExecutableResources(
-      String functionName,
-      String className,
-      List<String> uris,
-      UDFExecutableManager udfExecutableManager)
-      throws UDFRegistrationException {
-    if (uris.isEmpty()) {
-      return;
-    }
-
-    try {
-      final ExecutableResource resource = udfExecutableManager.request(uris);
-      try {
-        udfExecutableManager.removeUDFJarFromExtLibDir(functionName);
-        udfExecutableManager.moveTempDirToExtLibDir(resource, functionName);
-      } catch (Exception innerException) {
-        udfExecutableManager.removeUDFJarFromExtLibDir(functionName);
-        udfExecutableManager.removeFromTemporaryLibRoot(resource);
-        throw innerException;
-      }
-    } catch (Exception outerException) {
-      String errorMessage =
-          String.format(
-              "Failed to register UDF %s(%s) because failed to fetch UDF executables(%s)",
-              functionName, className, uris);
-      LOGGER.warn(errorMessage, outerException);
-      throw new UDFRegistrationException(errorMessage, outerException);
-    }
-  }
-
-  private void doRegister(String functionName, String className, List<String> uris)
-      throws UDFRegistrationException {
-    acquireRegistrationLock();
-    try {
-      UDFClassLoader currentActiveClassLoader =
-          UDFClassLoaderManager.getInstance().updateAndGetActiveClassLoader();
-      updateAllRegisteredClasses(currentActiveClassLoader);
-
-      Class<?> functionClass = Class.forName(className, true, currentActiveClassLoader);
-      functionClass.getDeclaredConstructor().newInstance();
-      registrationInformation.put(
-          functionName,
-          new UDFRegistrationInformation(functionName, className, uris, false, functionClass));
-    } catch (IOException
-        | InstantiationException
-        | InvocationTargetException
-        | NoSuchMethodException
-        | IllegalAccessException
-        | ClassNotFoundException e) {
-      String errorMessage =
-          String.format(
-              "Failed to register UDF %s(%s), because its instance can not be constructed successfully. Exception: %s",
-              functionName, className, e);
-      LOGGER.warn(errorMessage, e);
-      throw new UDFRegistrationException(errorMessage);
-    } finally {
-      releaseRegistrationLock();
-    }
-  }
-
-  private void tryAppendRegistrationLog(
-      String functionName, String className, List<String> uris, boolean writeToTemporaryLogFile)
-      throws UDFRegistrationException {
-    if (!writeToTemporaryLogFile) {
-      return;
-    }
-
-    try {
-      appendRegistrationLog(functionName, className, uris);
-    } catch (IOException e) {
-      registrationInformation.remove(functionName);
-      String errorMessage =
-          String.format(
-              "Failed to append UDF log when registering UDF %s(%s), because %s",
-              functionName, className, e);
-      LOGGER.error(errorMessage);
-      throw new UDFRegistrationException(errorMessage, e);
-    }
-  }
-
-  private void updateAllRegisteredClasses(UDFClassLoader activeClassLoader)
-      throws ClassNotFoundException {
-    for (UDFRegistrationInformation information : getRegistrationInformation()) {
-      if (!information.isBuiltin()) {
-        information.updateFunctionClass(activeClassLoader);
-      }
-    }
-  }
-
-  public void deregister(String functionName) throws UDFRegistrationException {
-    functionName = functionName.toUpperCase();
-    UDFRegistrationInformation information = registrationInformation.get(functionName);
-    if (information == null) {
-      String errorMessage = String.format("UDF %s does not exist.", functionName);
-      LOGGER.warn(errorMessage);
-      throw new UDFRegistrationException(errorMessage);
-    }
-
-    if (information.isBuiltin()) {
-      String errorMessage =
-          String.format("Built-in function %s can not be deregistered.", functionName);
-      LOGGER.warn(errorMessage);
-      throw new UDFRegistrationException(errorMessage);
-    }
-
-    try {
-      appendDeregistrationLog(functionName);
-      registrationInformation.remove(functionName);
-    } catch (IOException e) {
-      String errorMessage =
-          String.format(
-              "Failed to append UDF log when deregistering UDF %s, because %s", functionName, e);
-      LOGGER.error(errorMessage);
-      throw new UDFRegistrationException(errorMessage, e);
-    }
-  }
-
-  private void appendRegistrationLog(String functionName, String className, List<String> uris)
-      throws IOException {
-    logWriterLock.writeLock().lock();
-    try {
-      logWriter.register(functionName, className, uris);
-    } finally {
-      logWriterLock.writeLock().unlock();
-    }
-  }
-
-  private void appendDeregistrationLog(String functionName) throws IOException {
-    logWriterLock.writeLock().lock();
-    try {
-      logWriter.deregister(functionName);
-    } finally {
-      logWriterLock.writeLock().unlock();
-    }
-  }
-
-  public UDF reflect(String functionName) {
-    functionName = functionName.toUpperCase();
-    UDFRegistrationInformation information = registrationInformation.get(functionName);
-    if (information == null) {
-      String errorMessage =
-          String.format(
-              "Failed to reflect UDF instance, because UDF %s has not been registered.",
-              functionName);
-      LOGGER.warn(errorMessage);
-      throw new RuntimeException(errorMessage);
-    }
-
-    if (!information.isBuiltin()) {
-      Thread.currentThread()
-          .setContextClassLoader(UDFClassLoaderManager.getInstance().getActiveClassLoader());
-    }
-
-    try {
-      return (UDF) information.getFunctionClass().getDeclaredConstructor().newInstance();
-    } catch (InstantiationException
-        | InvocationTargetException
-        | NoSuchMethodException
-        | IllegalAccessException e) {
-      String errorMessage =
-          String.format(
-              "Failed to reflect UDF %s(%s) instance, because %s",
-              functionName, information.getClassName(), e);
-      LOGGER.warn(errorMessage, e);
-      throw new RuntimeException(errorMessage);
-    }
-  }
-
-  public UDFRegistrationInformation[] getRegistrationInformation() {
-    return registrationInformation.values().toArray(new UDFRegistrationInformation[0]);
-  }
-
-  @Override
-  public void start() throws StartupException {
-    try {
-      recovery();
-    } catch (Exception e) {
-      throw new StartupException(e);
-    }
-  }
-
-  private void recovery() throws Exception {
-    registrationInformation = new ConcurrentHashMap<>();
-    registerBuiltinTimeSeriesGeneratingFunctions();
-    makeDirIfNecessary();
-    doRecovery();
-    logWriter = new UDFLogWriter(logFileName);
-  }
-
-  private void registerBuiltinTimeSeriesGeneratingFunctions() {
-    for (BuiltinTimeSeriesGeneratingFunction builtinTimeSeriesGeneratingFunction :
-        BuiltinTimeSeriesGeneratingFunction.values()) {
-      String functionName = builtinTimeSeriesGeneratingFunction.getFunctionName();
-      registrationInformation.put(
-          functionName,
-          new UDFRegistrationInformation(
-              functionName,
-              builtinTimeSeriesGeneratingFunction.getClassName(),
-              Collections.emptyList(),
-              true,
-              builtinTimeSeriesGeneratingFunction.getFunctionClass()));
-    }
-  }
-
-  private void makeDirIfNecessary() throws IOException {
-    File file = SystemFileFactory.INSTANCE.getFile(ulogFileDir);
-    if (file.exists() && file.isDirectory()) {
-      return;
-    }
-    FileUtils.forceMkdir(file);
-  }
-
-  private void doRecovery() throws IOException {
-    File temporaryLogFile = SystemFileFactory.INSTANCE.getFile(temporaryLogFileName);
-    File logFile = SystemFileFactory.INSTANCE.getFile(logFileName);
-
-    if (temporaryLogFile.exists()) {
-      if (logFile.exists()) {
-        recoveryFromLogFile(logFile);
-        FileUtils.deleteQuietly(temporaryLogFile);
-      } else {
-        recoveryFromLogFile(temporaryLogFile);
-        FSFactoryProducer.getFSFactory().moveFile(temporaryLogFile, logFile);
-      }
-    } else if (logFile.exists()) {
-      recoveryFromLogFile(logFile);
-    }
-  }
-
-  private void recoveryFromLogFile(File logFile) throws IOException {
-    HashMap<String, String> recoveredUDFs = new HashMap<>();
-
-    try (BufferedReader reader = new BufferedReader(new FileReader(logFile))) {
-      String line;
-      while ((line = reader.readLine()) != null) {
-        String[] data = line.split(",");
-        byte type = Byte.parseByte(data[0]);
-        if (type == UDFLogWriter.REGISTER_WITHOUT_URIS_TYPE
-            || type == UDFLogWriter.REGISTER_WITH_URIS_TYPE) {
-          recoveredUDFs.put(data[1], data[2]);
-        } else if (type == UDFLogWriter.DEREGISTER_TYPE) {
-          recoveredUDFs.remove(data[1]);
-        } else {
-          throw new UnsupportedEncodingException();
-        }
-      }
-    }
-
-    for (Entry<String, String> udf : recoveredUDFs.entrySet()) {
-      try {
-        register(udf.getKey(), udf.getValue(), false);
-      } catch (UDFRegistrationException ignored) {
-        // ignored
-      }
-    }
-  }
-
-  @Override
-  public void stop() {
-    try {
-      writeTemporaryLogFile();
-
-      logWriter.close();
-      logWriter.deleteLogFile();
-
-      File temporaryLogFile = SystemFileFactory.INSTANCE.getFile(temporaryLogFileName);
-      File logFile = SystemFileFactory.INSTANCE.getFile(logFileName);
-      FSFactoryProducer.getFSFactory().moveFile(temporaryLogFile, logFile);
-    } catch (IOException ignored) {
-      // ignored
-    }
-  }
-
-  private void writeTemporaryLogFile() throws IOException {
-    UDFLogWriter temporaryLogFile = new UDFLogWriter(temporaryLogFileName);
-    for (UDFRegistrationInformation information : registrationInformation.values()) {
-      if (information.isBuiltin()) {
-        continue;
-      }
-      temporaryLogFile.register(
-          information.getFunctionName(), information.getClassName(), information.getUris());
-    }
-    temporaryLogFile.close();
-  }
-
-  @TestOnly
-  public void deregisterAll() throws UDFRegistrationException {
-    for (UDFRegistrationInformation information : getRegistrationInformation()) {
-      if (!information.isBuiltin()) {
-        deregister(information.getFunctionName());
-      }
-    }
-  }
-
-  @TestOnly
-  public void registerBuiltinFunction(String functionName, String className)
-      throws ClassNotFoundException {
-    ClassLoader classLoader = getClass().getClassLoader();
-    Class<?> functionClass = Class.forName(className, true, classLoader);
-    functionName = functionName.toUpperCase();
-    registrationInformation.put(
-        functionName,
-        new UDFRegistrationInformation(
-            functionName, className, Collections.emptyList(), true, functionClass));
-  }
-
-  @TestOnly
-  public void deregisterBuiltinFunction(String functionName) {
-    registrationInformation.remove(functionName.toUpperCase());
-  }
-
-  @Override
-  public ServiceType getID() {
-    return ServiceType.UDF_REGISTRATION_SERVICE;
-  }
-
-  private static UDFRegistrationService INSTANCE = null;
-
-  public static synchronized UDFRegistrationService setupAndGetInstance(String ulogFileDir) {
-    if (INSTANCE == null) {
-      INSTANCE = new UDFRegistrationService(ulogFileDir);
-    }
-    return INSTANCE;
-  }
-
-  public static UDFRegistrationService getInstance() {
-    return INSTANCE;
-  }
-
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-  // SnapshotProcessor
-  /////////////////////////////////////////////////////////////////////////////////////////////////
-
-  @Override
-  public boolean processTakeSnapshot(File snapshotDir) throws IOException {
-    return SnapshotUtils.takeSnapshotForDir(
-        ulogFileDir, snapshotDir.getAbsolutePath() + File.separator + "udf");
-  }
-
-  @Override
-  public void processLoadSnapshot(File snapshotDir) throws IOException {
-    SnapshotUtils.loadSnapshotForDir(
-        snapshotDir.getAbsolutePath() + File.separator + "udf", ulogFileDir);
-
-    try {
-      recovery();
-    } catch (Exception e) {
-      throw new IOException(e);
-    }
-  }
-}
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/TransformOperator.java b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/TransformOperator.java
index c45af386b4..4346ed231e 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/TransformOperator.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/execution/operator/process/TransformOperator.java
@@ -20,7 +20,7 @@
 package org.apache.iotdb.db.mpp.execution.operator.process;
 
 import org.apache.iotdb.commons.udf.service.UDFClassLoaderManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.mpp.common.NodeRef;
@@ -117,7 +117,7 @@ public class TransformOperator implements ProcessOperator {
       Map<String, List<InputLocation>> inputLocations,
       Expression[] outputExpressions,
       Map<NodeRef<Expression>, TSDataType> expressionTypes) {
-    UDFRegistrationService.getInstance().acquireRegistrationLock();
+    UDFManagementService.getInstance().acquireLock();
     try {
       // This statement must be surrounded by the registration lock.
       UDFClassLoaderManager.getInstance().initializeUDFQuery(operatorContext.getOperatorId());
@@ -136,7 +136,7 @@ public class TransformOperator implements ProcessOperator {
               .buildResultColumnPointReaders()
               .getOutputPointReaders();
     } finally {
-      UDFRegistrationService.getInstance().releaseRegistrationLock();
+      UDFManagementService.getInstance().releaseLock();
     }
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/StandaloneConfigTaskExecutor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/StandaloneConfigTaskExecutor.java
index b3d48aadf0..c64c8a1469 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/StandaloneConfigTaskExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/StandaloneConfigTaskExecutor.java
@@ -27,8 +27,8 @@ import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.exception.sync.PipeSinkException;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.sync.pipesink.PipeSink;
-import org.apache.iotdb.commons.udf.service.UDFExecutableManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.UDFInformation;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.confignode.rpc.thrift.TShowPipeResp;
 import org.apache.iotdb.confignode.rpc.thrift.TStorageGroupInfo;
 import org.apache.iotdb.confignode.rpc.thrift.TStorageGroupSchema;
@@ -205,8 +205,7 @@ public class StandaloneConfigTaskExecutor implements IConfigTaskExecutor {
       String udfName, String className, List<String> uris) {
     SettableFuture<ConfigTaskResult> future = SettableFuture.create();
     try {
-      UDFRegistrationService.getInstance()
-          .register(udfName, className, uris, UDFExecutableManager.getInstance(), true);
+      UDFManagementService.getInstance().register(new UDFInformation(udfName, className));
       future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
     } catch (Exception e) {
       final String message =
@@ -224,7 +223,7 @@ public class StandaloneConfigTaskExecutor implements IConfigTaskExecutor {
   public SettableFuture<ConfigTaskResult> dropFunction(String udfName) {
     SettableFuture<ConfigTaskResult> future = SettableFuture.create();
     try {
-      UDFRegistrationService.getInstance().deregister(udfName);
+      UDFManagementService.getInstance().deregister(udfName);
       future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
     } catch (Exception e) {
       final String message =
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/metadata/ShowFunctionsTask.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/metadata/ShowFunctionsTask.java
index 5f41aabbbf..3c15cbf736 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/metadata/ShowFunctionsTask.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/metadata/ShowFunctionsTask.java
@@ -20,9 +20,9 @@
 package org.apache.iotdb.db.mpp.plan.execution.config.metadata;
 
 import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.udf.UDFInformation;
 import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationInformation;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.db.mpp.common.header.ColumnHeader;
 import org.apache.iotdb.db.mpp.common.header.ColumnHeaderConstant;
 import org.apache.iotdb.db.mpp.common.header.DatasetHeaderFactory;
@@ -116,8 +116,7 @@ public class ShowFunctionsTask implements IConfigTask {
   }
 
   private void appendUDFs(ListDataSet listDataSet) {
-    for (UDFRegistrationInformation info :
-        UDFRegistrationService.getInstance().getRegistrationInformation()) {
+    for (UDFInformation info : UDFManagementService.getInstance().getAllUDFInformation()) {
       RowRecord rowRecord = new RowRecord(0); // ignore timestamp
       rowRecord.addField(Binary.valueOf(info.getFunctionName()), TSDataType.TEXT);
       String functionType = "";
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/udf/UDTFExecutor.java b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/udf/UDTFExecutor.java
index 8aecaebcf1..ea8a64bcd5 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/udf/UDTFExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/udf/UDTFExecutor.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.mpp.transformation.dag.udf;
 
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.commons.udf.utils.UDFDataTypeTransformer;
 import org.apache.iotdb.db.mpp.transformation.datastructure.tv.ElasticSerializableTVList;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -80,7 +80,7 @@ public class UDTFExecutor {
       List<TSDataType> childExpressionDataTypes,
       Map<String, String> attributes) {
 
-    udtf = (UDTF) UDFRegistrationService.getInstance().reflect(functionName);
+    udtf = (UDTF) UDFManagementService.getInstance().reflect(functionName);
 
     final UDFParameters parameters =
         new UDFParameters(
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/udf/UDTFInformationInferrer.java b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/udf/UDTFInformationInferrer.java
index bf702ac938..321d83d44a 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/udf/UDTFInformationInferrer.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/transformation/dag/udf/UDTFInformationInferrer.java
@@ -19,7 +19,7 @@
 
 package org.apache.iotdb.db.mpp.transformation.dag.udf;
 
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.commons.udf.utils.UDFDataTypeTransformer;
 import org.apache.iotdb.db.exception.sql.SemanticException;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -84,7 +84,7 @@ public class UDTFInformationInferrer {
       List<TSDataType> childExpressionDataTypes,
       Map<String, String> attributes)
       throws Exception {
-    UDTF udtf = (UDTF) UDFRegistrationService.getInstance().reflect(functionName);
+    UDTF udtf = (UDTF) UDFManagementService.getInstance().reflect(functionName);
 
     UDFParameters parameters =
         new UDFParameters(
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index 1c12638403..104c91c639 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -36,9 +36,9 @@ import org.apache.iotdb.commons.exception.sync.PipeSinkException;
 import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.sync.pipesink.PipeSink;
+import org.apache.iotdb.commons.udf.UDFInformation;
 import org.apache.iotdb.commons.udf.builtin.BuiltinAggregationFunction;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationInformation;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.commons.utils.AuthUtils;
 import org.apache.iotdb.db.auth.AuthorityChecker;
 import org.apache.iotdb.db.auth.AuthorizerManager;
@@ -183,7 +183,7 @@ import org.apache.iotdb.tsfile.utils.Binary;
 import org.apache.iotdb.tsfile.utils.Pair;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
 import org.apache.iotdb.tsfile.write.writer.RestorableTsFileIOWriter;
-import org.apache.iotdb.udf.api.exception.UDFRegistrationException;
+import org.apache.iotdb.udf.api.exception.UDFManagementException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -507,13 +507,14 @@ public class PlanExecutor implements IPlanExecutor {
     return true;
   }
 
-  private boolean operateCreateFunction(CreateFunctionPlan plan) throws UDFRegistrationException {
-    UDFRegistrationService.getInstance().register(plan.getUdfName(), plan.getClassName(), true);
+  private boolean operateCreateFunction(CreateFunctionPlan plan) throws UDFManagementException {
+    UDFManagementService.getInstance()
+        .register(new UDFInformation(plan.getUdfName(), plan.getClassName()));
     return true;
   }
 
-  private boolean operateDropFunction(DropFunctionPlan plan) throws UDFRegistrationException {
-    UDFRegistrationService.getInstance().deregister(plan.getUdfName());
+  private boolean operateDropFunction(DropFunctionPlan plan) throws UDFManagementException {
+    UDFManagementService.getInstance().deregister(plan.getUdfName());
     return true;
   }
 
@@ -1081,8 +1082,7 @@ public class PlanExecutor implements IPlanExecutor {
   }
 
   private void appendUDFs(ListDataSet listDataSet) throws QueryProcessException {
-    for (UDFRegistrationInformation info :
-        UDFRegistrationService.getInstance().getRegistrationInformation()) {
+    for (UDFInformation info : UDFManagementService.getInstance().getAllUDFInformation()) {
       RowRecord rowRecord = new RowRecord(0); // ignore timestamp
       rowRecord.addField(Binary.valueOf(info.getFunctionName()), TSDataType.TEXT);
       String functionType = "";
diff --git a/server/src/main/java/org/apache/iotdb/db/query/dataset/UDTFDataSet.java b/server/src/main/java/org/apache/iotdb/db/query/dataset/UDTFDataSet.java
index 89466f0cce..7322dfce34 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/dataset/UDTFDataSet.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/dataset/UDTFDataSet.java
@@ -21,7 +21,7 @@ package org.apache.iotdb.db.query.dataset;
 
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.commons.udf.service.UDFClassLoaderManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.mpp.transformation.api.LayerPointReader;
@@ -114,7 +114,7 @@ public abstract class UDTFDataSet extends QueryDataSet {
   }
 
   protected void initTransformers() throws QueryProcessException, IOException {
-    UDFRegistrationService.getInstance().acquireRegistrationLock();
+    UDFManagementService.getInstance().acquireLock();
     // This statement must be surrounded by the registration lock.
     UDFClassLoaderManager.getInstance().initializeUDFQuery(queryId);
     try {
@@ -131,7 +131,7 @@ public abstract class UDTFDataSet extends QueryDataSet {
               .setDataSetResultColumnDataTypes()
               .getResultColumnPointReaders();
     } finally {
-      UDFRegistrationService.getInstance().releaseRegistrationLock();
+      UDFManagementService.getInstance().releaseLock();
     }
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/service/DataNode.java b/server/src/main/java/org/apache/iotdb/db/service/DataNode.java
index fe1944cfb1..3d230afbf1 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/DataNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/DataNode.java
@@ -37,7 +37,6 @@ import org.apache.iotdb.commons.trigger.exception.TriggerManagementException;
 import org.apache.iotdb.commons.trigger.service.TriggerExecutableManager;
 import org.apache.iotdb.commons.udf.service.UDFClassLoaderManager;
 import org.apache.iotdb.commons.udf.service.UDFExecutableManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
 import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRegisterReq;
 import org.apache.iotdb.confignode.rpc.thrift.TDataNodeRegisterResp;
 import org.apache.iotdb.confignode.rpc.thrift.TGetTriggerJarReq;
@@ -80,7 +79,6 @@ import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
@@ -409,9 +407,6 @@ public class DataNode implements DataNodeMBean {
         UDFExecutableManager.setupAndGetInstance(
             config.getUdfTemporaryLibDir(), config.getUdfDir()));
     registerManager.register(UDFClassLoaderManager.setupAndGetInstance(config.getUdfDir()));
-    registerManager.register(
-        UDFRegistrationService.setupAndGetInstance(
-            config.getSystemDir() + File.separator + "udf" + File.separator));
   }
 
   private void initTriggerRelatedInstance() throws StartupException {
diff --git a/server/src/main/java/org/apache/iotdb/db/service/IoTDB.java b/server/src/main/java/org/apache/iotdb/db/service/IoTDB.java
index 4bfc5be5ef..990eace370 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/IoTDB.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/IoTDB.java
@@ -26,7 +26,6 @@ import org.apache.iotdb.commons.service.JMXService;
 import org.apache.iotdb.commons.service.RegisterManager;
 import org.apache.iotdb.commons.service.StartupChecks;
 import org.apache.iotdb.commons.udf.service.UDFClassLoaderManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.conf.IoTDBStartCheck;
@@ -54,7 +53,6 @@ import org.apache.iotdb.db.wal.WALManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
 import java.io.IOException;
 
 public class IoTDB implements IoTDBMBean {
@@ -148,12 +146,6 @@ public class IoTDB implements IoTDBMBean {
     registerManager.register(
         UDFClassLoaderManager.setupAndGetInstance(
             IoTDBDescriptor.getInstance().getConfig().getUdfDir()));
-    registerManager.register(
-        UDFRegistrationService.setupAndGetInstance(
-            IoTDBDescriptor.getInstance().getConfig().getSystemDir()
-                + File.separator
-                + "udf"
-                + File.separator));
     registerManager.register(CompactionTaskManager.getInstance());
 
     // in cluster mode, RPC service is not enabled.
diff --git a/server/src/main/java/org/apache/iotdb/db/service/NewIoTDB.java b/server/src/main/java/org/apache/iotdb/db/service/NewIoTDB.java
index f24e0b3466..03ab7e10dd 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/NewIoTDB.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/NewIoTDB.java
@@ -27,7 +27,6 @@ import org.apache.iotdb.commons.service.JMXService;
 import org.apache.iotdb.commons.service.RegisterManager;
 import org.apache.iotdb.commons.service.StartupChecks;
 import org.apache.iotdb.commons.udf.service.UDFClassLoaderManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.conf.IoTDBStartCheck;
@@ -54,7 +53,6 @@ import org.apache.iotdb.db.wal.WALManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
 import java.io.IOException;
 
 public class NewIoTDB implements NewIoTDBMBean {
@@ -139,12 +137,6 @@ public class NewIoTDB implements NewIoTDBMBean {
     registerManager.register(
         UDFClassLoaderManager.setupAndGetInstance(
             IoTDBDescriptor.getInstance().getConfig().getUdfDir()));
-    registerManager.register(
-        UDFRegistrationService.setupAndGetInstance(
-            IoTDBDescriptor.getInstance().getConfig().getSystemDir()
-                + File.separator
-                + "udf"
-                + File.separator));
 
     // in cluster mode, RPC service is not enabled.
     if (IoTDBDescriptor.getInstance().getConfig().isEnableRpcService()) {
diff --git a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
index c8dc6a8da4..29d482dfb9 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/DataNodeInternalRPCServiceImpl.java
@@ -41,8 +41,8 @@ import org.apache.iotdb.commons.sync.pipe.PipeInfo;
 import org.apache.iotdb.commons.sync.pipe.SyncOperation;
 import org.apache.iotdb.commons.trigger.TriggerInformation;
 import org.apache.iotdb.commons.trigger.service.TriggerExecutableManager;
-import org.apache.iotdb.commons.udf.service.UDFExecutableManager;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.UDFInformation;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.consensus.common.Peer;
 import org.apache.iotdb.consensus.common.response.ConsensusGenericResponse;
 import org.apache.iotdb.consensus.exception.PeerNotInConsensusGroupException;
@@ -1093,13 +1093,8 @@ public class DataNodeInternalRPCServiceImpl implements IDataNodeRPCService.Iface
   @Override
   public TSStatus createFunction(TCreateFunctionRequest request) {
     try {
-      UDFRegistrationService.getInstance()
-          .register(
-              request.getUdfName(),
-              request.getClassName(),
-              request.getUris(),
-              UDFExecutableManager.getInstance(),
-              true);
+      UDFManagementService.getInstance()
+          .register(new UDFInformation(request.getUdfName(), request.getClassName()));
       return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
     } catch (Exception e) {
       return new TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode())
@@ -1110,7 +1105,7 @@ public class DataNodeInternalRPCServiceImpl implements IDataNodeRPCService.Iface
   @Override
   public TSStatus dropFunction(TDropFunctionRequest request) {
     try {
-      UDFRegistrationService.getInstance().deregister(request.getUdfName());
+      UDFManagementService.getInstance().deregister(request.getUdfName());
       return new TSStatus(TSStatusCode.SUCCESS_STATUS.getStatusCode());
     } catch (Exception e) {
       return new TSStatus(TSStatusCode.EXECUTE_STATEMENT_ERROR.getStatusCode())
diff --git a/server/src/test/java/org/apache/iotdb/db/qp/physical/PhysicalPlanTest.java b/server/src/test/java/org/apache/iotdb/db/qp/physical/PhysicalPlanTest.java
index 7f0a1cb2f3..650808cfd0 100644
--- a/server/src/test/java/org/apache/iotdb/db/qp/physical/PhysicalPlanTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/qp/physical/PhysicalPlanTest.java
@@ -21,7 +21,8 @@ package org.apache.iotdb.db.qp.physical;
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.UDFInformation;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.trigger.executor.TriggerEvent;
 import org.apache.iotdb.db.exception.StorageEngineException;
@@ -506,14 +507,16 @@ public class PhysicalPlanTest {
           (CreateFunctionPlan)
               processor.parseSQLToPhysicalPlan(
                   "create function udf as 'org.apache.iotdb.db.query.udf.example.Adder'");
-      UDFRegistrationService.getInstance()
-          .register(createFunctionPlan.getUdfName(), createFunctionPlan.getClassName(), true);
+      UDFManagementService.getInstance()
+          .register(
+              new UDFInformation(
+                  createFunctionPlan.getUdfName(), createFunctionPlan.getClassName()));
 
       String sqlStr =
           "select udf(d2.s1, d1.s1), udf(d1.s1, d2.s1), d1.s1, d2.s1, udf(d1.s1, d2.s1), udf(d2.s1, d1.s1), d1.s1, d2.s1 from root.vehicle";
       PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);
 
-      UDFRegistrationService.getInstance().deregister(createFunctionPlan.getUdfName());
+      UDFManagementService.getInstance().deregister(createFunctionPlan.getUdfName());
 
       if (!(plan instanceof UDTFPlan)) {
         fail();
@@ -548,14 +551,16 @@ public class PhysicalPlanTest {
           (CreateFunctionPlan)
               processor.parseSQLToPhysicalPlan(
                   "create function udf as 'org.apache.iotdb.db.query.udf.example.Adder'");
-      UDFRegistrationService.getInstance()
-          .register(createFunctionPlan.getUdfName(), createFunctionPlan.getClassName(), true);
+      UDFManagementService.getInstance()
+          .register(
+              new UDFInformation(
+                  createFunctionPlan.getUdfName(), createFunctionPlan.getClassName()));
 
       String sqlStr =
           "select udf(d2.s1, d1.s1, 'addend'='100'), udf(d1.s1, d2.s1), d1.s1, d2.s1, udf(d2.s1, d1.s1) from root.vehicle";
       PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);
 
-      UDFRegistrationService.getInstance().deregister(createFunctionPlan.getUdfName());
+      UDFManagementService.getInstance().deregister(createFunctionPlan.getUdfName());
       if (!(plan instanceof UDTFPlan)) {
         fail();
       }
@@ -593,13 +598,15 @@ public class PhysicalPlanTest {
           (CreateFunctionPlan)
               processor.parseSQLToPhysicalPlan(
                   "create function udf as 'org.apache.iotdb.db.query.udf.example.Adder'");
-      UDFRegistrationService.getInstance()
-          .register(createFunctionPlan.getUdfName(), createFunctionPlan.getClassName(), true);
+      UDFManagementService.getInstance()
+          .register(
+              new UDFInformation(
+                  createFunctionPlan.getUdfName(), createFunctionPlan.getClassName()));
 
       String sqlStr = "select *, udf(*, *), *, udf(*, *), * from root.vehicle.**";
       PhysicalPlan plan = processor.parseSQLToPhysicalPlan(sqlStr);
 
-      UDFRegistrationService.getInstance().deregister(createFunctionPlan.getUdfName());
+      UDFManagementService.getInstance().deregister(createFunctionPlan.getUdfName());
       if (!(plan instanceof UDTFPlan)) {
         fail();
       }
diff --git a/server/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java b/server/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
index 9298697653..0452ef8188 100644
--- a/server/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
+++ b/server/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
@@ -22,7 +22,7 @@ import org.apache.iotdb.commons.auth.AuthException;
 import org.apache.iotdb.commons.cluster.NodeStatus;
 import org.apache.iotdb.commons.conf.CommonConfig;
 import org.apache.iotdb.commons.conf.CommonDescriptor;
-import org.apache.iotdb.commons.udf.service.UDFRegistrationService;
+import org.apache.iotdb.commons.udf.service.UDFManagementService;
 import org.apache.iotdb.db.auth.AuthorizerManager;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
@@ -57,7 +57,7 @@ import org.apache.iotdb.metrics.config.MetricConfigDescriptor;
 import org.apache.iotdb.rpc.TConfigurationConst;
 import org.apache.iotdb.rpc.TSocketWrapper;
 import org.apache.iotdb.tsfile.utils.FilePathUtils;
-import org.apache.iotdb.udf.api.exception.UDFRegistrationException;
+import org.apache.iotdb.udf.api.exception.UDFManagementException;
 
 import org.apache.commons.io.FileUtils;
 import org.apache.thrift.TConfiguration;
@@ -108,8 +108,8 @@ public class EnvironmentUtils {
 
     // deregister all user defined classes
     try {
-      if (UDFRegistrationService.getInstance() != null) {
-        UDFRegistrationService.getInstance().deregisterAll();
+      if (UDFManagementService.getInstance() != null) {
+        UDFManagementService.getInstance().deregisterAll();
       }
       if (TriggerRegistrationService.getInstance() != null) {
         TriggerRegistrationService.getInstance().deregisterAll();
@@ -117,7 +117,7 @@ public class EnvironmentUtils {
       if (ContinuousQueryService.getInstance() != null) {
         ContinuousQueryService.getInstance().deregisterAll();
       }
-    } catch (UDFRegistrationException | TriggerManagementException | ContinuousQueryException e) {
+    } catch (UDFManagementException | TriggerManagementException | ContinuousQueryException e) {
       fail(e.getMessage());
     }
 
diff --git a/udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFRegistrationException.java b/udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFManagementException.java
similarity index 83%
rename from udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFRegistrationException.java
rename to udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFManagementException.java
index c8e5b14460..14bd7fdfb4 100644
--- a/udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFRegistrationException.java
+++ b/udf-api/src/main/java/org/apache/iotdb/udf/api/exception/UDFManagementException.java
@@ -19,14 +19,14 @@
 
 package org.apache.iotdb.udf.api.exception;
 
-public class UDFRegistrationException extends UDFException {
+public class UDFManagementException extends UDFException {
 
-  public UDFRegistrationException(String message, Throwable cause) {
+  public UDFManagementException(String message, Throwable cause) {
     super(message);
     this.initCause(cause);
   }
 
-  public UDFRegistrationException(String message) {
+  public UDFManagementException(String message) {
     super(message);
   }
 }