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

qiaojialin 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 984dfd9058 [IOTDB-3117][snapshot] add authInfo snapshot. (#5843)
984dfd9058 is described below

commit 984dfd90585cf31bf024d4042885e0753263caf3
Author: ZhangHongYin <[email protected]>
AuthorDate: Sat May 14 00:06:31 2022 +0800

    [IOTDB-3117][snapshot] add authInfo snapshot. (#5843)
---
 .../iotdb/confignode/persistence/AuthorInfo.java   |  35 +++-
 .../confignode/persistence/ClusterSchemaInfo.java  |   1 +
 .../confignode/persistence/PartitionInfo.java      |   1 +
 .../executor/ConfigRequestExecutor.java            |   2 +-
 .../confignode/persistence/AuthorInfoTest.java     |  47 +++++
 ...IoTDBLoadExternalTsFileWithTimePartitionIT.java |   2 +-
 .../commons/auth/authorizer/BasicAuthorizer.java   |  16 ++
 .../iotdb/commons/auth/authorizer/IAuthorizer.java |   4 +-
 .../iotdb/commons/auth/role/BasicRoleManager.java  |   6 +-
 .../iotdb/commons/auth/role/IRoleAccessor.java     |   3 +-
 .../iotdb/commons/auth/role/IRoleManager.java      |   3 +-
 .../commons/auth/role/LocalFileRoleAccessor.java   |  45 +++++
 .../commons/auth/role/LocalFileRoleManager.java    |  15 ++
 .../iotdb/commons/auth/user/BasicUserManager.java  |   6 +-
 .../iotdb/commons/auth/user/IUserAccessor.java     |   3 +-
 .../iotdb/commons/auth/user/IUserManager.java      |   3 +-
 .../commons/auth/user/LocalFileUserAccessor.java   |  48 ++++-
 .../commons/auth/user/LocalFileUserManager.java    |  15 ++
 .../iotdb/commons/snapshot}/SnapshotProcessor.java |   2 +-
 .../org/apache/iotdb/commons}/utils/FileUtils.java |  56 +++++-
 .../apache/iotdb/db/auth/AuthorizerManager.java    | 201 ++++++++++++++++++---
 .../iotdb/db/engine/storagegroup/DataRegion.java   |   4 +-
 .../iotdb/db/service/metrics/MetricsService.java   |   2 +-
 .../sync/pipedata/queue/BufferedPipeDataQueue.java |   2 +-
 .../db/sync/sender/recovery/TsFilePipeLogger.java  |   2 +-
 .../iotdb/db/wal/recover/WALNodeRecoverTask.java   |   2 +-
 .../db/engine/compaction/TsFileIdentifierUT.java   |   2 +-
 27 files changed, 477 insertions(+), 51 deletions(-)

diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
index a27c81fd43..72704fd7da 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/AuthorInfo.java
@@ -26,26 +26,35 @@ import org.apache.iotdb.commons.auth.entity.PathPrivilege;
 import org.apache.iotdb.commons.auth.entity.PrivilegeType;
 import org.apache.iotdb.commons.auth.entity.Role;
 import org.apache.iotdb.commons.auth.entity.User;
+import org.apache.iotdb.commons.conf.CommonConfig;
+import org.apache.iotdb.commons.conf.CommonDescriptor;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
 import org.apache.iotdb.commons.utils.AuthUtils;
+import org.apache.iotdb.commons.utils.FileUtils;
+import org.apache.iotdb.commons.utils.TestOnly;
 import org.apache.iotdb.confignode.consensus.request.ConfigRequestType;
 import org.apache.iotdb.confignode.consensus.request.auth.AuthorReq;
 import org.apache.iotdb.confignode.consensus.response.PermissionInfoResp;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 
+import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-public class AuthorInfo {
+public class AuthorInfo implements SnapshotProcessor {
 
   private static final Logger logger = 
LoggerFactory.getLogger(AuthorInfo.class);
+  private static final CommonConfig commonConfig = 
CommonDescriptor.getInstance().getConfig();
 
   private IAuthorizer authorizer;
 
@@ -332,7 +341,6 @@ public class AuthorInfo {
   }
 
   private static class AuthorInfoHolder {
-
     private static final AuthorInfo INSTANCE = new AuthorInfo();
 
     private AuthorInfoHolder() {
@@ -343,4 +351,27 @@ public class AuthorInfo {
   public static AuthorInfo getInstance() {
     return AuthorInfo.AuthorInfoHolder.INSTANCE;
   }
+
+  @Override
+  public boolean processTakeSnapshot(File snapshotDir) throws TException, 
IOException {
+    return authorizer.processTakeSnapshot(snapshotDir);
+  }
+
+  @Override
+  public void processLoadSnapshot(File snapshotDir) throws TException, 
IOException {
+    authorizer.processLoadSnapshot(snapshotDir);
+  }
+
+  @TestOnly
+  public void clear() throws AuthException {
+    File userFolder = new File(commonConfig.getUserFolder());
+    if (userFolder.exists()) {
+      FileUtils.deleteDirectory(userFolder);
+    }
+    File roleFolder = new File(commonConfig.getRoleFolder());
+    if (roleFolder.exists()) {
+      FileUtils.deleteDirectory(roleFolder);
+    }
+    authorizer.reset();
+  }
 }
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/ClusterSchemaInfo.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/ClusterSchemaInfo.java
index 42e8976494..04a5ef47a9 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/ClusterSchemaInfo.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/ClusterSchemaInfo.java
@@ -25,6 +25,7 @@ import org.apache.iotdb.common.rpc.thrift.TSStatus;
 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.snapshot.SnapshotProcessor;
 import org.apache.iotdb.commons.utils.TestOnly;
 import org.apache.iotdb.confignode.consensus.request.read.CountStorageGroupReq;
 import org.apache.iotdb.confignode.consensus.request.read.GetStorageGroupReq;
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/PartitionInfo.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/PartitionInfo.java
index 8a10c7e84f..1e36ebb832 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/PartitionInfo.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/PartitionInfo.java
@@ -26,6 +26,7 @@ import 
org.apache.iotdb.common.rpc.thrift.TSeriesPartitionSlot;
 import org.apache.iotdb.common.rpc.thrift.TTimePartitionSlot;
 import org.apache.iotdb.commons.partition.DataPartition;
 import org.apache.iotdb.commons.partition.SchemaPartition;
+import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
 import org.apache.iotdb.commons.utils.TestOnly;
 import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
 import org.apache.iotdb.confignode.consensus.request.read.GetDataPartitionReq;
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigRequestExecutor.java
 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigRequestExecutor.java
index fadcd07d65..2deed21569 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigRequestExecutor.java
+++ 
b/confignode/src/main/java/org/apache/iotdb/confignode/persistence/executor/ConfigRequestExecutor.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.confignode.persistence.executor;
 
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.auth.AuthException;
+import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
 import org.apache.iotdb.confignode.consensus.request.ConfigRequest;
 import org.apache.iotdb.confignode.consensus.request.auth.AuthorReq;
 import org.apache.iotdb.confignode.consensus.request.read.CountStorageGroupReq;
@@ -47,7 +48,6 @@ import 
org.apache.iotdb.confignode.persistence.ClusterSchemaInfo;
 import org.apache.iotdb.confignode.persistence.NodeInfo;
 import org.apache.iotdb.confignode.persistence.PartitionInfo;
 import org.apache.iotdb.confignode.persistence.ProcedureInfo;
-import org.apache.iotdb.confignode.persistence.SnapshotProcessor;
 import org.apache.iotdb.consensus.common.DataSet;
 import org.apache.iotdb.rpc.TSStatusCode;
 
diff --git 
a/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
 
b/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
index eae73ac4d7..d1f80ff43a 100644
--- 
a/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
+++ 
b/confignode/src/test/java/org/apache/iotdb/confignode/persistence/AuthorInfoTest.java
@@ -22,31 +22,55 @@ package org.apache.iotdb.confignode.persistence;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.auth.AuthException;
 import org.apache.iotdb.commons.auth.entity.PrivilegeType;
+import org.apache.iotdb.commons.conf.CommonConfig;
+import org.apache.iotdb.commons.conf.CommonDescriptor;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.confignode.conf.ConfigNodeConf;
+import org.apache.iotdb.confignode.conf.ConfigNodeDescriptor;
 import org.apache.iotdb.confignode.consensus.request.ConfigRequestType;
 import org.apache.iotdb.confignode.consensus.request.auth.AuthorReq;
 import org.apache.iotdb.confignode.consensus.response.PermissionInfoResp;
 import org.apache.iotdb.confignode.rpc.thrift.TCheckUserPrivilegesReq;
 import org.apache.iotdb.rpc.TSStatusCode;
 
+import org.apache.commons.io.FileUtils;
 import org.apache.thrift.TException;
+import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static org.apache.iotdb.db.constant.TestConstant.BASE_OUTPUT_PATH;
+
 public class AuthorInfoTest {
 
   private static AuthorInfo authorInfo;
+  private static final File snapshotDir = new File(BASE_OUTPUT_PATH, 
"authorInfo-snapshot");
+  private static final ConfigNodeConf config = 
ConfigNodeDescriptor.getInstance().getConf();
+  private static final CommonConfig commonConfig = 
CommonDescriptor.getInstance().getConfig();
 
   @BeforeClass
   public static void setup() {
     authorInfo = AuthorInfo.getInstance();
+    if (!snapshotDir.exists()) {
+      snapshotDir.mkdirs();
+    }
+  }
+
+  @AfterClass
+  public static void cleanup() throws IOException, AuthException {
+    authorInfo.clear();
+    if (snapshotDir.exists()) {
+      FileUtils.deleteDirectory(snapshotDir);
+    }
   }
 
   @Test
@@ -289,4 +313,27 @@ public class AuthorInfoTest {
       Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
     }
   }
+
+  @Test
+  public void takeSnapshot() throws TException, IOException, AuthException {
+    cleanUserAndRole();
+    // create role
+    AuthorReq createRoleReq = new AuthorReq(ConfigRequestType.CreateRole);
+    createRoleReq.setRoleName("testRole");
+    TSStatus status = authorInfo.authorNonQuery(createRoleReq);
+    Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
+    AuthorReq createUserReq = new AuthorReq(ConfigRequestType.CreateUser);
+    createUserReq.setUserName("testUser");
+    createUserReq.setPassword("testPassword");
+    status = authorInfo.authorNonQuery(createUserReq);
+    Assert.assertEquals(TSStatusCode.SUCCESS_STATUS.getStatusCode(), 
status.getCode());
+
+    Assert.assertEquals(1, 
authorInfo.executeListRole().getPermissionInfo().get("role").size());
+    Assert.assertEquals(2, 
authorInfo.executeListUser().getPermissionInfo().get("user").size());
+    Assert.assertTrue(authorInfo.processTakeSnapshot(snapshotDir));
+    authorInfo.clear();
+    authorInfo.processLoadSnapshot(snapshotDir);
+    Assert.assertEquals(1, 
authorInfo.executeListRole().getPermissionInfo().get("role").size());
+    Assert.assertEquals(2, 
authorInfo.executeListUser().getPermissionInfo().get("user").size());
+  }
 }
diff --git 
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBLoadExternalTsFileWithTimePartitionIT.java
 
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBLoadExternalTsFileWithTimePartitionIT.java
index e8d85129ff..e8390bf9cd 100644
--- 
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBLoadExternalTsFileWithTimePartitionIT.java
+++ 
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBLoadExternalTsFileWithTimePartitionIT.java
@@ -20,11 +20,11 @@ package org.apache.iotdb.db.integration;
 
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.path.PartialPath;
+import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.StorageEngine;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
-import org.apache.iotdb.db.utils.FileUtils;
 import org.apache.iotdb.itbase.category.LocalStandaloneTest;
 import org.apache.iotdb.jdbc.Config;
 import org.apache.iotdb.tsfile.exception.write.WriteProcessException;
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
index 81e04716d4..ad67bde66f 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/BasicAuthorizer.java
@@ -30,9 +30,12 @@ import org.apache.iotdb.commons.service.IService;
 import org.apache.iotdb.commons.service.ServiceType;
 import org.apache.iotdb.commons.utils.AuthUtils;
 
+import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -164,6 +167,7 @@ public abstract class BasicAuthorizer implements 
IAuthorizer, IService {
   @Override
   public void createRole(String roleName) throws AuthException {
     if (!roleManager.createRole(roleName)) {
+      logger.error("Role {} already exists", roleName);
       throw new AuthException(String.format("Role %s already exists", 
roleName));
     }
   }
@@ -403,4 +407,16 @@ public abstract class BasicAuthorizer implements 
IAuthorizer, IService {
   public void replaceAllRoles(Map<String, Role> roles) throws AuthException {
     roleManager.replaceAllRoles(roles);
   }
+
+  @Override
+  public boolean processTakeSnapshot(File snapshotDir) throws TException, 
IOException {
+    return userManager.processTakeSnapshot(snapshotDir)
+        & roleManager.processTakeSnapshot(snapshotDir);
+  }
+
+  @Override
+  public void processLoadSnapshot(File snapshotDir) throws TException, 
IOException {
+    userManager.processLoadSnapshot(snapshotDir);
+    roleManager.processLoadSnapshot(snapshotDir);
+  }
 }
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/IAuthorizer.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/IAuthorizer.java
index 95d897560d..d06df9b2cf 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/IAuthorizer.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/authorizer/IAuthorizer.java
@@ -16,18 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.iotdb.commons.auth.authorizer;
 
 import org.apache.iotdb.commons.auth.AuthException;
 import org.apache.iotdb.commons.auth.entity.Role;
 import org.apache.iotdb.commons.auth.entity.User;
+import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
 
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 /** This interface provides all authorization-relative operations. */
-public interface IAuthorizer {
+public interface IAuthorizer extends SnapshotProcessor {
 
   /**
    * Login for a user.
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/BasicRoleManager.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/BasicRoleManager.java
index facf03d35d..9dcc646a98 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/BasicRoleManager.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/BasicRoleManager.java
@@ -37,9 +37,9 @@ import java.util.Set;
  */
 public abstract class BasicRoleManager implements IRoleManager {
 
-  private Map<String, Role> roleMap;
-  private IRoleAccessor accessor;
-  private HashLock lock;
+  protected Map<String, Role> roleMap;
+  protected IRoleAccessor accessor;
+  protected HashLock lock;
 
   BasicRoleManager(LocalFileRoleAccessor accessor) {
     this.roleMap = new HashMap<>();
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/IRoleAccessor.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/IRoleAccessor.java
index e6a1f071a0..fec9dfa28a 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/IRoleAccessor.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/IRoleAccessor.java
@@ -19,12 +19,13 @@
 package org.apache.iotdb.commons.auth.role;
 
 import org.apache.iotdb.commons.auth.entity.Role;
+import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
 
 import java.io.IOException;
 import java.util.List;
 
 /** This interface manages the serialization/deserialization of the role 
objects. */
-public interface IRoleAccessor {
+public interface IRoleAccessor extends SnapshotProcessor {
 
   /**
    * Deserialize a role from lower storage.
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/IRoleManager.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/IRoleManager.java
index 7128e0b82d..ccadbd5917 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/IRoleManager.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/IRoleManager.java
@@ -20,12 +20,13 @@ package org.apache.iotdb.commons.auth.role;
 
 import org.apache.iotdb.commons.auth.AuthException;
 import org.apache.iotdb.commons.auth.entity.Role;
+import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
 
 import java.util.List;
 import java.util.Map;
 
 /** This interface maintains roles in memory and is responsible for their 
modifications. */
-public interface IRoleManager {
+public interface IRoleManager extends SnapshotProcessor {
 
   /**
    * Get a role object.
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/LocalFileRoleAccessor.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/LocalFileRoleAccessor.java
index e39ea0cc03..f75758b481 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/LocalFileRoleAccessor.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/LocalFileRoleAccessor.java
@@ -22,8 +22,10 @@ import org.apache.iotdb.commons.auth.entity.PathPrivilege;
 import org.apache.iotdb.commons.auth.entity.Role;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.file.SystemFileFactory;
+import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.commons.utils.IOUtils;
 
+import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,6 +41,7 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 
 /**
  * This class store each role in a separate sequential file. Role file schema 
: Int32 role name size
@@ -53,6 +56,7 @@ public class LocalFileRoleAccessor implements IRoleAccessor {
   private static final Logger logger = 
LoggerFactory.getLogger(LocalFileRoleAccessor.class);
   private static final String TEMP_SUFFIX = ".temp";
   private static final String STRING_ENCODING = "utf-8";
+  private static final String roleSnapshotFileName = "system" + File.separator 
+ "roles";
 
   private String roleDirPath;
 
@@ -183,6 +187,47 @@ public class LocalFileRoleAccessor implements 
IRoleAccessor {
     return retList;
   }
 
+  @Override
+  public boolean processTakeSnapshot(File snapshotDir) throws TException, 
IOException {
+    SystemFileFactory systemFileFactory = SystemFileFactory.INSTANCE;
+    File roleFolder = systemFileFactory.getFile(roleDirPath);
+    File roleSnapshotDir = systemFileFactory.getFile(snapshotDir, 
roleSnapshotFileName);
+    File roleTmpSnapshotDir =
+        systemFileFactory.getFile(roleSnapshotDir.getAbsolutePath() + "-" + 
UUID.randomUUID());
+
+    boolean result = true;
+    try {
+      result = FileUtils.copyDir(roleFolder, roleTmpSnapshotDir);
+      result &= roleTmpSnapshotDir.renameTo(roleSnapshotDir);
+    } finally {
+      if (roleTmpSnapshotDir.exists() && !roleTmpSnapshotDir.delete()) {
+        FileUtils.deleteDirectory(roleTmpSnapshotDir);
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public void processLoadSnapshot(File snapshotDir) throws TException, 
IOException {
+    SystemFileFactory systemFileFactory = SystemFileFactory.INSTANCE;
+    File roleFolder = systemFileFactory.getFile(roleDirPath);
+    File roleTmpFolder =
+        systemFileFactory.getFile(roleFolder.getAbsolutePath() + "-" + 
UUID.randomUUID());
+    File roleSnapshotDir = systemFileFactory.getFile(snapshotDir, 
roleSnapshotFileName);
+
+    try {
+      org.apache.commons.io.FileUtils.moveDirectory(roleFolder, roleTmpFolder);
+      if (!FileUtils.copyDir(roleSnapshotDir, roleFolder)) {
+        logger.error("Failed to load role folder snapshot and rollback.");
+        // rollback if failed to copy
+        FileUtils.deleteDirectory(roleFolder);
+        org.apache.commons.io.FileUtils.moveDirectory(roleTmpFolder, 
roleFolder);
+      }
+    } finally {
+      FileUtils.deleteDirectory(roleTmpFolder);
+    }
+  }
+
   @Override
   public void reset() {
     if (SystemFileFactory.INSTANCE.getFile(roleDirPath).mkdirs()) {
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/LocalFileRoleManager.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/LocalFileRoleManager.java
index ecf52a68d3..3569e7c90d 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/LocalFileRoleManager.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/role/LocalFileRoleManager.java
@@ -19,9 +19,24 @@
 
 package org.apache.iotdb.commons.auth.role;
 
+import org.apache.thrift.TException;
+
+import java.io.File;
+import java.io.IOException;
+
 public class LocalFileRoleManager extends BasicRoleManager {
 
   public LocalFileRoleManager(String roleDirPath) {
     super(new LocalFileRoleAccessor(roleDirPath));
   }
+
+  @Override
+  public boolean processTakeSnapshot(File snapshotDir) throws TException, 
IOException {
+    return accessor.processTakeSnapshot(snapshotDir);
+  }
+
+  @Override
+  public void processLoadSnapshot(File snapshotDir) throws TException, 
IOException {
+    accessor.processLoadSnapshot(snapshotDir);
+  }
 }
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
index e4e04aa62d..00501f2563 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/BasicUserManager.java
@@ -45,9 +45,9 @@ public abstract class BasicUserManager implements 
IUserManager {
   private static final Logger logger = 
LoggerFactory.getLogger(BasicUserManager.class);
   private static final String NO_SUCH_USER_ERROR = "No such user %s";
 
-  private Map<String, User> userMap;
-  private IUserAccessor accessor;
-  private HashLock lock;
+  protected Map<String, User> userMap;
+  protected IUserAccessor accessor;
+  protected HashLock lock;
 
   /**
    * BasicUserManager Constructor.
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/IUserAccessor.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/IUserAccessor.java
index cb0cffee73..0dba5a04aa 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/IUserAccessor.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/IUserAccessor.java
@@ -19,12 +19,13 @@
 package org.apache.iotdb.commons.auth.user;
 
 import org.apache.iotdb.commons.auth.entity.User;
+import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
 
 import java.io.IOException;
 import java.util.List;
 
 /** This interface manages the serialization/deserialization of the user 
objects. */
-public interface IUserAccessor {
+public interface IUserAccessor extends SnapshotProcessor {
 
   /**
    * Deserialize a user from lower storage.
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/IUserManager.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/IUserManager.java
index 8f538512e1..6abc22e9d8 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/IUserManager.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/IUserManager.java
@@ -20,12 +20,13 @@ package org.apache.iotdb.commons.auth.user;
 
 import org.apache.iotdb.commons.auth.AuthException;
 import org.apache.iotdb.commons.auth.entity.User;
+import org.apache.iotdb.commons.snapshot.SnapshotProcessor;
 
 import java.util.List;
 import java.util.Map;
 
 /** This interface provides accesses to users. */
-public interface IUserManager {
+public interface IUserManager extends SnapshotProcessor {
 
   /**
    * Get a user object.
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/LocalFileUserAccessor.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/LocalFileUserAccessor.java
index 01f08d4428..7ded804145 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/LocalFileUserAccessor.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/LocalFileUserAccessor.java
@@ -22,8 +22,10 @@ import org.apache.iotdb.commons.auth.entity.PathPrivilege;
 import org.apache.iotdb.commons.auth.entity.User;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.file.SystemFileFactory;
+import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.commons.utils.IOUtils;
 
+import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -41,6 +43,7 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.UUID;
 
 /**
  * This class loads a user's information from the corresponding file.The user 
file is a sequential
@@ -55,10 +58,10 @@ import java.util.Set;
  * bytes
  */
 public class LocalFileUserAccessor implements IUserAccessor {
-
+  private static final Logger logger = 
LoggerFactory.getLogger(LocalFileUserAccessor.class);
   private static final String TEMP_SUFFIX = ".temp";
   private static final String STRING_ENCODING = "utf-8";
-  private static final Logger logger = 
LoggerFactory.getLogger(LocalFileUserAccessor.class);
+  private static final String userSnapshotFileName = "system" + File.separator 
+ "users";
 
   private String userDirPath;
   /**
@@ -235,6 +238,47 @@ public class LocalFileUserAccessor implements 
IUserAccessor {
     return retList;
   }
 
+  @Override
+  public boolean processTakeSnapshot(File snapshotDir) throws TException, 
IOException {
+    SystemFileFactory systemFileFactory = SystemFileFactory.INSTANCE;
+    File userFolder = systemFileFactory.getFile(userDirPath);
+    File userSnapshotDir = systemFileFactory.getFile(snapshotDir, 
userSnapshotFileName);
+    File userTmpSnapshotDir =
+        systemFileFactory.getFile(userSnapshotDir.getAbsolutePath() + "-" + 
UUID.randomUUID());
+
+    boolean result = true;
+    try {
+      result = FileUtils.copyDir(userFolder, userTmpSnapshotDir);
+      result &= userTmpSnapshotDir.renameTo(userSnapshotDir);
+    } finally {
+      if (userTmpSnapshotDir.exists() && !userTmpSnapshotDir.delete()) {
+        FileUtils.deleteDirectory(userTmpSnapshotDir);
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public void processLoadSnapshot(File snapshotDir) throws TException, 
IOException {
+    SystemFileFactory systemFileFactory = SystemFileFactory.INSTANCE;
+    File userFolder = systemFileFactory.getFile(userDirPath);
+    File userTmpFolder =
+        systemFileFactory.getFile(userFolder.getAbsolutePath() + "-" + 
UUID.randomUUID());
+    File userSnapshotDir = systemFileFactory.getFile(snapshotDir, 
userSnapshotFileName);
+
+    try {
+      org.apache.commons.io.FileUtils.moveDirectory(userFolder, userTmpFolder);
+      if (!FileUtils.copyDir(userSnapshotDir, userFolder)) {
+        logger.error("Failed to load user folder snapshot and rollback.");
+        // rollback if failed to copy
+        FileUtils.deleteDirectory(userFolder);
+        org.apache.commons.io.FileUtils.moveDirectory(userTmpFolder, 
userFolder);
+      }
+    } finally {
+      FileUtils.deleteDirectory(userTmpFolder);
+    }
+  }
+
   @Override
   public void reset() {
     if (SystemFileFactory.INSTANCE.getFile(userDirPath).mkdirs()) {
diff --git 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/LocalFileUserManager.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/LocalFileUserManager.java
index de38b7d4ca..b0f0364822 100644
--- 
a/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/LocalFileUserManager.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/auth/user/LocalFileUserManager.java
@@ -20,9 +20,24 @@ package org.apache.iotdb.commons.auth.user;
 
 import org.apache.iotdb.commons.auth.AuthException;
 
+import org.apache.thrift.TException;
+
+import java.io.File;
+import java.io.IOException;
+
 public class LocalFileUserManager extends BasicUserManager {
 
   public LocalFileUserManager(String userDirPath) throws AuthException {
     super(new LocalFileUserAccessor(userDirPath));
   }
+
+  @Override
+  public boolean processTakeSnapshot(File snapshotDir) throws TException, 
IOException {
+    return accessor.processTakeSnapshot(snapshotDir);
+  }
+
+  @Override
+  public void processLoadSnapshot(File snapshotDir) throws TException, 
IOException {
+    accessor.processLoadSnapshot(snapshotDir);
+  }
 }
diff --git 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/SnapshotProcessor.java
 
b/node-commons/src/main/java/org/apache/iotdb/commons/snapshot/SnapshotProcessor.java
similarity index 97%
rename from 
confignode/src/main/java/org/apache/iotdb/confignode/persistence/SnapshotProcessor.java
rename to 
node-commons/src/main/java/org/apache/iotdb/commons/snapshot/SnapshotProcessor.java
index 1ff79b5a83..06a69f568d 100644
--- 
a/confignode/src/main/java/org/apache/iotdb/confignode/persistence/SnapshotProcessor.java
+++ 
b/node-commons/src/main/java/org/apache/iotdb/commons/snapshot/SnapshotProcessor.java
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-package org.apache.iotdb.confignode.persistence;
+package org.apache.iotdb.commons.snapshot;
 
 import org.apache.thrift.TException;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/FileUtils.java 
b/node-commons/src/main/java/org/apache/iotdb/commons/utils/FileUtils.java
similarity index 54%
rename from server/src/main/java/org/apache/iotdb/db/utils/FileUtils.java
rename to 
node-commons/src/main/java/org/apache/iotdb/commons/utils/FileUtils.java
index c062fd401a..6296a46e42 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/FileUtils.java
+++ b/node-commons/src/main/java/org/apache/iotdb/commons/utils/FileUtils.java
@@ -16,14 +16,19 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.iotdb.db.utils;
+package org.apache.iotdb.commons.utils;
 
 import org.apache.iotdb.commons.file.SystemFileFactory;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.nio.file.DirectoryNotEmptyException;
 import java.nio.file.Files;
 import java.nio.file.NoSuchFileException;
@@ -32,6 +37,8 @@ import java.util.Arrays;
 public class FileUtils {
   private static Logger logger = LoggerFactory.getLogger(FileUtils.class);
 
+  private static final int bufferSize = 1024;
+
   private FileUtils() {}
 
   public static void deleteDirectory(File folder) {
@@ -49,6 +56,53 @@ public class FileUtils {
     }
   }
 
+  public static boolean copyDir(File sourceDir, File targetDir) throws 
IOException {
+    if (!sourceDir.exists() || !sourceDir.isDirectory()) {
+      logger.error(
+          "Failed to copy folder, because source folder [{}] doesn't exist.",
+          sourceDir.getAbsolutePath());
+      return false;
+    }
+    if (!targetDir.exists()) {
+      if (!targetDir.mkdirs()) {
+        logger.error(
+            "Failed to copy folder, because failed to create target 
folder[{}].",
+            targetDir.getAbsolutePath());
+        return false;
+      }
+    } else if (!targetDir.isDirectory()) {
+      logger.error(
+          "Failed to copy folder, because target folder [{}] already exist.",
+          targetDir.getAbsolutePath());
+      return false;
+    }
+    File[] files = sourceDir.listFiles();
+    if (files == null || files.length == 0) {
+      return true;
+    }
+    boolean result = true;
+    for (File file : files) {
+      if (!file.exists()) {
+        continue;
+      }
+      File targetFile = new File(targetDir, file.getName());
+      if (file.isDirectory()) {
+        result &= copyDir(file.getAbsoluteFile(), targetFile);
+      } else {
+        // copy file
+        try (BufferedInputStream in = new BufferedInputStream(new 
FileInputStream(file));
+            BufferedOutputStream out = new BufferedOutputStream(new 
FileOutputStream(targetFile))) {
+          byte[] bytes = new byte[bufferSize];
+          int size = 0;
+          while ((size = in.read(bytes)) > 0) {
+            out.write(bytes, 0, size);
+          }
+        }
+      }
+    }
+    return result;
+  }
+
   /**
    * Calculate the directory size including sub dir.
    *
diff --git 
a/server/src/main/java/org/apache/iotdb/db/auth/AuthorizerManager.java 
b/server/src/main/java/org/apache/iotdb/db/auth/AuthorizerManager.java
index 84c79e42e9..7ea4e3f225 100644
--- a/server/src/main/java/org/apache/iotdb/db/auth/AuthorizerManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/auth/AuthorizerManager.java
@@ -25,22 +25,28 @@ import org.apache.iotdb.commons.auth.authorizer.IAuthorizer;
 import org.apache.iotdb.commons.auth.entity.Role;
 import org.apache.iotdb.commons.auth.entity.User;
 
+import org.apache.thrift.TException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.File;
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 public class AuthorizerManager implements IAuthorizer {
 
   private static final Logger logger = 
LoggerFactory.getLogger(AuthorizerManager.class);
 
   private IAuthorizer iAuthorizer;
+  private ReentrantReadWriteLock snapshotLock;
 
   public AuthorizerManager() {
     try {
       iAuthorizer = BasicAuthorizer.getInstance();
+      snapshotLock = new ReentrantReadWriteLock();
     } catch (AuthException e) {
       logger.error(e.getMessage());
     }
@@ -59,77 +65,147 @@ public class AuthorizerManager implements IAuthorizer {
 
   @Override
   public boolean login(String username, String password) throws AuthException {
-    return iAuthorizer.login(username, password);
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.login(username, password);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void createUser(String username, String password) throws 
AuthException {
-    iAuthorizer.createUser(username, password);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.createUser(username, password);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void deleteUser(String username) throws AuthException {
-    iAuthorizer.deleteUser(username);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.deleteUser(username);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void grantPrivilegeToUser(String username, String path, int 
privilegeId)
       throws AuthException {
-    iAuthorizer.grantPrivilegeToUser(username, path, privilegeId);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.grantPrivilegeToUser(username, path, privilegeId);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void revokePrivilegeFromUser(String username, String path, int 
privilegeId)
       throws AuthException {
-    iAuthorizer.revokePrivilegeFromUser(username, path, privilegeId);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.revokePrivilegeFromUser(username, path, privilegeId);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void createRole(String roleName) throws AuthException {
-    iAuthorizer.createRole(roleName);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.createRole(roleName);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void deleteRole(String roleName) throws AuthException {
-    iAuthorizer.deleteRole(roleName);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.deleteRole(roleName);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void grantPrivilegeToRole(String roleName, String path, int 
privilegeId)
       throws AuthException {
-    iAuthorizer.grantPrivilegeToRole(roleName, path, privilegeId);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.grantPrivilegeToRole(roleName, path, privilegeId);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void revokePrivilegeFromRole(String roleName, String path, int 
privilegeId)
       throws AuthException {
-    iAuthorizer.revokePrivilegeFromRole(roleName, path, privilegeId);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.revokePrivilegeFromRole(roleName, path, privilegeId);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void grantRoleToUser(String roleName, String username) throws 
AuthException {
-    iAuthorizer.grantRoleToUser(roleName, username);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.grantRoleToUser(roleName, username);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void revokeRoleFromUser(String roleName, String username) throws 
AuthException {
-    iAuthorizer.revokeRoleFromUser(roleName, username);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.revokeRoleFromUser(roleName, username);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public Set<Integer> getPrivileges(String username, String path) throws 
AuthException {
-    return iAuthorizer.getPrivileges(username, path);
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.getPrivileges(username, path);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void updateUserPassword(String username, String newPassword) throws 
AuthException {
-    iAuthorizer.updateUserPassword(username, newPassword);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.updateUserPassword(username, newPassword);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public boolean checkUserPrivileges(String username, String path, int 
privilegeId)
       throws AuthException {
-    return iAuthorizer.checkUserPrivileges(username, path, privilegeId);
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.checkUserPrivileges(username, path, privilegeId);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
@@ -139,56 +215,131 @@ public class AuthorizerManager implements IAuthorizer {
 
   @Override
   public List<String> listAllUsers() {
-    return iAuthorizer.listAllUsers();
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.listAllUsers();
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public List<String> listAllRoles() {
-    return iAuthorizer.listAllRoles();
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.listAllRoles();
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public Role getRole(String roleName) throws AuthException {
-    return iAuthorizer.getRole(roleName);
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.getRole(roleName);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public User getUser(String username) throws AuthException {
-    return iAuthorizer.getUser(username);
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.getUser(username);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public boolean isUserUseWaterMark(String userName) throws AuthException {
-    return iAuthorizer.isUserUseWaterMark(userName);
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.isUserUseWaterMark(userName);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void setUserUseWaterMark(String userName, boolean useWaterMark) 
throws AuthException {
-    iAuthorizer.setUserUseWaterMark(userName, useWaterMark);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.setUserUseWaterMark(userName, useWaterMark);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public Map<String, Boolean> getAllUserWaterMarkStatus() {
-    return iAuthorizer.getAllUserWaterMarkStatus();
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.getAllUserWaterMarkStatus();
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public Map<String, User> getAllUsers() {
-    return iAuthorizer.getAllUsers();
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.getAllUsers();
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public Map<String, Role> getAllRoles() {
-    return iAuthorizer.getAllRoles();
+    snapshotLock.readLock().lock();
+    try {
+      return iAuthorizer.getAllRoles();
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void replaceAllUsers(Map<String, User> users) throws AuthException {
-    iAuthorizer.replaceAllUsers(users);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.replaceAllUsers(users);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
   }
 
   @Override
   public void replaceAllRoles(Map<String, Role> roles) throws AuthException {
-    iAuthorizer.replaceAllRoles(roles);
+    snapshotLock.readLock().lock();
+    try {
+      iAuthorizer.replaceAllRoles(roles);
+    } finally {
+      snapshotLock.readLock().unlock();
+    }
+  }
+
+  @Override
+  public boolean processTakeSnapshot(File snapshotDir) throws TException, 
IOException {
+    snapshotLock.writeLock().lock();
+    try {
+      return iAuthorizer.processTakeSnapshot(snapshotDir);
+    } finally {
+      snapshotLock.writeLock().unlock();
+    }
+  }
+
+  @Override
+  public void processLoadSnapshot(File snapshotDir) throws TException, 
IOException {
+    snapshotLock.writeLock().lock();
+    try {
+      iAuthorizer.processLoadSnapshot(snapshotDir);
+    } finally {
+      snapshotLock.writeLock().unlock();
+    }
   }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/DataRegion.java 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/DataRegion.java
index 7112596005..1fbd2ab5e0 100755
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/DataRegion.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/DataRegion.java
@@ -1571,7 +1571,7 @@ public class DataRegion {
     try {
       File storageGroupFolder = SystemFileFactory.INSTANCE.getFile(systemDir, 
dataRegionId);
       if (storageGroupFolder.exists()) {
-        
org.apache.iotdb.db.utils.FileUtils.deleteDirectory(storageGroupFolder);
+        
org.apache.iotdb.commons.utils.FileUtils.deleteDirectory(storageGroupFolder);
       }
     } finally {
       writeUnlock();
@@ -1628,7 +1628,7 @@ public class DataRegion {
       File storageGroupFolder =
           fsFactory.getFile(tsfilePath, logicalStorageGroupName + 
File.separator + dataRegionId);
       if (storageGroupFolder.exists()) {
-        
org.apache.iotdb.db.utils.FileUtils.deleteDirectory(storageGroupFolder);
+        
org.apache.iotdb.commons.utils.FileUtils.deleteDirectory(storageGroupFolder);
       }
     }
   }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/service/metrics/MetricsService.java 
b/server/src/main/java/org/apache/iotdb/db/service/metrics/MetricsService.java
index 294bd508c0..88d0cc2208 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/service/metrics/MetricsService.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/service/metrics/MetricsService.java
@@ -24,8 +24,8 @@ import org.apache.iotdb.commons.exception.StartupException;
 import org.apache.iotdb.commons.service.IService;
 import org.apache.iotdb.commons.service.JMXService;
 import org.apache.iotdb.commons.service.ServiceType;
+import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.utils.FileUtils;
 import org.apache.iotdb.db.wal.node.WALNode;
 import org.apache.iotdb.metrics.MetricService;
 import org.apache.iotdb.metrics.config.ReloadLevel;
diff --git 
a/server/src/main/java/org/apache/iotdb/db/sync/pipedata/queue/BufferedPipeDataQueue.java
 
b/server/src/main/java/org/apache/iotdb/db/sync/pipedata/queue/BufferedPipeDataQueue.java
index 7c8d51f531..7df0161272 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/sync/pipedata/queue/BufferedPipeDataQueue.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/sync/pipedata/queue/BufferedPipeDataQueue.java
@@ -19,11 +19,11 @@
 package org.apache.iotdb.db.sync.pipedata.queue;
 
 import org.apache.iotdb.commons.exception.IllegalPathException;
+import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.db.sync.conf.SyncConstant;
 import org.apache.iotdb.db.sync.conf.SyncPathUtil;
 import org.apache.iotdb.db.sync.pipedata.PipeData;
 import org.apache.iotdb.db.sync.pipedata.TsFilePipeData;
-import org.apache.iotdb.db.utils.FileUtils;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git 
a/server/src/main/java/org/apache/iotdb/db/sync/sender/recovery/TsFilePipeLogger.java
 
b/server/src/main/java/org/apache/iotdb/db/sync/sender/recovery/TsFilePipeLogger.java
index 6aa4e3309c..02bd032471 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/sync/sender/recovery/TsFilePipeLogger.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/sync/sender/recovery/TsFilePipeLogger.java
@@ -20,12 +20,12 @@
 package org.apache.iotdb.db.sync.sender.recovery;
 
 import org.apache.iotdb.commons.conf.IoTDBConstant;
+import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.db.engine.modification.ModificationFile;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
 import org.apache.iotdb.db.sync.conf.SyncConstant;
 import org.apache.iotdb.db.sync.conf.SyncPathUtil;
 import org.apache.iotdb.db.sync.sender.pipe.TsFilePipe;
-import org.apache.iotdb.db.utils.FileUtils;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
diff --git 
a/server/src/main/java/org/apache/iotdb/db/wal/recover/WALNodeRecoverTask.java 
b/server/src/main/java/org/apache/iotdb/db/wal/recover/WALNodeRecoverTask.java
index f8f533529c..477e93a408 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/wal/recover/WALNodeRecoverTask.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/wal/recover/WALNodeRecoverTask.java
@@ -18,7 +18,7 @@
  */
 package org.apache.iotdb.db.wal.recover;
 
-import org.apache.iotdb.db.utils.FileUtils;
+import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.db.wal.buffer.WALEntry;
 import org.apache.iotdb.db.wal.checkpoint.MemTableInfo;
 import org.apache.iotdb.db.wal.io.WALReader;
diff --git 
a/server/src/test/java/org/apache/iotdb/db/engine/compaction/TsFileIdentifierUT.java
 
b/server/src/test/java/org/apache/iotdb/db/engine/compaction/TsFileIdentifierUT.java
index 5ca09317fa..dab3c74767 100644
--- 
a/server/src/test/java/org/apache/iotdb/db/engine/compaction/TsFileIdentifierUT.java
+++ 
b/server/src/test/java/org/apache/iotdb/db/engine/compaction/TsFileIdentifierUT.java
@@ -19,10 +19,10 @@
 
 package org.apache.iotdb.db.engine.compaction;
 
+import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.db.conf.IoTDBConfig;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.engine.compaction.log.TsFileIdentifier;
-import org.apache.iotdb.db.utils.FileUtils;
 
 import org.junit.Assert;
 import org.junit.Test;

Reply via email to