You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by yi...@apache.org on 2024/02/23 11:05:52 UTC

(doris) 12/13: [regression](cold_heat)add cold heat test for hdfs (#31074)

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

yiguolei pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git

commit 30ef9b70c3a5768275c169bbdce91df27b571f4b
Author: lsy3993 <11...@users.noreply.github.com>
AuthorDate: Fri Feb 23 15:45:58 2024 +0800

    [regression](cold_heat)add cold heat test for hdfs (#31074)
    
    * add cold heat test for hdfs
---
 .../alter_table_add_policy_by_hdfs.groovy          | 145 ++++++
 ...reate_table_use_partition_policy_by_hdfs.groovy | 166 +++++++
 .../create_table_use_policy_by_hdfs.groovy         | 108 +++++
 .../disable_storage_policy_MoW_by_hdfs.groovy      | 137 ++++++
 .../modify_partition_add_policy_by_hdfs.groovy     | 158 +++++++
 .../use_default_storage_policy_bu_hdfs.groovy      | 105 +++++
 .../policy/alter_hdfs_resouce.groovy               | 262 +++++++++++
 .../policy/create_hdfs_resource.groovy             | 456 +++++++++++++++++++
 .../policy/drop_hdfs_reource.groovy                | 148 ++++++
 .../policy/show_hdfs_resource.groovy               |  70 +++
 .../add_drop_partition_by_hdfs.groovy              | 284 ++++++++++++
 ...eate_table_use_dynamic_partition_by_hdfs.groovy | 279 ++++++++++++
 ...reate_table_use_partition_policy_by_hdfs.groovy | 370 +++++++++++++++
 .../create_table_use_policy_by_hdfs.groovy         | 294 ++++++++++++
 .../modify_replica_use_partition_by_hdfs.groovy    | 506 +++++++++++++++++++++
 .../table_modify_resouce_and_policy_by_hdfs.groovy | 326 +++++++++++++
 16 files changed, 3814 insertions(+)

diff --git a/regression-test/suites/cold_heat_separation/empty_table_use_policy/alter_table_add_policy_by_hdfs.groovy b/regression-test/suites/cold_heat_separation/empty_table_use_policy/alter_table_add_policy_by_hdfs.groovy
new file mode 100644
index 00000000000..2517c2904b9
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/empty_table_use_policy/alter_table_add_policy_by_hdfs.groovy
@@ -0,0 +1,145 @@
+// 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.
+
+suite("add_table_policy_by_alter_table_hdfs") {
+    def create_table_not_have_policy_result = try_sql """
+        CREATE TABLE IF NOT EXISTS create_table_not_have_policy_hdfs
+        (
+            k1 BIGINT,
+            k2 LARGEINT,
+            v1 VARCHAR(2048)
+        )
+        UNIQUE KEY(k1)
+        DISTRIBUTED BY HASH (k1) BUCKETS 3
+        PROPERTIES(
+            "replication_num" = "1",
+            "enable_unique_key_merge_on_write" = "false"
+        );
+    """
+    assertEquals(create_table_not_have_policy_result.size(), 1);
+
+    def alter_table_use_not_exist_policy_result = try_sql """
+        ALTER TABLE create_table_not_have_policy_hdfs set ("storage_policy" = "policy_not_exist");
+    """
+    //  errCode = 2, detailMessage = Resource does not exist. name: policy_not_exist
+    assertEquals(alter_table_use_not_exist_policy_result, null);
+
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    if (!storage_exist.call("created_create_table_alter_policy_hdfs")) {
+        def create_hdfs_resource = try_sql """
+            CREATE RESOURCE IF NOT EXISTS "test_create_alter_table_use_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY IF NOT EXISTS created_create_table_alter_policy_hdfs
+            PROPERTIES(
+            "storage_resource" = "test_create_alter_table_use_resource_hdfs",
+            "cooldown_datetime" = "2025-06-08 00:00:00"
+            );
+        """
+        assertEquals(storage_exist.call("created_create_table_alter_policy_hdfs"), true)
+    }
+
+    def alter_table_try_again_result = try_sql """
+        ALTER TABLE create_table_not_have_policy_hdfs set ("storage_policy" = "created_create_table_alter_policy_hdfs");
+    """
+    // OK
+    assertEquals(alter_table_try_again_result.size(), 1);
+
+    def alter_table_when_table_has_storage_policy_result = try_sql """
+        ALTER TABLE create_table_not_have_policy_hdfs set ("storage_policy" = "created_create_table_alter_policy_hdfs");
+    """
+    // OK
+    assertEquals(alter_table_when_table_has_storage_policy_result.size(), 1);
+
+    if (!storage_exist.call("created_create_table_alter_policy_1_hdfs")) {
+        def create_hdfs_resource = try_sql """
+            CREATE RESOURCE IF NOT EXISTS "test_create_alter_table_use_resource_1_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY IF NOT EXISTS created_create_table_alter_policy_1_hdfs
+            PROPERTIES(
+            "storage_resource" = "test_create_alter_table_use_resource_1_hdfs",
+            "cooldown_datetime" = "2025-06-08 00:00:00"
+            );
+        """
+        assertEquals(storage_exist.call("created_create_table_alter_policy_1_hdfs"), true)
+    }
+
+    // current not support change storage policy name
+    def cannot_modify_exist_storage_policy_table_result = try_sql """
+        ALTER TABLE create_table_not_have_policy_hdfs set ("storage_policy" = "created_create_table_alter_policy_1_hdfs");
+    """
+    // OK
+    assertEquals(cannot_modify_exist_storage_policy_table_result.size(), 1);
+
+    // you can change created_create_table_alter_policy's policy cooldown time, cooldown ttl property,
+    // by alter storage policy
+    def modify_storage_policy_property_result = try_sql """
+        ALTER STORAGE POLICY "created_create_table_alter_policy_1_hdfs" PROPERTIES("cooldown_datetime" = "2026-06-08 00:00:00");
+    """
+    // change s3 resource, ak、sk by alter resource
+    def modify_storage_policy_property_result_1 = try_sql """
+        ALTER RESOURCE "test_create_alter_table_use_resource_1_hdfs" PROPERTIES("dfs.nameservices" = "has_been_changed");
+    """
+
+    sql """
+    DROP TABLE create_table_not_have_policy_hdfs;
+    """
+
+    sql """
+    DROP STORAGE POLICY created_create_table_alter_policy_1_hdfs;
+    """
+
+    sql """
+    DROP RESOURCE test_create_alter_table_use_resource_1_hdfs;
+    """
+
+}
+
diff --git a/regression-test/suites/cold_heat_separation/empty_table_use_policy/create_table_use_partition_policy_by_hdfs.groovy b/regression-test/suites/cold_heat_separation/empty_table_use_policy/create_table_use_partition_policy_by_hdfs.groovy
new file mode 100644
index 00000000000..4e55834adea
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/empty_table_use_policy/create_table_use_partition_policy_by_hdfs.groovy
@@ -0,0 +1,166 @@
+// 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.
+
+suite("create_table_use_partition_policy_hdfs") {
+    def cooldown_ttl = "10"
+
+    def create_table_partition_use_not_create_policy = try_sql """
+        CREATE TABLE IF NOT EXISTS create_table_partition_use_not_create_policy_hdfs
+        (
+            k1 DATE,
+            k2 INT,
+            V1 VARCHAR(2048) REPLACE
+        ) PARTITION BY RANGE (k1) (
+            PARTITION p1 VALUES LESS THAN ("2022-01-01") ("storage_policy" = "not_exist_policy_1" ,"replication_num"="1"),
+            PARTITION p2 VALUES LESS THAN ("2022-02-01") ("storage_policy" = "not_exist_policy_2" ,"replication_num"="1")
+        ) DISTRIBUTED BY HASH(k2) BUCKETS 1;
+    """
+
+    // errCode = 2, detailMessage = Storage policy does not exist. name: not_exist_policy_1
+    assertEquals(create_table_partition_use_not_create_policy, null)
+
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    if (!storage_exist.call("test_create_table_partition_use_policy_1_hdfs")) {
+        def create_hdfs_resource = try_sql """
+            CREATE RESOURCE IF NOT EXISTS "test_create_table_partition_use_resource_1_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY IF NOT EXISTS test_create_table_partition_use_policy_1_hdfs
+            PROPERTIES(
+            "storage_resource" = "test_create_table_partition_use_resource_1_hdfs",
+            "cooldown_ttl" = "$cooldown_ttl"
+            );
+        """
+        assertEquals(storage_exist.call("test_create_table_partition_use_policy_1_hdfs"), true)
+    }
+
+
+    if (!storage_exist.call("test_create_table_partition_use_policy_2_hdfs")) {
+        def create_hdfs_resource = try_sql """
+            CREATE RESOURCE IF NOT EXISTS "test_create_table_partition_use_resource_2_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY IF NOT EXISTS test_create_table_partition_use_policy_2_hdfs
+            PROPERTIES(
+            "storage_resource" = "test_create_table_partition_use_resource_2_hdfs",
+            "cooldown_ttl" = "$cooldown_ttl"
+            );
+        """
+        assertEquals(storage_exist.call("test_create_table_partition_use_policy_2_hdfs"), true)
+    }
+
+    // success
+    def create_table_partition_use_created_policy = try_sql """
+        CREATE TABLE IF NOT EXISTS create_table_partition_use_created_policy_hdfs
+        (
+            k1 DATE,
+            k2 INT,
+            V1 VARCHAR(2048) REPLACE
+        ) PARTITION BY RANGE (k1) (
+            PARTITION p1 VALUES LESS THAN ("2022-01-01") ("storage_policy" = "test_create_table_partition_use_policy_1_hdfs" ,"replication_num"="1"),
+            PARTITION p2 VALUES LESS THAN ("2022-02-01") ("storage_policy" = "test_create_table_partition_use_policy_2_hdfs" ,"replication_num"="1")
+        ) DISTRIBUTED BY HASH(k2) BUCKETS 1;
+    """
+
+    assertEquals(create_table_partition_use_created_policy.size(), 1);
+
+    sql """
+    DROP TABLE create_table_partition_use_created_policy_hdfs
+    """
+
+    def create_table_partition_use_created_policy_1 = try_sql """
+        CREATE TABLE IF NOT EXISTS create_table_partition_use_created_policy_1_hdfs
+        (
+            k1 DATEV2,
+            k2 INT,
+            V1 VARCHAR(2048) REPLACE
+        ) PARTITION BY RANGE (k1) (
+            PARTITION p1 VALUES LESS THAN ("2022-01-01") ("storage_policy" = "test_create_table_partition_use_policy_1_hdfs" ,"replication_num"="1"),
+            PARTITION p2 VALUES LESS THAN ("2022-02-01") ("storage_policy" = "test_create_table_partition_use_policy_2_hdfs" ,"replication_num"="1")
+        ) DISTRIBUTED BY HASH(k2) BUCKETS 1;
+    """
+
+    assertEquals(create_table_partition_use_created_policy_1.size(), 1);
+
+    sql """
+    DROP TABLE create_table_partition_use_created_policy_1_hdfs
+    """
+
+    def create_table_partition_use_created_policy_2 = try_sql """
+        CREATE TABLE IF NOT EXISTS create_table_partition_use_created_policy_2_hdfs
+        (
+            k1 DATETIMEV2(3),
+            k2 INT,
+            V1 VARCHAR(2048) REPLACE
+        ) PARTITION BY RANGE (k1) (
+            PARTITION p1 VALUES LESS THAN ("2022-01-01 00:00:00.111") ("storage_policy" = "test_create_table_partition_use_policy_1_hdfs" ,"replication_num"="1"),
+            PARTITION p2 VALUES LESS THAN ("2022-02-01 00:00:00.111") ("storage_policy" = "test_create_table_partition_use_policy_2_hdfs" ,"replication_num"="1")
+        ) DISTRIBUTED BY HASH(k2) BUCKETS 1;
+    """
+
+    assertEquals(create_table_partition_use_created_policy_2.size(), 1);
+
+    sql """
+    DROP TABLE create_table_partition_use_created_policy_2_hdfs;
+    """
+    sql """
+    DROP STORAGE POLICY test_create_table_partition_use_policy_1_hdfs;
+    """
+    sql """
+    DROP STORAGE POLICY test_create_table_partition_use_policy_2_hdfs;
+    """
+    sql """
+    DROP RESOURCE test_create_table_partition_use_resource_1_hdfs
+    """
+    sql """
+    DROP RESOURCE test_create_table_partition_use_resource_2_hdfs
+    """
+}
+
diff --git a/regression-test/suites/cold_heat_separation/empty_table_use_policy/create_table_use_policy_by_hdfs.groovy b/regression-test/suites/cold_heat_separation/empty_table_use_policy/create_table_use_policy_by_hdfs.groovy
new file mode 100644
index 00000000000..a81dc07256b
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/empty_table_use_policy/create_table_use_policy_by_hdfs.groovy
@@ -0,0 +1,108 @@
+// 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.
+
+suite("create_table_use_policy_hdfs") {
+    def cooldown_ttl = "10"
+
+    def create_table_use_not_create_policy = try_sql """
+        CREATE TABLE IF NOT EXISTS create_table_use_not_create_policy_hdfs
+        (
+            k1 BIGINT,
+            k2 LARGEINT,
+            v1 VARCHAR(2048)
+        )
+        UNIQUE KEY(k1)
+        DISTRIBUTED BY HASH (k1) BUCKETS 3
+        PROPERTIES(
+            "storage_policy" = "not_exist_policy",
+            "replication_num" = "1",
+            "enable_unique_key_merge_on_write" = "false"
+        );
+    """
+
+    // errCode = 2, detailMessage = Storage policy does not exist. name: not_exist_policy
+    assertEquals(create_table_use_not_create_policy, null)
+
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def create_hdfs_resource = try_sql """
+        CREATE RESOURCE IF NOT EXISTS "test_create_table_use_resource_hdfs"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+    def create_succ_1 = try_sql """
+        CREATE STORAGE POLICY IF NOT EXISTS test_create_table_use_policy_hdfs
+        PROPERTIES(
+        "storage_resource" = "test_create_table_use_resource_hdfs",
+        "cooldown_ttl" = "$cooldown_ttl"
+        );
+    """
+
+    sql """ALTER STORAGE POLICY test_create_table_use_policy_hdfs PROPERTIES("cooldown_ttl" = "$cooldown_ttl")"""
+
+    assertEquals(storage_exist.call("test_create_table_use_policy_hdfs"), true)
+
+    // success
+    def create_table_use_created_policy = try_sql """
+        CREATE TABLE IF NOT EXISTS create_table_use_created_policy_hdfs
+        (
+            k1 BIGINT,
+            k2 LARGEINT,
+            v1 VARCHAR(2048)
+        )
+        UNIQUE KEY(k1)
+        DISTRIBUTED BY HASH (k1) BUCKETS 3
+        PROPERTIES(
+            "storage_policy" = "test_create_table_use_policy_hdfs",
+            "replication_num" = "1",
+            "enable_unique_key_merge_on_write" = "false"
+        );
+    """
+
+    assertEquals(create_table_use_created_policy.size(), 1);
+
+    sql """
+    DROP TABLE IF EXISTS create_table_use_created_policy_hdfs
+    """
+    sql """
+    DROP STORAGE POLICY test_create_table_use_policy_hdfs
+    """
+    sql """
+    DROP RESOURCE test_create_table_use_resource_hdfs
+    """
+
+}
+
diff --git a/regression-test/suites/cold_heat_separation/empty_table_use_policy/disable_storage_policy_MoW_by_hdfs.groovy b/regression-test/suites/cold_heat_separation/empty_table_use_policy/disable_storage_policy_MoW_by_hdfs.groovy
new file mode 100644
index 00000000000..d5131d9c2a7
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/empty_table_use_policy/disable_storage_policy_MoW_by_hdfs.groovy
@@ -0,0 +1,137 @@
+// 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.
+
+suite("disable_storage_policy_MoW_hdfs"){
+    def s3_source_name = "default_s3_source_test"
+    def hdfs_source_name = "default_hdfs_source_test"
+    def storage_policy_name = "default_storage_policy_test_hdfs"
+
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    if(!storage_exist.call("${storage_policy_name}")){
+        def create_hdfs_resource = sql """
+            CREATE RESOURCE IF NOT EXISTS "${hdfs_source_name}"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_storage_policy = sql """
+            CREATE STORAGE POLICY IF NOT EXISTS ${storage_policy_name} PROPERTIES(
+                "storage_resource" = "${hdfs_source_name}",
+                "cooldown_ttl" = "1008611"
+            );
+        """
+
+        create_hdfs_resource
+        create_storage_policy
+    }
+
+    def table_name_test_1 = "disable_storage_policy_on_mow1_hdfs"
+    def table_name_test_2 = "disable_storage_policy_on_mow2_hdfs"
+    def table_name_test_3 = "disable_storage_policy_on_mow3_hdfs"
+    //Test case I. Should panic when creates MoW table with storage policy
+    test{
+        sql """
+            CREATE TABLE IF NOT EXISTS ${table_name_test_1} (
+                k1 DATE,
+                k2 INT,
+                V1 VARCHAR(2048) 
+            ) ENGINE = OLAP
+            UNIQUE KEY(k1,k2)
+            PARTITION BY RANGE (k1) 
+            ( 
+                PARTITION p1 VALUES LESS THAN ("2022-01-01") ("storage_policy" = "${storage_policy_name}", "replication_num"="1"), 
+                PARTITION p2 VALUES LESS THAN ("2022-02-01") ("storage_policy" = "${storage_policy_name}", "replication_num"="1") 
+            ) DISTRIBUTED BY HASH(k2) BUCKETS 1
+            PROPERTIES(
+                "replication_num" = "1",
+                "enable_unique_key_merge_on_write" = "true"
+            )  
+        """
+        exception "with storage policy(${storage_policy_name})"
+    }
+
+    //Test case II. Should panic when sets storage policy to MoW table or its partitions
+    sql """
+        CREATE TABLE IF NOT EXISTS ${table_name_test_2} (
+            id INT,
+            v1 INT
+        ) ENGINE = OLAP
+        UNIQUE KEY(id)
+        DISTRIBUTED BY HASH(id) BUCKETS 1
+        PROPERTIES(
+            "replication_num" = "1",
+            "enable_unique_key_merge_on_write" = "true"
+        );
+    """
+
+    test {
+        sql """
+            ALTER TABLE ${table_name_test_2} MODIFY PARTITION(*) SET("storage_policy" = "${storage_policy_name}");
+        """
+        exception "with storage policy(${storage_policy_name})"
+    }
+
+    test {
+        sql """
+            ALTER TABLE ${table_name_test_2} SET ("storage_policy" = "${storage_policy_name}");
+        """
+        exception "with storage policy(${storage_policy_name})"
+    }
+
+    //Test case III. Should panic when creates MoW table(without partitions) with storage policy
+    test {
+        sql """
+            CREATE TABLE IF NOT EXISTS ${table_name_test_3} (
+                k1 INT,
+                V1 INT
+            ) ENGINE = OLAP
+            UNIQUE KEY(k1)
+            DISTRIBUTED BY HASH (k1) BUCKETS 1
+            PROPERTIES(
+                "replication_num" = "1",
+                "enable_unique_key_merge_on_write" = "true",
+                "storage_policy" = "${storage_policy_name}"
+            );
+        """
+        exception "with storage policy(${storage_policy_name})"
+    }
+
+    //clean resource
+    sql""" DROP TABLE IF EXISTS ${table_name_test_1} """
+    sql""" DROP TABLE IF EXISTS ${table_name_test_2} """
+    sql""" DROP TABLE IF EXISTS ${table_name_test_3} """
+}
+
diff --git a/regression-test/suites/cold_heat_separation/empty_table_use_policy/modify_partition_add_policy_by_hdfs.groovy b/regression-test/suites/cold_heat_separation/empty_table_use_policy/modify_partition_add_policy_by_hdfs.groovy
new file mode 100644
index 00000000000..e6cbcd780ea
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/empty_table_use_policy/modify_partition_add_policy_by_hdfs.groovy
@@ -0,0 +1,158 @@
+// 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.
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+suite("add_table_policy_by_modify_partition_hdfs") {
+    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
+    Date date = new Date(System.currentTimeMillis() + 3600000)
+    def cooldownTime = format.format(date)
+
+    sql """DROP TABLE IF EXISTS create_table_partition_hdfs"""
+    def create_table_partition_not_have_policy_result = try_sql """
+        CREATE TABLE IF NOT EXISTS `create_table_partition_hdfs` (
+        `lo_orderkey` bigint(20) NOT NULL COMMENT "",
+        `lo_linenumber` bigint(20) NOT NULL COMMENT "",
+        `lo_custkey` int(11) NOT NULL COMMENT "",
+        `lo_partkey` int(11) NOT NULL COMMENT "",
+        `lo_suppkey` int(11) NOT NULL COMMENT "",
+        `lo_orderdate` int(11) NOT NULL COMMENT "",
+        `lo_orderpriority` varchar(16) NOT NULL COMMENT "",
+        `lo_shippriority` int(11) NOT NULL COMMENT "",
+        `lo_quantity` bigint(20) NOT NULL COMMENT "",
+        `lo_extendedprice` bigint(20) NOT NULL COMMENT "",
+        `lo_ordtotalprice` bigint(20) NOT NULL COMMENT "",
+        `lo_discount` bigint(20) NOT NULL COMMENT "",
+        `lo_revenue` bigint(20) NOT NULL COMMENT "",
+        `lo_supplycost` bigint(20) NOT NULL COMMENT "",
+        `lo_tax` bigint(20) NOT NULL COMMENT "",
+        `lo_commitdate` bigint(20) NOT NULL COMMENT "",
+        `lo_shipmode` varchar(11) NOT NULL COMMENT ""
+        )
+        PARTITION BY RANGE(`lo_orderdate`)
+        (PARTITION p1992 VALUES [("-2147483648"), ("19930101")),
+        PARTITION p1998 VALUES [("19980101"), ("19990101")) )
+        DISTRIBUTED BY HASH(`lo_orderkey`) BUCKETS 4
+        PROPERTIES (
+        "replication_num" = "1"
+        );
+    """
+    assertEquals(create_table_partition_not_have_policy_result.size(), 1);
+
+    // support
+    // 1. ALTER TABLE create_table_partition MODIFY PARTITION p1992 SET("storage_policy"="not_exist_policy");
+    // 2. ALTER TABLE create_table_partition MODIFY PARTITION (p1992, p1998) SET("storage_policy"="not_exist_policy");
+    // 3. ALTER TABLE create_table_partition MODIFY PARTITION (*) SET("storage_policy"="not_exist_policy");
+    def alter_table_partition_use_not_exist_policy_result = try_sql """
+        ALTER TABLE create_table_partition_hdfs MODIFY PARTITION p1992 SET("storage_policy"="not_exist_policy");
+    """
+    // errCode = 2, detailMessage = Resource does not exist. name: not_exist_policy
+    assertEquals(alter_table_partition_use_not_exist_policy_result, null);
+
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def create_hdfs_resource = try_sql """
+        CREATE RESOURCE IF NOT EXISTS "test_modify_partition_table_use_resource_hdfs"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+    def create_succ_1 = try_sql """
+        CREATE STORAGE POLICY IF NOT EXISTS created_create_table_partition_alter_policy_hdfs
+        PROPERTIES(
+        "storage_resource" = "test_modify_partition_table_use_resource_hdfs",
+        "cooldown_datetime" = "$cooldownTime"
+        );
+    """
+    sql """ALTER STORAGE POLICY created_create_table_partition_alter_policy_hdfs PROPERTIES("cooldown_datetime" = "$cooldownTime")"""
+    assertEquals(storage_exist.call("created_create_table_partition_alter_policy_hdfs"), true)
+
+    def alter_table_partition_try_again_result = try_sql """
+        ALTER TABLE create_table_partition_hdfs MODIFY PARTITION (*) SET("storage_policy"="created_create_table_partition_alter_policy_hdfs");
+    """
+    // OK
+    assertEquals(alter_table_partition_try_again_result.size(), 1);
+
+    try_sql """
+    CREATE STORAGE POLICY IF NOT EXISTS tmp2_hdfs
+        PROPERTIES(
+        "storage_resource" = "test_modify_partition_table_use_resource_hdfs",
+        "cooldown_datetime" = "$cooldownTime"
+        );
+    """
+
+    sql """
+    CREATE TABLE create_table_partion_use_created_policy_test_hdfs
+    (
+    k1 DATE,
+    k2 INT,
+    V1 VARCHAR(2048) REPLACE
+    ) PARTITION BY RANGE (k1) (
+    PARTITION p1 VALUES LESS THAN ("2022-01-01") ("storage_policy" = "tmp2_hdfs" ,"replication_num"="1"),
+    PARTITION p2 VALUES LESS THAN ("2022-02-01") ("storage_policy" = "tmp2_hdfs" ,"replication_num"="1")
+    ) DISTRIBUTED BY HASH(k2) BUCKETS 1 
+    PROPERTIES (
+    "replication_allocation" = "tag.location.default: 1",
+    "storage_policy" = "created_create_table_partition_alter_policy_hdfs"
+    );
+    """
+
+    // Test that the partition's specified policy would be covered by the table's policy
+    def partitions = sql """
+    show partitions from create_table_partion_use_created_policy_test_hdfs
+    """
+
+    for (par in partitions) {
+        assertTrue(par[12] == "created_create_table_partition_alter_policy_hdfs")
+    }
+
+    sql """
+    DROP TABLE IF EXISTS create_table_partition_hdfs;
+    """
+    sql """
+    DROP TABLE IF EXISTS create_table_partion_use_created_policy_test_hdfs;
+    """
+    sql """
+    DROP STORAGE POLICY created_create_table_partition_alter_policy_hdfs
+    """
+    sql """
+    DROP STORAGE POLICY tmp2_hdfs
+    """
+    sql """
+    DROP RESOURCE test_modify_partition_table_use_resource_hdfs
+    """
+}
+
diff --git a/regression-test/suites/cold_heat_separation/empty_table_use_policy/use_default_storage_policy_bu_hdfs.groovy b/regression-test/suites/cold_heat_separation/empty_table_use_policy/use_default_storage_policy_bu_hdfs.groovy
new file mode 100644
index 00000000000..48417febae4
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/empty_table_use_policy/use_default_storage_policy_bu_hdfs.groovy
@@ -0,0 +1,105 @@
+// 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.
+
+suite("use_default_storage_policy_hdfs") {
+    try_sql """
+    DROP TABLE use_default_storage_policy_hdfs;
+    """
+    try_sql """
+    DROP STORAGE POLICY default_storage_policy_hdfs
+    """
+    try_sql """
+    DROP RESOURCE default_hdfs_resource_hdfs
+    """
+
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    if (!storage_exist.call("default_storage_policy_hdfs")) {
+        def create_table_use_default_policy_but_not_set_default_policy_result = try_sql """
+            CREATE TABLE IF NOT EXISTS use_default_storage_policy_hdfs 
+            ( k1 DATE, k2 INT, V1 VARCHAR(2048) REPLACE ) 
+            PARTITION BY RANGE (k1) 
+            ( 
+                PARTITION p1 VALUES LESS THAN ("2022-01-01") ("storage_policy" = "default_storage_policy_hdfs", "replication_num"="1"), 
+                PARTITION p2 VALUES LESS THAN ("2022-02-01") ("storage_policy" = "default_storage_policy_hdfs", "replication_num"="1") 
+            ) DISTRIBUTED BY HASH(k2) BUCKETS 1;
+        """
+        // errCode = 2, detailMessage = Use default storage policy, but not give s3 info, please use alter resource to add default storage policy S3 info.
+        assertEquals(create_table_use_default_policy_but_not_set_default_policy_result, null);
+
+        def create_hdfs_resource = try_sql """
+            CREATE RESOURCE IF NOT EXISTS "default_hdfs_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY IF NOT EXISTS default_storage_policy_hdfs PROPERTIES(
+                "storage_resource" = "default_hdfs_resource_hdfs",
+                "cooldown_ttl" = "1008611"
+            );
+        """
+        assertEquals(storage_exist.call("default_storage_policy_hdfs"), true)
+    }
+
+    def create_table_use_default_policy_has_set_default_policy_result = try_sql """
+        CREATE TABLE IF NOT EXISTS use_default_storage_policy_hdfs 
+        ( k1 DATE, k2 INT, V1 VARCHAR(2048) REPLACE ) 
+        PARTITION BY RANGE (k1) 
+        ( 
+            PARTITION p1 VALUES LESS THAN ("2022-01-01") ("storage_policy" = "default_storage_policy_hdfs", "replication_num"="1"), 
+            PARTITION p2 VALUES LESS THAN ("2022-02-01") ("storage_policy" = "default_storage_policy_hdfs", "replication_num"="1") 
+        ) DISTRIBUTED BY HASH(k2) BUCKETS 1;
+    """
+    // success
+    assertEquals(create_table_use_default_policy_has_set_default_policy_result.size(), 1)
+
+    // you can change default_storage_policy's policy property, such as ak、sk,
+    // so table create_table_not_have_policy will use AWS_ACCESS_KEY = "has_been_changed"
+    def modify_storage_policy_property_result_1 = try_sql """
+        ALTER RESOURCE "default_hdfs_resource_hdfs" PROPERTIES("AWS_ACCESS_KEY" = "has_been_changed");
+    """
+
+    sql """
+    DROP TABLE use_default_storage_policy_hdfs;
+    """
+    sql """
+    DROP STORAGE POLICY default_storage_policy_hdfs
+    """
+    sql """
+    DROP RESOURCE default_hdfs_resource_hdfs
+    """
+}
+
diff --git a/regression-test/suites/cold_heat_separation/policy/alter_hdfs_resouce.groovy b/regression-test/suites/cold_heat_separation/policy/alter_hdfs_resouce.groovy
new file mode 100644
index 00000000000..44b38a41843
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/policy/alter_hdfs_resouce.groovy
@@ -0,0 +1,262 @@
+// 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.
+
+suite("alter_hdfs_policy") {
+
+    def check_resource_delete_if_exist = { resource_name ->
+        def has_resouce = sql """
+            SHOW RESOURCES WHERE NAME = "${resource_name}";
+        """
+        if (has_resouce.size() > 0) {
+            sql """
+                DROP RESOURCE '${resource_name}';
+            """
+        }
+    }
+
+    // create resource
+    def create_source = { resource_name ->
+        sql """
+        CREATE RESOURCE IF NOT EXISTS "${resource_name}"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+        """
+    }
+
+    def alter_resource_change_property = { resource_name ->
+        // support
+        def alter_result_succ_1 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("fs.defaultFS" = "1111");
+        """
+
+        def alter_result_succ_2 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("hadoop.username" = "2222");
+        """
+
+        def alter_result_succ_5 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("hadoop.password" = "5555");
+        """
+
+        def alter_result_succ_6 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("dfs.nameservices" = "6666");
+        """
+
+        def alter_result_succ_7 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("dfs.ha.namenodes.my_ha" = "7777");
+        """
+
+        // errCode = 2, detailMessage = current not support modify property : dfs.namenode.rpc-address.my_ha.my_namenode1
+        def alter_result_fail_1 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("dfs.namenode.rpc-address.my_ha.my_namenode1" = "8888");
+        """
+
+        // errCode = 2, detailMessage = current not support modify property : dfs.namenode.rpc-address.my_ha.my_namenode2
+        def alter_result_fail_2 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("dfs.namenode.rpc-address.my_ha.my_namenode2" = "9999");
+        """
+
+        // errCode = 2, detailMessage = current not support modify property : dfs.client.failover.proxy.provider
+        def alter_result_fail_3 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("dfs.client.failover.proxy.provider" = "10101010");
+        """
+
+        // errCode = 2, detailMessage = current not support modify property : type
+        def alter_result_fail_5 = try_sql """
+            ALTER RESOURCE "${resource_name}" PROPERTIES("type" = "local");
+        """
+    }
+
+    // todo : this function should check by really situation
+    def check_alter_resource_result_no_policy = { resource_name ->
+        def show_alter_result = order_sql """
+            SHOW RESOURCES WHERE NAME = "${resource_name}";
+        """
+        logger.info(show_alter_result.toString())
+        println show_alter_result.toString()
+
+        // AWS_ACCESS_KEY
+        assertEquals(show_alter_result[1][3], "false")
+        // AWS_BUCKET
+        assertEquals(show_alter_result[2][3], "7777")
+        // AWS_MAX_CONNECTIONS
+        assertEquals(show_alter_result[3][3], "8888")
+        // AWS_REQUEST_TIMEOUT_MS
+        assertEquals(show_alter_result[4][3], "9999")
+        // AWS_CONNECTION_TIMEOUT_MS
+        assertEquals(show_alter_result[5][3], "6666")
+        // AWS_ENDPOINT
+        assertEquals(show_alter_result[6][3], "1111")
+        // AWS_REGION
+        assertEquals(show_alter_result[7][3], "5555")
+        // s3_rootpath
+        assertEquals(show_alter_result[8][3], "2222")
+        // AWS_SECRET_KEY
+        assertEquals(show_alter_result[9][3], "hdfs")
+    }
+
+    // todo : this function should check by really situation
+    def check_alter_resource_result_with_policy = { resource_name ->
+        def show_alter_result = order_sql """
+            SHOW RESOURCES WHERE NAME = "${resource_name}";
+        """
+        logger.info(show_alter_result.toString())
+        println show_alter_result.toString()
+
+        // AWS_ACCESS_KEY
+        assertEquals(show_alter_result[1][3], "false")
+        // AWS_BUCKET
+        assertEquals(show_alter_result[2][3], "7777")
+        // AWS_MAX_CONNECTIONS
+        assertEquals(show_alter_result[3][3], "8888")
+        // AWS_REQUEST_TIMEOUT_MS
+        assertEquals(show_alter_result[4][3], "9999")
+        // AWS_CONNECTION_TIMEOUT_MS
+        assertEquals(show_alter_result[5][3], "6666")
+        // AWS_ENDPOINT
+        assertEquals(show_alter_result[6][3], "1111")
+        // AWS_REGION
+        assertEquals(show_alter_result[7][3], "5555")
+        // s3_rootpath
+        assertEquals(show_alter_result[8][3], "2222")
+        // AWS_SECRET_KEY
+        assertEquals(show_alter_result[9][3], "hdfs")
+    }
+
+
+    // test when no policy binding to resource
+    def no_binding_policy_resource = "no_binding_policy_resource_hdfs"
+    check_resource_delete_if_exist(no_binding_policy_resource)
+    create_source(no_binding_policy_resource)
+    alter_resource_change_property(no_binding_policy_resource)
+    check_alter_resource_result_no_policy(no_binding_policy_resource)
+
+
+    // test when policy binding to resource
+    def has_resource_policy_alter = "has_resource_policy_alter_hdfs"
+    sql """
+    DROP STORAGE POLICY IF EXISTS has_resouce_policy_alter_policy_hdfs
+    """
+    sql """
+    DROP STORAGE POLICY IF EXISTS has_test_policy_to_alter_hdfs
+    """
+    sql """
+    DROP STORAGE POLICY IF EXISTS has_test_policy_to_alter_1_hdfs
+    """
+    check_resource_delete_if_exist(has_resource_policy_alter)
+    create_source(has_resource_policy_alter)
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS has_resouce_policy_alter_policy_hdfs
+        PROPERTIES(
+            "storage_resource" = "${has_resource_policy_alter}",
+            "cooldown_ttl" = "1d"
+        )
+        """
+    alter_resource_change_property(has_resource_policy_alter)
+    check_alter_resource_result_with_policy(has_resource_policy_alter)
+    sql """
+    DROP STORAGE POLICY has_resouce_policy_alter_policy_hdfs
+    """
+
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    if (!storage_exist.call("has_test_policy_to_alter_hdfs")) {
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY has_test_policy_to_alter_hdfs
+            PROPERTIES( 
+            "storage_resource" = "${has_resource_policy_alter}",
+            "cooldown_ttl" = "10086"
+            );
+        """
+        assertEquals(storage_exist.call("has_test_policy_to_alter_hdfs"), true)
+    }
+
+    // OK
+    def alter_result_sql_succ_ttl = try_sql """
+        ALTER STORAGE POLICY has_test_policy_to_alter_hdfs PROPERTIES("cooldown_ttl" = "10000");
+    """
+
+    // FAIL
+    alter_result_sql_succ_ttl = try_sql """
+        ALTER STORAGE POLICY has_test_policy_to_alter_hdfs PROPERTIES("cooldown_ttl" = "-10000");
+    """
+
+    // OK
+    def alter_result_sql_succ_datetime = try_sql """
+        ALTER STORAGE POLICY has_test_policy_to_alter_hdfs PROPERTIES("cooldown_datetime" = "2023-06-08 00:00:00");
+    """
+
+    // FAILED
+    alter_result_sql_succ_datetime = try_sql """
+        ALTER STORAGE POLICY has_test_policy_to_alter_hdfs PROPERTIES("cooldown_datetime" = "2023-13-32 00:00:00");
+    """
+
+    // FAILED
+    def alter_result_sql_failed_storage_resource = try_sql """
+        ALTER STORAGE POLICY has_test_policy_to_alter_hdfs PROPERTIES("storage_resource" = "${no_binding_policy_resource}");
+    """
+    // errCode = 2, detailMessage = not support change storage policy's storage resource, you can change s3 properties by alter resource
+    assertEquals(alter_result_sql_failed_storage_resource, null)
+
+    if (!storage_exist.call("has_test_policy_to_alter_1_hdfs")) {
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY has_test_policy_to_alter_1_hdfs
+            PROPERTIES(
+            "storage_resource" = "${no_binding_policy_resource}",
+            "cooldown_datetime" = "2025-06-08 00:00:00"
+            );
+        """
+        assertEquals(storage_exist.call("has_test_policy_to_alter_1_hdfs"), true)
+    }
+
+    // go to check be、fe log about notify alter.
+    def alter_result_succ_again = try_sql """
+        ALTER RESOURCE "${has_resource_policy_alter}" PROPERTIES("AWS_ACCESS_KEY" = "akakak");
+    """
+
+    sql """
+    DROP STORAGE POLICY has_test_policy_to_alter_hdfs;
+    """
+
+    sql """
+    DROP STORAGE POLICY has_test_policy_to_alter_1_hdfs;
+    """
+
+    sql """
+            DROP RESOURCE '${no_binding_policy_resource}'
+        """
+}
+
diff --git a/regression-test/suites/cold_heat_separation/policy/create_hdfs_resource.groovy b/regression-test/suites/cold_heat_separation/policy/create_hdfs_resource.groovy
new file mode 100644
index 00000000000..0c903f3467e
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/policy/create_hdfs_resource.groovy
@@ -0,0 +1,456 @@
+// 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.
+
+suite("create_hdfs_policy") {
+    def has_created_1 = sql """
+        SHOW RESOURCES WHERE NAME = "crete_policy_1_hdfs";
+    """
+
+    // doesn't have name crete_policy_1 resources
+    // normal
+    if(has_created_1.size() == 0) {
+        sql """
+        CREATE RESOURCE IF NOT EXISTS "crete_policy_1_hdfs"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+        """
+
+        def create_sucess = sql """
+             SHOW RESOURCES WHERE NAME = "crete_policy_1_hdfs";
+        """
+        assertEquals(create_sucess.size(), 10)
+
+        def failed_cannot_create_duplicate_name_resources = try_sql """
+            CREATE RESOURCE "crete_policy_1_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+
+        // errCode = 2, detailMessage = Resource(crete_policy_1) already exist
+        assertEquals(failed_cannot_create_duplicate_name_resources, null)
+
+        // test if we could create one polycy with the same name but
+        // with different properties
+        def failed_cannot_create_duplicate_name_resources_with_different_properties = try_sql """
+            CREATE RESOURCE "crete_policy_1_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive1",
+            "hadoop.password"="hive1",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+           );
+        """
+        assertEquals(failed_cannot_create_duplicate_name_resources_with_different_properties, null)
+
+        // delete the policy with the same name then try to
+        // create policies with different property each time
+        def drop_result = try_sql """
+            DROP RESOURCE 'crete_policy_1_hdfs'
+        """
+        assertEquals(drop_result.size(), 1)
+
+        def create_duplicate_name_resources_different_username = try_sql """
+            CREATE RESOURCE "crete_policy_1_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive1",
+            "hadoop.password"="hive1",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        assertEquals(create_duplicate_name_resources_different_username.size(), 1)
+
+        drop_result = try_sql """
+            DROP RESOURCE 'crete_policy_1_hdfs'
+        """
+
+        assertEquals(drop_result.size(), 1)
+
+        def create_duplicate_name_resources_different_dfs_nameservices = try_sql """
+        CREATE RESOURCE "crete_policy_1_hdfs"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+        """
+        assertEquals(create_duplicate_name_resources_different_dfs_nameservices.size(), 1)
+
+        drop_result = try_sql """
+            DROP RESOURCE 'crete_policy_1_hdfs'
+        """
+        assertEquals(drop_result.size(), 1)
+    }
+
+    // can't create success, due to missing required items
+    def has_created_2 = sql """
+        SHOW RESOURCES WHERE NAME = "crete_policy_2_hdfs";
+    """
+    if (has_created_2.size() == 0) {
+        def failed_create_1 = try_sql """
+        CREATE RESOURCE "crete_policy_2_hdfs"
+        PROPERTIES(
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+        """
+        // errCode = 2, detailMessage = Resource type can't be null
+        assertEquals(failed_create_1, null)
+    }
+
+    if (has_created_2.size() == 0) {
+        def failed_create_2 = try_sql """
+        CREATE RESOURCE "crete_policy_2_hdfs"
+        PROPERTIES(
+            "type"="hdfs",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+        """
+        // errCode = 2, detailMessage = Missing [fs.defaultFS] in properties.
+        assertEquals(failed_create_2, [[0]])
+    }
+
+    if (has_created_2.size() == 0) {
+        def failed_create_2 = try_sql """
+        CREATE RESOURCE "crete_policy_2_hdfs"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+        """
+        // errCode = 2, detailMessage = Missing [hadoop.username] in properties.
+        assertEquals(failed_create_2, null)
+    }
+
+    if (has_created_2.size() == 0) {
+        def failed_create_2 = try_sql """
+        CREATE RESOURCE "crete_policy_2_hdfs"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+        """
+        // errCode = 2, detailMessage = Missing [dfs.nameservices] in properties.
+        assertEquals(failed_create_2, null)
+    }
+
+    if (has_created_2.size() == 0) {
+        def failed_create_2 = try_sql """
+        CREATE RESOURCE "crete_policy_2_hdfs"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+       );
+        """
+        // errCode = 2, detailMessage = Missing [dfs.ha.namenodes.my_ha] in properties.
+        assertEquals(failed_create_2, null)
+    }
+
+    // create policy
+
+
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    if (!storage_exist.call("testPolicy_10_hdfs")) {
+        def create_s3_resource = try_sql """
+            CREATE RESOURCE "testPolicy_10_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY testPolicy_10_hdfs
+            PROPERTIES(
+            "storage_resource" = "testPolicy_10_resource_hdfs",
+            "cooldown_datetime" = "2025-06-08 00:00:00"
+            );
+        """
+        assertEquals(storage_exist.call("testPolicy_10_hdfs"), true)
+
+        sql"""
+        DROP STORAGE POLICY testPolicy_10_hdfs;
+        """
+
+        sql"""
+        DROP RESOURCE testPolicy_10_resource_hdfs;
+        """
+    }
+
+    if (!storage_exist.call("testPolicy_11_hdfs")) {
+        def create_s3_resource = try_sql """
+            CREATE RESOURCE "testPolicy_11_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY testPolicy_11_hdfs
+            PROPERTIES(
+            "storage_resource" = "testPolicy_11_resource_hdfs",
+            "cooldown_ttl" = "10086"
+            );
+        """
+        assertEquals(storage_exist.call("testPolicy_11_hdfs"), true)
+
+        sql """
+        DROP STORAGE POLICY testPolicy_11_hdfs;
+        """
+
+        sql """
+        DROP RESOURCE "testPolicy_11_resource_hdfs";
+        """
+    }
+
+    if (!storage_exist.call("testPolicy_12_hdfs")) {
+        def create_s3_resource = try_sql """
+            CREATE RESOURCE "testPolicy_12_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY testPolicy_12_hdfs
+            PROPERTIES(
+            "storage_resource" = "testPolicy_12_resource_hdfs",
+            "cooldown_ttl" = "10086",
+            "cooldown_datetime" = "2025-06-08 00:00:00"
+            );
+        """
+        // errCode = 2, detailMessage = cooldown_datetime and cooldown_ttl can't be set together.
+        assertEquals(storage_exist.call("testPolicy_12_hdfs"), false)
+
+        sql """
+            DROP RESOURCE "testPolicy_12_resource_hdfs"
+        """
+    }
+
+    if (!storage_exist.call("testPolicy_13_hdfs")) {
+        def create_s3_resource = try_sql """
+            CREATE RESOURCE "testPolicy_13_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY testPolicy_13_hdfs
+            PROPERTIES(
+            "storage_resource" = "testPolicy_13_resource_hdfs",
+            "cooldown_ttl" = "-10086"
+            );
+        """
+        // errCode = 2, detailMessage = cooldown_ttl must >= 0.
+        assertEquals(storage_exist.call("testPolicy_13_hdfs"), false)
+        sql """
+            DROP RESOURCE "testPolicy_13_resource_hdfs"
+        """
+    }
+
+    if (!storage_exist.call("testPolicy_14_hdfs")) {
+        def create_s3_resource = try_sql """
+            CREATE RESOURCE "testPolicy_14_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY testPolicy_14_hdfs
+            PROPERTIES(
+            "storage_resource" = "testPolicy_14_resource_hdfs",
+            "cooldown_datetime" = "2025-06-08"
+            );
+        """
+        //  errCode = 2, detailMessage = cooldown_datetime format error: 2022-06-08
+        assertEquals(storage_exist.call("testPolicy_14_hdfs"), false)
+    }
+
+    if (!storage_exist.call("testPolicy_15_hdfs")) {
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY testPolicy_15_hdfs
+            PROPERTIES(
+            "storage_resource" = "s3_resource_not_exist_hdfs",
+            "cooldown_datetime" = "2025-06-08 00:00:00"
+            );
+        """
+        //  errCode = 2, detailMessage = storage resource doesn't exist: s3_resource_not_exist_hdfs
+        assertEquals(storage_exist.call("testPolicy_15_hdfs"), false)
+    }
+
+    if (!storage_exist.call("testPolicy_redundant_name_hdfs")) {
+        def create_s3_resource = try_sql """
+            CREATE RESOURCE "testPolicy_redundant_name_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_s3_resource_1 = try_sql """
+            CREATE RESOURCE "testPolicy_redundant_name_resource_1_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY testPolicy_redundant_name_hdfs
+            PROPERTIES(
+            "storage_resource" = "testPolicy_redundant_name_resource_hdfs",
+            "cooldown_ttl" = "10086"
+            );
+        """
+        try {
+            sql """
+                CREATE STORAGE POLICY testPolicy_redundant_name_hdfs
+                PROPERTIES(
+                "storage_resource" = "testPolicy_redundant_name_resource_1_hdfs",
+                "cooldown_ttl" = "10086"
+                );
+            """
+        } catch (Exception e) {
+            log.info(e.getMessage())
+            assertTrue(e.getMessage().contains('already create'))
+        }
+    }
+}
+
diff --git a/regression-test/suites/cold_heat_separation/policy/drop_hdfs_reource.groovy b/regression-test/suites/cold_heat_separation/policy/drop_hdfs_reource.groovy
new file mode 100644
index 00000000000..39bbaf09e7a
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/policy/drop_hdfs_reource.groovy
@@ -0,0 +1,148 @@
+// 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.
+
+suite("drop_hdfs_policy") {
+    def storage_exist = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(iter in show_storage_policy){
+            if(name == iter[0]){
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def resource_not_table_use = "resource_not_table_use_hdfs"
+    def use_policy = "use_policy_hdfs"
+
+    if (!storage_exist.call(use_policy)) {
+        def has_resouce_policy_drop = sql """
+            SHOW RESOURCES WHERE NAME = "${resource_not_table_use}";
+        """
+        if(has_resouce_policy_drop.size() == 0) {
+            sql """
+            CREATE RESOURCE "${resource_not_table_use}"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+            """
+        }
+
+
+        def drop_result = try_sql """
+            DROP RESOURCE ${resource_not_table_use}
+        """
+        // can drop, no policy use
+        assertEquals(drop_result.size(), 1)
+
+        def resource_table_use = "resource_table_use_hdfs"
+        sql """
+        CREATE RESOURCE IF NOT EXISTS "${resource_table_use}"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+        """
+
+
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY ${use_policy}
+            PROPERTIES(
+            "storage_resource" = "${resource_table_use}",
+            "cooldown_datetime" = "2025-06-08 00:00:00"
+            );
+        """
+        assertEquals(storage_exist.call(use_policy), true)
+
+        def drop_s3_resource_result_1 = try_sql """
+            DROP RESOURCE ${resource_table_use}
+        """
+        // errCode = 2, detailMessage = S3 resource used by policy, can't drop it.
+        assertEquals(drop_s3_resource_result_1, null)
+
+        def drop_policy_ret = try_sql """
+            DROP STORAGE POLICY ${use_policy}
+        """
+        // can drop, no table use
+        assertEquals(drop_policy_ret.size(), 1)
+
+        def create_succ_2 = try_sql """
+            CREATE STORAGE POLICY IF NOT EXISTS drop_policy_test_has_table_binded_hdfs
+            PROPERTIES(
+            "storage_resource" = "${resource_table_use}",
+            "cooldown_datetime" = "2025-06-08 00:00:00"
+            );
+        """
+        assertEquals(storage_exist.call("drop_policy_test_has_table_binded_hdfs"), true)
+
+        // success
+        def create_table_use_created_policy = try_sql """
+            CREATE TABLE IF NOT EXISTS create_table_binding_created_policy_hdfs
+            (
+                k1 BIGINT,
+                k2 LARGEINT,
+                v1 VARCHAR(2048)
+            )
+            UNIQUE KEY(k1)
+            DISTRIBUTED BY HASH (k1) BUCKETS 3
+            PROPERTIES(
+                "storage_policy" = "drop_policy_test_has_table_binded_hdfs",
+                "replication_num" = "1",
+                "enable_unique_key_merge_on_write" = "false"
+            );
+        """
+
+        assertEquals(create_table_use_created_policy.size(), 1);
+
+        def drop_policy_fail_ret = try_sql """
+            DROP STORAGE POLICY drop_policy_test_has_table_binded_hdfs
+        """
+        // fail to drop, there are tables using this policy
+        assertEquals(drop_policy_fail_ret, null)
+
+        sql """
+        DROP TABLE create_table_binding_created_policy_hdfs;
+        """
+
+        sql """
+        DROP STORAGE POLICY drop_policy_test_has_table_binded_hdfs;
+        """
+
+        sql """
+        DROP RESOURCE ${resource_table_use};
+        """
+    }
+
+}
+
diff --git a/regression-test/suites/cold_heat_separation/policy/show_hdfs_resource.groovy b/regression-test/suites/cold_heat_separation/policy/show_hdfs_resource.groovy
new file mode 100644
index 00000000000..70e06ea15f1
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation/policy/show_hdfs_resource.groovy
@@ -0,0 +1,70 @@
+// 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.
+
+suite("show_hdfs_policy") {
+    def get_storage_policy = { name ->
+        def show_storage_policy = sql """
+        SHOW STORAGE POLICY;
+        """
+        for(policy in show_storage_policy){
+            if(name == policy[0]){
+                return policy;
+            }
+        }
+        return [];
+    }
+
+    if (get_storage_policy.call("showPolicy_1_policy_hdfs").isEmpty()){
+        def create_s3_resource = try_sql """
+            CREATE RESOURCE "showPolicy_1_resource_hdfs"
+            PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="127.0.0.1:8120",
+            "hadoop.username"="hive",
+            "hadoop.password"="hive",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+            );
+        """
+        def create_succ_1 = try_sql """
+            CREATE STORAGE POLICY showPolicy_1_policy_hdfs
+            PROPERTIES(
+            "storage_resource" = "showPolicy_1_resource_hdfs",
+            "cooldown_datetime" = "2022-06-08 00:00:00"
+            );
+        """
+    }
+    def show_result = sql """
+        SHOW STORAGE POLICY;
+    """
+
+    def storage_policy = get_storage_policy("showPolicy_1_policy_hdfs")
+    assertEquals(storage_policy.size(), 7)
+    assertEquals(storage_policy[4], "showPolicy_1_resource_hdfs")
+    assertEquals(storage_policy[5], "2022-06-08 00:00:00")
+    sql """
+    DROP STORAGE POLICY showPolicy_1_policy_hdfs;
+    """
+
+    sql """
+    DROP RESOURCE "showPolicy_1_resource_hdfs";
+    """
+}
+
diff --git a/regression-test/suites/cold_heat_separation_p2/add_drop_partition_by_hdfs.groovy b/regression-test/suites/cold_heat_separation_p2/add_drop_partition_by_hdfs.groovy
new file mode 100644
index 00000000000..3437bcfc37b
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation_p2/add_drop_partition_by_hdfs.groovy
@@ -0,0 +1,284 @@
+// 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.
+import groovy.json.JsonSlurper
+import org.codehaus.groovy.runtime.IOGroovyMethods
+import java.time.LocalDate;
+
+suite("add_drop_partition_by_hdfs") {
+    def fetchBeHttp = { check_func, meta_url ->
+        def i = meta_url.indexOf("/api")
+        String endPoint = meta_url.substring(0, i)
+        String metaUri = meta_url.substring(i)
+        i = endPoint.lastIndexOf('/')
+        endPoint = endPoint.substring(i + 1)
+        httpTest {
+            endpoint endPoint
+            uri metaUri
+            op "get"
+            check check_func
+        }
+    }
+    // data_sizes is one arrayList<Long>, t is tablet
+    def fetchDataSize = { data_sizes, t ->
+        def tabletId = t[0]
+        String meta_url = t[17]
+        def clos = {  respCode, body ->
+            logger.info("test ttl expired resp Code {}", "${respCode}".toString())
+            assertEquals("${respCode}".toString(), "200")
+            String out = "${body}".toString()
+            def obj = new JsonSlurper().parseText(out)
+            data_sizes[0] = obj.local_data_size
+            data_sizes[1] = obj.remote_data_size
+        }
+        fetchBeHttp(clos, meta_url.replace("header", "data_size"))
+    }
+    // used as passing out parameter to fetchDataSize
+    List<Long> sizes = [-1, -1]
+    def tableName = "tbl1"
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+
+    def check_storage_policy_exist = { name->
+        def polices = sql"""
+        show storage policy;
+        """
+        for (p in polices) {
+            if (name == p[0]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def resource_name = "test_add_drop_partition_resource"
+    def policy_name= "test_add_drop_partition_policy"
+
+    if (check_storage_policy_exist(policy_name)) {
+        sql """
+            DROP STORAGE POLICY ${policy_name}
+        """
+    }
+
+    def has_resouce = sql """
+        SHOW RESOURCES WHERE NAME = "${resource_name}";
+    """
+    if (has_resouce.size() > 0) {
+        sql """
+            DROP RESOURCE ${resource_name}
+        """
+    }
+
+    sql """
+        CREATE RESOURCE IF NOT EXISTS "${resource_name}"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="${getHdfsFs()}",
+            "hadoop.username"="${getHdfsUser()}",
+            "hadoop.password"="${getHdfsPasswd()}",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS ${policy_name}
+        PROPERTIES(
+            "storage_resource" = "${resource_name}",
+            "cooldown_ttl" = "300"
+        )
+    """
+
+    // test one replica
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    sql """
+            CREATE TABLE ${tableName} (
+            `k1` int,
+            `k2` date
+            )
+            PARTITION BY RANGE(k2)(
+                partition p1 VALUES LESS THAN ("2014-01-01"),
+                partition p2 VALUES LESS THAN ("2015-01-01"),
+                partition p3 VALUES LESS THAN ("2016-01-01")
+            )
+            DISTRIBUTED BY HASH(k1) BUCKETS 1
+            PROPERTIES
+            (
+            "replication_num" = "1",
+            "storage_policy" = "${policy_name}"
+            );
+        """
+    sql """
+        insert into ${tableName} values(1, "2013-01-01");
+    """
+    sql """
+        insert into ${tableName} values(1, "2014-01-01");
+    """
+    sql """
+        insert into ${tableName} values(1, "2015-01-01");
+    """
+
+    // show tablets from table, 获取第一个tablet的 LocalDataSize1
+    def tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+    def LocalDataSize1 = sizes[0]
+    def RemoteDataSize1 = sizes[1]
+    log.info( "test local size {} not zero, remote size {}", LocalDataSize1, RemoteDataSize1)
+    assertTrue(LocalDataSize1 != 0)
+    log.info( "test remote size is zero")
+    assertEquals(RemoteDataSize1, 0)
+    def originLocalDataSize1 = LocalDataSize1;
+
+    // 等待10min,show tablets from table, 预期not_use_storage_policy_tablet_list 的 RemoteDataSize 为0,LocalDataSize不为0
+    sleep(600000)
+
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    assertTrue(tablets.size() > 0)
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    Long sleepTimes = 0;
+    while (RemoteDataSize1 != originLocalDataSize1 && sleepTimes < 60) {
+        log.info( "test remote size is same with origin size, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+        LocalDataSize1 = sizes[0]
+        RemoteDataSize1 = sizes[1]
+        sleepTimes += 1
+    }
+    log.info( "test local size is  zero")
+    assertEquals(LocalDataSize1, 0)
+    log.info( "test remote size not zero")
+    assertEquals(RemoteDataSize1, originLocalDataSize1)
+
+    // 12列是storage policy
+    def partitions = sql "show partitions from ${tableName}"
+    for (par in partitions) {
+        assertTrue(par[12] == "${policy_name}")
+    }
+
+    try_sql """
+    drop storage policy add_policy;
+    """
+
+    try_sql """
+    drop resource add_resource;
+    """
+
+    sql """
+        CREATE RESOURCE IF NOT EXISTS "add_resource"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="${getHdfsFs()}",
+            "hadoop.username"="${getHdfsUser()}",
+            "hadoop.password"="${getHdfsPasswd()}",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+
+    try_sql """
+    create storage policy tmp_policy
+    PROPERTIES( "storage_resource" = "add_resource", "cooldown_ttl" = "300");
+    """
+
+    // can not set to one policy with different resource
+    try {
+        sql """alter table ${tableName} set ("storage_policy" = "add_policy");"""
+    } catch (java.sql.SQLException t) {
+        assertTrue(true)
+    }
+
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS add_policy1
+        PROPERTIES(
+            "storage_resource" = "${resource_name}",
+            "cooldown_ttl" = "60"
+        )
+    """
+
+    sql """alter table ${tableName} set ("storage_policy" = "add_policy1");"""
+
+    // wait for report
+    sleep(300000)
+
+    partitions = sql "show partitions from ${tableName}"
+    for (par in partitions) {
+        assertTrue(par[12] == "add_policy1")
+    }
+
+
+    sql """
+        alter table ${tableName} ADD PARTITION np
+        VALUES LESS THAN ("2017-01-01");
+    """
+
+    sql """
+        insert into ${tableName} values(1, "2017-01-01");
+    """
+
+    partitions = sql "show partitions from ${tableName}"
+    for (par in partitions) {
+        assertTrue(par[12] == "add_policy1")
+    }
+
+    sql """
+    select * from ${tableName}
+    """
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+    sql """
+    drop storage policy add_policy;
+    """
+
+    sql """
+    drop storage policy add_policy1;
+    """
+
+    sql """
+    drop resource add_resource;
+    """
+
+
+
+}
diff --git a/regression-test/suites/cold_heat_separation_p2/create_table_use_dynamic_partition_by_hdfs.groovy b/regression-test/suites/cold_heat_separation_p2/create_table_use_dynamic_partition_by_hdfs.groovy
new file mode 100644
index 00000000000..a007b26305d
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation_p2/create_table_use_dynamic_partition_by_hdfs.groovy
@@ -0,0 +1,279 @@
+// 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.
+import groovy.json.JsonSlurper
+import org.codehaus.groovy.runtime.IOGroovyMethods
+import java.time.LocalDate;
+
+suite("cold_heat_dynamic_partition_by_hdfs") {
+    def fetchBeHttp = { check_func, meta_url ->
+        def i = meta_url.indexOf("/api")
+        String endPoint = meta_url.substring(0, i)
+        String metaUri = meta_url.substring(i)
+        i = endPoint.lastIndexOf('/')
+        endPoint = endPoint.substring(i + 1)
+        httpTest {
+            endpoint endPoint
+            uri metaUri
+            op "get"
+            check check_func
+        }
+    }
+    // data_sizes is one arrayList<Long>, t is tablet
+    def fetchDataSize = { data_sizes, t ->
+        def tabletId = t[0]
+        String meta_url = t[17]
+        def clos = {  respCode, body ->
+            logger.info("test ttl expired resp Code {}", "${respCode}".toString())
+            assertEquals("${respCode}".toString(), "200")
+            String out = "${body}".toString()
+            def obj = new JsonSlurper().parseText(out)
+            data_sizes[0] = obj.local_data_size
+            data_sizes[1] = obj.remote_data_size
+        }
+        fetchBeHttp(clos, meta_url.replace("header", "data_size"))
+    }
+    // used as passing out parameter to fetchDataSize
+    List<Long> sizes = [-1, -1]
+    def tableName = "tbl2"
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+
+    def check_storage_policy_exist = { name->
+        def polices = sql"""
+        show storage policy;
+        """
+        for (p in polices) {
+            if (name == p[0]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def resource_name = "test_dynamic_partition_resource"
+    def policy_name= "test_dynamic_partition_policy"
+
+    if (check_storage_policy_exist(policy_name)) {
+        sql """
+            DROP STORAGE POLICY ${policy_name}
+        """
+    }
+
+    def has_resouce = sql """
+        SHOW RESOURCES WHERE NAME = "${resource_name}";
+    """
+    if (has_resouce.size() > 0) {
+        sql """
+            DROP RESOURCE IF EXISTS ${resource_name}
+        """
+    }
+
+    sql """
+        CREATE RESOURCE IF NOT EXISTS "${resource_name}"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="${getHdfsFs()}",
+            "hadoop.username"="${getHdfsUser()}",
+            "hadoop.password"="${getHdfsPasswd()}",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS ${policy_name}
+        PROPERTIES(
+            "storage_resource" = "${resource_name}",
+            "cooldown_ttl" = "300"
+        )
+    """
+
+    // test one replica
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    sql """
+            CREATE TABLE ${tableName} (
+            `k1` int,
+            `k2` date
+            )
+            PARTITION BY RANGE(k2)()
+            DISTRIBUTED BY HASH(k1) BUCKETS 1
+            PROPERTIES
+            (
+            "dynamic_partition.enable" = "true",
+            "dynamic_partition.time_unit" = "DAY",
+            "dynamic_partition.end" = "3",
+            "dynamic_partition.prefix" = "p",
+            "dynamic_partition.buckets" = "1",
+            "dynamic_partition.replication_num" = "1",
+            "dynamic_partition.start" = "-3",
+            "storage_policy" = "${policy_name}",
+            "replication_num" = "1"
+            );
+        """
+    LocalDate currentDate = LocalDate.now();
+    LocalDate currentDatePlusOne = currentDate.plusDays(1);
+    LocalDate currentDatePlusTwo = currentDate.plusDays(2);
+    LocalDate currentDatePlusThree = currentDate.plusDays(3);
+    sql """
+        insert into ${tableName} values(1, "${currentDate.toString()}");
+    """
+    sql """
+        insert into ${tableName} values(1, "${currentDatePlusOne.toString()}");
+    """
+    sql """
+        insert into ${tableName} values(1, "${currentDatePlusTwo.toString()}");
+    """
+    sql """
+        insert into ${tableName} values(1, "${currentDatePlusThree.toString()}");
+    """
+
+    // show tablets from table, 获取第一个tablet的 LocalDataSize1
+    def tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+    def LocalDataSize1 = sizes[0]
+    def RemoteDataSize1 = sizes[1]
+    log.info( "test local size {} not zero, remote size {}", LocalDataSize1, RemoteDataSize1)
+    assertTrue(LocalDataSize1 != 0)
+    log.info( "test remote size is zero")
+    assertEquals(RemoteDataSize1, 0)
+    def originLocalDataSize1 = LocalDataSize1;
+
+    // 等待10min,show tablets from table, 预期not_use_storage_policy_tablet_list 的 RemoteDataSize 为0,LocalDataSize不为0
+    sleep(600000)
+
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    assertTrue(tablets.size() > 0)
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    Long sleepTimes = 0;
+    while (RemoteDataSize1 != originLocalDataSize1 && sleepTimes < 60) {
+        log.info( "test remote size is same with origin size, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM
+        """
+        fetchDataSize(sizes, tablets[0])
+        LocalDataSize1 = sizes[0]
+        RemoteDataSize1 = sizes[1]
+        sleepTimes += 1
+    }
+    log.info( "test local size is  zero")
+    assertEquals(LocalDataSize1, 0)
+    log.info( "test remote size not zero")
+    assertEquals(RemoteDataSize1, originLocalDataSize1)
+
+    // 12列是storage policy
+    def partitions = sql "show partitions from ${tableName}"
+    for (par in partitions) {
+        assertTrue(par[12] == "${policy_name}")
+    }
+
+    try_sql """
+    drop storage policy tmp_policy;
+    """
+
+    try_sql """
+    drop resource tmp_resource;
+    """
+
+    sql """
+        CREATE RESOURCE IF NOT EXISTS "tmp_resource"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="${getHdfsFs()}",
+            "hadoop.username"="${getHdfsUser()}",
+            "hadoop.password"="${getHdfsPasswd()}",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+
+    try_sql """
+    create storage policy tmp_policy
+    PROPERTIES( "storage_resource" = "tmp_resource", "cooldown_ttl" = "300");
+    """
+
+    // can not set to one policy with different resource
+    try {
+        sql """alter table ${tableName} set ("storage_policy" = "tmp_policy");"""
+    } catch (java.sql.SQLException t) {
+        assertTrue(true)
+    }
+
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS tmp_policy1
+        PROPERTIES(
+            "storage_resource" = "${resource_name}",
+            "cooldown_ttl" = "60"
+        )
+    """
+
+    sql """alter table ${tableName} set ("storage_policy" = "tmp_policy1");"""
+
+    // wait for report
+    sleep(300000)
+
+    partitions = sql "show partitions from ${tableName}"
+    for (par in partitions) {
+        assertTrue(par[12] == "tmp_policy1")
+    }
+
+    sql """
+    select * from ${tableName}
+    """
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+    sql """
+    drop storage policy tmp_policy;
+    """
+
+    sql """
+    drop storage policy tmp_policy1;
+    """
+
+    sql """
+    drop resource tmp_resource;
+    """
+
+
+
+}
diff --git a/regression-test/suites/cold_heat_separation_p2/create_table_use_partition_policy_by_hdfs.groovy b/regression-test/suites/cold_heat_separation_p2/create_table_use_partition_policy_by_hdfs.groovy
new file mode 100644
index 00000000000..723f50721ec
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation_p2/create_table_use_partition_policy_by_hdfs.groovy
@@ -0,0 +1,370 @@
+// 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.
+import groovy.json.JsonSlurper
+import org.codehaus.groovy.runtime.IOGroovyMethods
+
+suite("create_table_use_partition_policy_by_hdfs") {
+    def fetchBeHttp = { check_func, meta_url ->
+        def i = meta_url.indexOf("/api")
+        String endPoint = meta_url.substring(0, i)
+        String metaUri = meta_url.substring(i)
+        i = endPoint.lastIndexOf('/')
+        endPoint = endPoint.substring(i + 1)
+        httpTest {
+            endpoint endPoint
+            uri metaUri
+            op "get"
+            check check_func
+        }
+    }
+    // data_sizes is one arrayList<Long>, t is tablet
+    def fetchDataSize = { data_sizes, t ->
+        def tabletId = t[0]
+        String meta_url = t[17]
+        def clos = {  respCode, body ->
+            assertEquals("${respCode}".toString(), "200")
+            String out = "${body}".toString()
+            logger.info("test ttl expired resp Code {}, body {}", "${respCode}".toString(), out)
+            def obj = new JsonSlurper().parseText(out)
+            data_sizes[0] = obj.local_data_size
+            data_sizes[1] = obj.remote_data_size
+        }
+        fetchBeHttp(clos, meta_url.replace("header", "data_size"))
+    }
+    // used as passing out parameter to fetchDataSize
+    List<Long> sizes = [-1, -1]
+    def tableName = "lineitem1"
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    def stream_load_one_part = { partnum ->
+        streamLoad {
+            table tableName
+            // a default db 'regression_test' is specified in
+            // ${DORIS_HOME}/conf/regression-conf.groovy
+
+            // default label is UUID:
+            // set 'label' UUID.randomUUID().toString()
+
+            // default column_separator is specify in doris fe config, usually is '\t'.
+            // this line change to ','
+            set 'column_separator', '|'
+            set 'compress_type', 'GZ'
+
+
+            // relate to ${DORIS_HOME}/regression-test/data/demo/streamload_input.csv.
+            // also, you can stream load a http stream, e.g. http://xxx/some.csv
+            file """${getS3Url()}/regression/tpch/sf1/lineitem.csv.split${partnum}.gz"""
+
+            time 10000 // limit inflight 10s
+
+            // stream load action will check result, include Success status, and NumberTotalRows == NumberLoadedRows
+
+            // if declared a check callback, the default check condition will ignore.
+            // So you must check all condition
+            check { result, exception, startTime, endTime ->
+                if (exception != null) {
+                    throw exception
+                }
+                log.info("Stream load result: ${result}".toString())
+                def json = parseJson(result)
+                assertEquals("success", json.Status.toLowerCase())
+                assertEquals(json.NumberTotalRows, json.NumberLoadedRows)
+                assertTrue(json.NumberLoadedRows > 0 && json.LoadBytes > 0)
+            }
+        }
+    }
+
+    def load_lineitem_table = {
+        stream_load_one_part("00")
+        stream_load_one_part("01")
+        def tablets = sql """
+        SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+        """
+        while (tablets[0][8] == "0") {
+            log.info( "test local size is zero, sleep 10s")
+            sleep(10000)
+            tablets = sql """
+            SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+            """
+        }
+    }
+
+    def check_storage_policy_exist = { name->
+        def polices = sql"""
+        show storage policy;
+        """
+        for (p in polices) {
+            if (name == p[0]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def resource_name = "test_table_partition_with_data_resource"
+    def policy_name= "test_table_partition_with_data_policy"
+
+    if (check_storage_policy_exist(policy_name)) {
+        sql """
+            DROP STORAGE POLICY ${policy_name}
+        """
+    }
+
+    def has_resouce = sql """
+        SHOW RESOURCES WHERE NAME = "${resource_name}";
+    """
+    if (has_resouce.size() > 0) {
+        sql """
+            DROP RESOURCE ${resource_name}
+        """
+    }
+
+    sql """
+        CREATE RESOURCE IF NOT EXISTS "${resource_name}"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="${getHdfsFs()}",
+            "hadoop.username"="${getHdfsUser()}",
+            "hadoop.password"="${getHdfsPasswd()}",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS ${policy_name}
+        PROPERTIES(
+            "storage_resource" = "${resource_name}",
+            "cooldown_ttl" = "300"
+        )
+    """
+
+    // test one replica
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            PARTITION BY RANGE(`L_SHIPDATE`)
+            (
+                PARTITION `p202301` VALUES LESS THAN ("1995-12-01") ("storage_policy" = "${policy_name}"),
+                PARTITION `p202302` VALUES LESS THAN ("2017-03-01")
+            )
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "replication_num" = "1"
+            )
+        """
+
+    load_lineitem_table()
+    // sleep(30000);
+
+    // show tablets from table, 获取第一个tablet的 LocalDataSize1
+    def tablets = sql """
+    SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+    def LocalDataSize1 = sizes[0]
+    def RemoteDataSize1 = sizes[1]
+    log.info( "test local size {} not zero, remote size {}", LocalDataSize1, RemoteDataSize1)
+    assertTrue(LocalDataSize1 != 0)
+    log.info( "test remote size is zero")
+    assertEquals(RemoteDataSize1, 0)
+    def originLocalDataSize1 = LocalDataSize1;
+
+    // 等待10min,show tablets from table, 预期not_use_storage_policy_tablet_list 的 RemoteDataSize 为0,LocalDataSize不为0
+    sleep(600000)
+
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    assertTrue(tablets.size() > 0)
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    Long sleepTimes = 0;
+    while (RemoteDataSize1 != originLocalDataSize1 && sleepTimes < 60) {
+        log.info( "test remote size is same with origin size, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+        """
+        fetchDataSize(sizes, tablets[0])
+        LocalDataSize1 = sizes[0]
+        RemoteDataSize1 = sizes[1]
+        sleepTimes += 1
+    }
+    log.info( "test local size is  zero")
+    assertEquals(LocalDataSize1, 0)
+    log.info( "test remote size not zero")
+    assertEquals(RemoteDataSize1, originLocalDataSize1)
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName} PARTITIONS(p202302)
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    log.info( "test local size is not zero")
+    assertTrue(LocalDataSize1 != 0)
+    log.info( "test remote size is zero")
+    assertEquals(RemoteDataSize1, 0)
+
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+    // test table with 3 replication
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            PARTITION BY RANGE(`L_SHIPDATE`)
+            (
+                PARTITION `p202301` VALUES LESS THAN ("1995-12-01") ("storage_policy" = "${policy_name}"),
+                PARTITION `p202302` VALUES LESS THAN ("2017-03-01")
+            )
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "replication_num" = "3"
+            )
+        """
+
+    load_lineitem_table()
+
+    // show tablets from table, 获取第一个tablet的 LocalDataSize1
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    assertTrue(tablets.size() > 0)
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    log.info( "test local size not zero")
+    assertTrue(LocalDataSize1 != 0)
+    log.info( "test remote size is zero")
+    assertEquals(RemoteDataSize1, 0)
+    originLocalDataSize1 = LocalDataSize1
+
+    // 等待10min,show tablets from table, 预期not_use_storage_policy_tablet_list 的 RemoteDataSize 为0,LocalDataSize不为0
+    sleep(600000)
+
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    assertTrue(tablets.size() > 0)
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    sleepTimes = 0
+    while (RemoteDataSize1 != originLocalDataSize1 && sleepTimes < 60) {
+        log.info( "test remote size is same with origin size, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName} PARTITIONS(p202301)
+        """
+        fetchDataSize(sizes, tablets[0])
+        LocalDataSize1 = sizes[0]
+        RemoteDataSize1 = sizes[1]
+        sleepTimes += 1
+    }
+    log.info( "test local size is zero")
+    assertEquals(LocalDataSize1, 0)
+    log.info( "test remote size not zero")
+    assertEquals(RemoteDataSize1, originLocalDataSize1)
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName} PARTITIONS(p202302)
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    assertTrue(tablets.size() > 0)
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    log.info( "test local size is not zero")
+    assertTrue(LocalDataSize1 != 0)
+    log.info( "test remote size is zero")
+    assertEquals(RemoteDataSize1, 0)
+
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+
+
+}
diff --git a/regression-test/suites/cold_heat_separation_p2/create_table_use_policy_by_hdfs.groovy b/regression-test/suites/cold_heat_separation_p2/create_table_use_policy_by_hdfs.groovy
new file mode 100644
index 00000000000..c80f82a167d
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation_p2/create_table_use_policy_by_hdfs.groovy
@@ -0,0 +1,294 @@
+// 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.
+import groovy.json.JsonSlurper
+import org.codehaus.groovy.runtime.IOGroovyMethods
+
+suite("create_table_use_policy_by_hdfs") {
+    def fetchBeHttp = { check_func, meta_url ->
+        def i = meta_url.indexOf("/api")
+        String endPoint = meta_url.substring(0, i)
+        String metaUri = meta_url.substring(i)
+        i = endPoint.lastIndexOf('/')
+        endPoint = endPoint.substring(i + 1)
+        httpTest {
+            endpoint endPoint
+            uri metaUri
+            op "get"
+            check check_func
+        }
+    }
+    // data_sizes is one arrayList<Long>, t is tablet
+    def fetchDataSize = { data_sizes, t ->
+        def tabletId = t[0]
+        String meta_url = t[17]
+        def clos = {  respCode, body ->
+            logger.info("test ttl expired resp Code {}", "${respCode}".toString())
+            assertEquals("${respCode}".toString(), "200")
+            String out = "${body}".toString()
+            def obj = new JsonSlurper().parseText(out)
+            data_sizes[0] = obj.local_data_size
+            data_sizes[1] = obj.remote_data_size
+        }
+        fetchBeHttp(clos, meta_url.replace("header", "data_size"))
+    }
+    // used as passing out parameter to fetchDataSize
+    List<Long> sizes = [-1, -1]
+    def tableName = "lineitem2"
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    def stream_load_one_part = { partnum ->
+        streamLoad {
+            table tableName
+            // a default db 'regression_test' is specified in
+            // ${DORIS_HOME}/conf/regression-conf.groovy
+
+            // default label is UUID:
+            // set 'label' UUID.randomUUID().toString()
+
+            // default column_separator is specify in doris fe config, usually is '\t'.
+            // this line change to ','
+            set 'column_separator', '|'
+            set 'compress_type', 'GZ'
+
+
+            // relate to ${DORIS_HOME}/regression-test/data/demo/streamload_input.csv.
+            // also, you can stream load a http stream, e.g. http://xxx/some.csv
+            file """${getS3Url()}/regression/tpch/sf1/lineitem.csv.split${partnum}.gz"""
+
+            time 10000 // limit inflight 10s
+
+            // stream load action will check result, include Success status, and NumberTotalRows == NumberLoadedRows
+
+            // if declared a check callback, the default check condition will ignore.
+            // So you must check all condition
+            check { result, exception, startTime, endTime ->
+                if (exception != null) {
+                    throw exception
+                }
+                log.info("Stream load result: ${result}".toString())
+                def json = parseJson(result)
+                assertEquals("success", json.Status.toLowerCase())
+                assertEquals(json.NumberTotalRows, json.NumberLoadedRows)
+                assertTrue(json.NumberLoadedRows > 0 && json.LoadBytes > 0)
+            }
+        }
+    }
+
+    def load_lineitem_table = {
+        stream_load_one_part("00")
+        stream_load_one_part("01")
+        def tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        while (tablets[0][8] == "0") {
+            log.info( "test local size is zero, sleep 10s")
+            sleep(10000)
+            tablets = sql """
+            SHOW TABLETS FROM ${tableName}
+            """
+        }
+    }
+
+    def check_storage_policy_exist = { name->
+        def polices = sql"""
+        show storage policy;
+        """
+        for (p in polices) {
+            if (name == p[0]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def resource_name = "test_table_with_data_resource"
+    def policy_name= "test_table_with_data_policy"
+
+    if (check_storage_policy_exist(policy_name)) {
+        sql """
+            DROP STORAGE POLICY ${policy_name}
+        """
+    }
+
+    def has_resouce = sql """
+        SHOW RESOURCES WHERE NAME = "${resource_name}";
+    """
+    if (has_resouce.size() > 0) {
+        sql """
+            DROP RESOURCE ${resource_name}
+        """
+    }
+
+    sql """
+        CREATE RESOURCE IF NOT EXISTS "${resource_name}"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="${getHdfsFs()}",
+            "hadoop.username"="${getHdfsUser()}",
+            "hadoop.password"="${getHdfsPasswd()}",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS ${policy_name}
+        PROPERTIES(
+            "storage_resource" = "${resource_name}",
+            "cooldown_ttl" = "300"
+        )
+    """
+
+    // test one replica
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "replication_num" = "1",
+            "storage_policy" = "${policy_name}"
+            )
+        """
+
+    load_lineitem_table()
+
+    // show tablets from table, 获取第一个tablet的 LocalDataSize1
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+    def LocalDataSize1 = sizes[0]
+
+    // 等待10min,show tablets from table, 预期RemoteDataSize 不为0,且等于LocalDataSize1,预期LocalDataSize 为0
+    sleep(600000)
+
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    assertTrue(tablets.size() > 0)
+    log.info( "test remote size not zero")
+    assertEquals(LocalDataSize1, sizes[1])
+    log.info( "test local size is zero")
+    assertEquals(0, sizes[0])
+
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+    // test table with 3 replication
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "replication_num" = "3",
+            "storage_policy" = "${policy_name}"
+            )
+        """
+
+    load_lineitem_table()
+
+    // show tablets from table, 获取第一个tablet的 LocalDataSize1
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    LocalDataSize1 = sizes[0]
+
+    // 等待10min,show tablets from table, 预期RemoteDataSize 不为0,且等于LocalDataSize1,预期LocalDataSize 为0
+    sleep(600000)
+
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    assertTrue(tablets.size() > 0)
+    log.info( "test remote size not zero")
+    assertEquals(LocalDataSize1, sizes[1])
+    log.info( "test local size is zero")
+    assertEquals(0, sizes[0])
+
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+
+
+}
diff --git a/regression-test/suites/cold_heat_separation_p2/modify_replica_use_partition_by_hdfs.groovy b/regression-test/suites/cold_heat_separation_p2/modify_replica_use_partition_by_hdfs.groovy
new file mode 100644
index 00000000000..b1371788de4
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation_p2/modify_replica_use_partition_by_hdfs.groovy
@@ -0,0 +1,506 @@
+// 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.
+import groovy.json.JsonSlurper
+import org.codehaus.groovy.runtime.IOGroovyMethods
+
+suite("modify_replica_use_partition_by_hdfs") {
+    def fetchBeHttp = { check_func, meta_url ->
+        def i = meta_url.indexOf("/api")
+        String endPoint = meta_url.substring(0, i)
+        String metaUri = meta_url.substring(i)
+        i = endPoint.lastIndexOf('/')
+        endPoint = endPoint.substring(i + 1)
+        httpTest {
+            endpoint endPoint
+            uri metaUri
+            op "get"
+            check check_func
+        }
+    }
+    // data_sizes is one arrayList<Long>, t is tablet
+    def fetchDataSize = { data_sizes, t ->
+        def tabletId = t[0]
+        String meta_url = t[17]
+        def clos = {  respCode, body ->
+            logger.info("test ttl expired resp Code {}", "${respCode}".toString())
+            assertEquals("${respCode}".toString(), "200")
+            String out = "${body}".toString()
+            def obj = new JsonSlurper().parseText(out)
+            data_sizes[0] = obj.local_data_size
+            data_sizes[1] = obj.remote_data_size
+        }
+        fetchBeHttp(clos, meta_url.replace("header", "data_size"))
+    }
+    // used as passing out parameter to fetchDataSize
+    List<Long> sizes = [-1, -1]
+    def get_meta = { url ->
+        StringBuilder sb = new StringBuilder();
+        sb.append("curl ")
+        sb.append(url)
+        String command = sb.toString()
+        log.info(command)
+        def process = command.execute()
+        int code = process.waitFor()
+        def err = IOGroovyMethods.getText(new BufferedReader(new InputStreamReader(process.getErrorStream())));
+        def out = process.getText()
+        logger.info("Run compaction: code=" + code + ", err=" + err)
+        assertEquals(code, 0)
+        return out
+    }
+
+    def tableName = "lineitem3"
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    def stream_load_one_part = { partnum ->
+        streamLoad {
+            table tableName
+            // a default db 'regression_test' is specified in
+            // ${DORIS_HOME}/conf/regression-conf.groovy
+
+            // default label is UUID:
+            // set 'label' UUID.randomUUID().toString()
+
+            // default column_separator is specify in doris fe config, usually is '\t'.
+            // this line change to ','
+            set 'column_separator', '|'
+            set 'compress_type', 'GZ'
+
+
+            // relate to ${DORIS_HOME}/regression-test/data/demo/streamload_input.csv.
+            // also, you can stream load a http stream, e.g. http://xxx/some.csv
+            file """${getS3Url()}/regression/tpch/sf1/lineitem.csv.split${partnum}.gz"""
+
+            time 10000 // limit inflight 10s
+
+            // stream load action will check result, include Success status, and NumberTotalRows == NumberLoadedRows
+
+            // if declared a check callback, the default check condition will ignore.
+            // So you must check all condition
+            check { result, exception, startTime, endTime ->
+                if (exception != null) {
+                    throw exception
+                }
+                log.info("Stream load result: ${result}".toString())
+                def json = parseJson(result)
+                assertEquals("success", json.Status.toLowerCase())
+                assertEquals(json.NumberTotalRows, json.NumberLoadedRows)
+                assertTrue(json.NumberLoadedRows > 0 && json.LoadBytes > 0)
+            }
+        }
+    }
+
+    def load_lineitem_table = {
+        stream_load_one_part("00")
+        stream_load_one_part("01")
+        def tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        while (tablets[0][8] == "0") {
+            log.info( "test local size is zero, sleep 10s")
+            sleep(10000)
+            tablets = sql """
+            SHOW TABLETS FROM ${tableName}
+            """
+        }
+    }
+
+    def check_storage_policy_exist = { name->
+        def polices = sql"""
+        show storage policy;
+        """
+        for (p in polices) {
+            if (name == p[0]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def resource_name = "test_table_replica_with_data_resource"
+    def policy_name= "test_table_replica_with_data_policy"
+
+    if (check_storage_policy_exist(policy_name)) {
+        sql """
+            DROP STORAGE POLICY ${policy_name}
+        """
+    }
+
+    def has_resouce = sql """
+        SHOW RESOURCES WHERE NAME = "${resource_name}";
+    """
+    if (has_resouce.size() > 0) {
+        sql """
+            DROP RESOURCE ${resource_name}
+        """
+    }
+
+    sql """
+        CREATE RESOURCE IF NOT EXISTS "${resource_name}"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="${getHdfsFs()}",
+            "hadoop.username"="${getHdfsUser()}",
+            "hadoop.password"="${getHdfsPasswd()}",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS ${policy_name}
+        PROPERTIES(
+            "storage_resource" = "${resource_name}",
+            "cooldown_ttl" = "300"
+        )
+    """
+
+    // test one replica then we will alter all the replica of all partitions to 3
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            PARTITION BY RANGE(`L_SHIPDATE`)
+            (
+                PARTITION `p202301` VALUES LESS THAN ("1995-12-01"),
+                PARTITION `p202302` VALUES LESS THAN ("2017-03-01")
+            )
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "storage_policy" = "${policy_name}",
+            "replication_num" = "1"
+            )
+        """
+
+    load_lineitem_table()
+
+    // 等待10min,show tablets from table, 预期not_use_storage_policy_tablet_list 的 RemoteDataSize 为LocalDataSize1,LocalDataSize为0
+    sleep(600000)
+
+
+    def tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    assertTrue(tablets.size() > 0)
+    def LocalDataSize1 = sizes[0]
+    def RemoteDataSize1 = sizes[1]
+    log.info( "test local size is zero")
+    assertEquals(LocalDataSize1, 0)
+    log.info( "test remote size not zero")
+    assertTrue(RemoteDataSize1 != 0)
+    def originSize = tablets.size()
+
+    // alter change replication num
+    sql """
+    ALTER TABLE ${tableName}
+    MODIFY PARTITION (p202301, p202302) SET("replication_num"="3");
+    """
+
+    sql """
+    select count(*) from ${tableName}
+    """
+
+    sql """
+    select * from ${tableName} limit 10
+    """
+    // wait one minute for migration to be completed
+    sleep(60000)
+
+    // 对比所有tablets的replicas的rowsets meta是否相同
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    while (tablets.size() != 3 * originSize) {
+        log.info( "tablets clone not finished, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+    }
+    def compactionStatusIdx = tablets[0].size() - 1
+    // check rowsets inside the 3 replica
+    def iterate_num = tablets.size() / 3;
+    for (int i = 0; i < iterate_num; i++) {
+        int idx = i * 3;
+        def dst = tablets[idx][18]
+        def text = get_meta(dst)
+        def obj = new JsonSlurper().parseText(text)
+        def rowsets = obj.rowsets
+        for (x in [1,2]) {
+            dst = tablets[idx + x][18]
+            text = get_meta(dst)
+            obj = new JsonSlurper().parseText(text)
+            log.info( "test rowset meta is the same")
+            assertEquals(rowsets, obj.rowsets)
+        }
+    }
+
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+    // test table with 3 replication, then we will alter all the replica of all partitions to 1
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            PARTITION BY RANGE(`L_SHIPDATE`)
+            (
+                PARTITION `p202301` VALUES LESS THAN ("1995-12-01"),
+                PARTITION `p202302` VALUES LESS THAN ("2017-03-01")
+            )
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "storage_policy" = "${policy_name}",
+            "replication_num" = "3"
+            )
+        """
+
+    load_lineitem_table()
+
+    // show tablets from table, 获取第一个tablet的 LocalDataSize1
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    fetchDataSize(sizes, tablets[0])
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    log.info( "test local size not zero")
+    assertTrue(LocalDataSize1 != 0)
+    log.info( "test remote size is zero")
+    assertEquals(RemoteDataSize1, 0)
+
+    // 等待10min,show tablets from table, 预期not_use_storage_policy_tablet_list 的 RemoteDataSize 为LocalDataSize1,LocalDataSize为0
+    sleep(600000)
+
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    log.info( "test local size is zero")
+    assertEquals(LocalDataSize1, 0)
+    log.info( "test remote size not zero")
+    assertTrue(RemoteDataSize1 != 0)
+
+    // alter change replication num
+    sql """
+    ALTER TABLE ${tableName}
+    MODIFY PARTITION (p202301, p202302) SET("replication_num"="1");
+    """
+
+    sql """
+    select count(*) from ${tableName}
+    """
+
+    sql """
+    select * from ${tableName} limit 10
+    """
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+
+    // test table with one partition p1 3 replication and another p2 with 1 replication,
+    // then we will alter p1 to one replica and p2 to 3
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            PARTITION BY RANGE(`L_SHIPDATE`)
+            (
+                PARTITION `p202301` VALUES LESS THAN ("1995-12-01") ("replication_num" = "3"),
+                PARTITION `p202302` VALUES LESS THAN ("2017-03-01") ("replication_num" = "1")
+            )
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "storage_policy" = "${policy_name}"
+            )
+        """
+
+    load_lineitem_table()
+
+    // show tablets from table, 获取第一个tablet的 LocalDataSize1
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    fetchDataSize(sizes, tablets[0])
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    log.info( "test local size not zero")
+    assertTrue(LocalDataSize1 != 0)
+    log.info( "test remote size is zero")
+    assertEquals(RemoteDataSize1, 0)
+
+    // 等待10min,show tablets from table, 预期not_use_storage_policy_tablet_list 的 RemoteDataSize 为LocalDataSize1,LocalDataSize为0
+    sleep(600000)
+
+
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+    while (sizes[1] == 0) {
+        log.info( "test remote size is zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+    }
+    LocalDataSize1 = sizes[0]
+    RemoteDataSize1 = sizes[1]
+    log.info( "test local size is zero")
+    assertEquals(LocalDataSize1, 0)
+    log.info( "test remote size not zero")
+    assertTrue(RemoteDataSize1 != 0)
+
+    // alter change replication num
+    sql """
+    ALTER TABLE ${tableName}
+    MODIFY PARTITION (p202301) SET("replication_num"="1");
+    """
+
+    sql """
+    ALTER TABLE ${tableName}
+    MODIFY PARTITION (p202302) SET("replication_num"="3");
+    """
+
+    sql """
+    select count(*) from ${tableName}
+    """
+
+    sql """
+    select * from ${tableName} limit 10
+    """
+
+    // wait one minute for migration to be completed
+    sleep(60000)
+    // 对比3副本的partition中所有tablets的replicas的rowsets meta是否相同
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName} PARTITIONS(p202302)
+    """
+    // sleep to wait for the report
+    sleep(15000)
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName} PARTITIONS(p202302)
+    """
+    compactionStatusIdx = tablets[0].size() - 1
+    // check rowsets inside the 3 replica
+    iterate_num = tablets.size() / 3;
+    for (int i = 0; i < iterate_num; i++) {
+        int idx = i * 3;
+        def dst = tablets[idx][18]
+        def text = get_meta(dst)
+        def obj = new JsonSlurper().parseText(text)
+        def rowsets = obj.rowsets
+        for (x in [1,2]) {
+            dst = tablets[idx + x][18]
+            text = get_meta(dst)
+            obj = new JsonSlurper().parseText(text)
+            log.info( "test rowset meta is the same")
+            assertEquals(rowsets, obj.rowsets)
+        }
+    }
+
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+
+}
diff --git a/regression-test/suites/cold_heat_separation_p2/table_modify_resouce_and_policy_by_hdfs.groovy b/regression-test/suites/cold_heat_separation_p2/table_modify_resouce_and_policy_by_hdfs.groovy
new file mode 100644
index 00000000000..2c3f2d18219
--- /dev/null
+++ b/regression-test/suites/cold_heat_separation_p2/table_modify_resouce_and_policy_by_hdfs.groovy
@@ -0,0 +1,326 @@
+// 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.
+import groovy.json.JsonSlurper
+import org.codehaus.groovy.runtime.IOGroovyMethods
+
+suite("table_modify_resouce_by_hdfs") {
+    def fetchBeHttp = { check_func, meta_url ->
+        def i = meta_url.indexOf("/api")
+        String endPoint = meta_url.substring(0, i)
+        String metaUri = meta_url.substring(i)
+        i = endPoint.lastIndexOf('/')
+        endPoint = endPoint.substring(i + 1)
+        httpTest {
+            endpoint endPoint
+            uri metaUri
+            op "get"
+            check check_func
+        }
+    }
+    // data_sizes is one arrayList<Long>, t is tablet
+    def fetchDataSize = { data_sizes, t ->
+        def tabletId = t[0]
+        String meta_url = t[17]
+        def clos = {  respCode, body ->
+            logger.info("test ttl expired resp Code {}", "${respCode}".toString())
+            assertEquals("${respCode}".toString(), "200")
+            String out = "${body}".toString()
+            def obj = new JsonSlurper().parseText(out)
+            data_sizes[0] = obj.local_data_size
+            data_sizes[1] = obj.remote_data_size
+        }
+        fetchBeHttp(clos, meta_url.replace("header", "data_size"))
+    }
+    // used as passing out parameter to fetchDataSize
+    List<Long> sizes = [-1, -1]
+    def tableName = "lineitem4"
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    def stream_load_one_part = { partnum ->
+        streamLoad {
+            table tableName
+            // a default db 'regression_test' is specified in
+            // ${DORIS_HOME}/conf/regression-conf.groovy
+
+            // default label is UUID:
+            // set 'label' UUID.randomUUID().toString()
+
+            // default column_separator is specify in doris fe config, usually is '\t'.
+            // this line change to ','
+            set 'column_separator', '|'
+            set 'compress_type', 'GZ'
+
+
+            // relate to ${DORIS_HOME}/regression-test/data/demo/streamload_input.csv.
+            // also, you can stream load a http stream, e.g. http://xxx/some.csv
+            file """${getS3Url()}/regression/tpch/sf1/lineitem.csv.split${partnum}.gz"""
+
+            time 10000 // limit inflight 10s
+
+            // stream load action will check result, include Success status, and NumberTotalRows == NumberLoadedRows
+
+            // if declared a check callback, the default check condition will ignore.
+            // So you must check all condition
+            check { result, exception, startTime, endTime ->
+                if (exception != null) {
+                    throw exception
+                }
+                log.info("Stream load result: ${result}".toString())
+                def json = parseJson(result)
+                assertEquals("success", json.Status.toLowerCase())
+                assertEquals(json.NumberTotalRows, json.NumberLoadedRows)
+                assertTrue(json.NumberLoadedRows > 0 && json.LoadBytes > 0)
+            }
+        }
+    }
+
+    def load_lineitem_table = {
+        stream_load_one_part("00")
+        stream_load_one_part("01")
+        def tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        while (tablets[0][8] == "0") {
+            log.info( "test local size is zero, sleep 10s")
+            sleep(10000)
+            tablets = sql """
+            SHOW TABLETS FROM ${tableName}
+            """
+        }
+    }
+
+    def check_storage_policy_exist = { name->
+        def polices = sql"""
+        show storage policy;
+        """
+        for (p in polices) {
+            if (name == p[0]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    def resource_name = "test_table_with_data_resource_modify_1"
+    def policy_name= "test_table_with_data_policy_modify_1"
+
+    if (check_storage_policy_exist(policy_name)) {
+        sql """
+            DROP STORAGE POLICY ${policy_name}
+        """
+    }
+
+    def has_resouce = sql """
+        SHOW RESOURCES WHERE NAME = "${resource_name}";
+    """
+    if (has_resouce.size() > 0) {
+        sql """
+            DROP RESOURCE ${resource_name}
+        """
+    }
+
+    sql """
+        CREATE RESOURCE IF NOT EXISTS "${resource_name}"
+        PROPERTIES(
+            "type"="hdfs",
+            "fs.defaultFS"="${getHdfsFs()}",
+            "hadoop.username"="${getHdfsUser()}",
+            "hadoop.password"="${getHdfsPasswd()}",
+            "dfs.nameservices" = "my_ha",
+            "dfs.ha.namenodes.my_ha" = "my_namenode1, my_namenode2",
+            "dfs.namenode.rpc-address.my_ha.my_namenode1" = "127.0.0.1:10000",
+            "dfs.namenode.rpc-address.my_ha.my_namenode2" = "127.0.0.1:10000",
+            "dfs.client.failover.proxy.provider" = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
+        );
+    """
+
+    sql """
+        CREATE STORAGE POLICY IF NOT EXISTS ${policy_name}
+        PROPERTIES(
+            "storage_resource" = "${resource_name}",
+            "cooldown_ttl" = "300"
+        )
+    """
+
+    // test one replica
+    sql """ DROP TABLE IF EXISTS ${tableName} """
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "replication_num" = "1",
+            "storage_policy" = "${policy_name}"
+            )
+        """
+
+    load_lineitem_table()
+
+    // 等待10分钟 获取remote data size
+    sleep(600000)
+    def tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+
+    def try_times = 100
+    while (sizes[0] != 0) {
+        log.info( "test local size is not zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+        try_times -= 1
+        assertTrue(try_times > 0)
+    }
+
+    // 修改resource和policy到新值然后查看remote data size是否能对上
+    sql """
+        ALTER STORAGE POLICY ${policy_name} PROPERTIES("cooldown_ttl" = "500");
+    """
+
+    sql """
+    select count(*) from ${tableName}
+    """
+
+    sql """
+    select max(L_SUPPKEY) from ${tableName}
+    """
+
+    sql """
+    select * from ${tableName} limit 10
+    """
+
+
+    def tablets2 = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    // [8] local data size, [9] remote data size
+    log.info( "test all remote size not zero")
+    for (int i = 0; i < tablets2.size(); i++) {
+        fetchDataSize(sizes, tablets2[i])
+        assertTrue(sizes[1] > 0)
+    }
+
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+    // test three replica
+    sql """
+            CREATE TABLE IF NOT EXISTS ${tableName} (
+            L_ORDERKEY    INTEGER NOT NULL,
+            L_PARTKEY     INTEGER NOT NULL,
+            L_SUPPKEY     INTEGER NOT NULL,
+            L_LINENUMBER  INTEGER NOT NULL,
+            L_QUANTITY    DECIMAL(15,2) NOT NULL,
+            L_EXTENDEDPRICE  DECIMAL(15,2) NOT NULL,
+            L_DISCOUNT    DECIMAL(15,2) NOT NULL,
+            L_TAX         DECIMAL(15,2) NOT NULL,
+            L_RETURNFLAG  CHAR(1) NOT NULL,
+            L_LINESTATUS  CHAR(1) NOT NULL,
+            L_SHIPDATE    DATE NOT NULL,
+            L_COMMITDATE  DATE NOT NULL,
+            L_RECEIPTDATE DATE NOT NULL,
+            L_SHIPINSTRUCT CHAR(25) NOT NULL,
+            L_SHIPMODE     CHAR(10) NOT NULL,
+            L_COMMENT      VARCHAR(44) NOT NULL
+            )
+            DUPLICATE KEY(L_ORDERKEY, L_PARTKEY, L_SUPPKEY, L_LINENUMBER)
+            DISTRIBUTED BY HASH(L_ORDERKEY) BUCKETS 3
+            PROPERTIES (
+            "replication_num" = "3",
+            "storage_policy" = "${policy_name}"
+            )
+        """
+
+    load_lineitem_table()
+
+    // 等待10分钟 获取remote data size
+    sleep(600000)
+    tablets = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    log.info( "test tablets not empty")
+    assertTrue(tablets.size() > 0)
+    fetchDataSize(sizes, tablets[0])
+    try_times = 100
+    while (sizes[0] != 0) {
+        log.info( "test local size is not zero, sleep 10s")
+        sleep(10000)
+        tablets = sql """
+        SHOW TABLETS FROM ${tableName}
+        """
+        fetchDataSize(sizes, tablets[0])
+        try_times -= 1
+        assertTrue(try_times > 0)
+    }
+
+    // 修改resource和policy到新值然后查看remote data size是否能对上
+    sql """
+        ALTER STORAGE POLICY ${policy_name} PROPERTIES("cooldown_ttl" = "500");
+    """
+
+    sql """
+    select count(*) from ${tableName}
+    """
+
+    sql """
+    select max(L_SUPPKEY) from ${tableName}
+    """
+
+    sql """
+    select * from ${tableName} limit 10
+    """
+
+
+    tablets2 = sql """
+    SHOW TABLETS FROM ${tableName}
+    """
+    // [8] local data size, [9] remote data size
+    log.info( "test all remote size not zero")
+    for (int i = 0; i < tablets2.size(); i++) {
+        fetchDataSize(sizes, tablets2[i])
+        assertTrue(sizes[1] > 0)
+    }
+
+
+    sql """
+    DROP TABLE ${tableName}
+    """
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org