
# 使用DWS冷热数据切换功能降低业务成本
#### 场景介绍
海量大数据场景下，随着业务和数据量的不断增长，数据存储与消耗的资源也日益增长。根据业务系统中用户对不同时期数据的不同使用需求，对膨胀的数据进行"冷热"分级管理，不仅可以提高数据分析性能还能降低业务成本。针对数据使用的典型场景，可以将数据按照时间分为：热数据、冷数据。
冷热数据主要从数据访问频率、更新频率进行划分。
- Hot（热数据）：访问、更新频率较高，对访问的响应时间要求很高的数据。
- Cold（冷数据）：不允许更新或更新频率较低，对访问的响应时间要求不高的数据。
用户可以定义冷热管理表，将符合规则的冷数据切换至OBS上进行存储，可以按照分区自动进行冷热数据的判断和迁移。
图1冷热数据管理   
![](https://support.huaweicloud.com/bestpractice-dws/figure/zh-cn_image_0000001445011109.png "点击放大")
DWS列存数据写入时，数据首先进入热分区进行存储，分区数据较多后，可通过手动或自动的方式，将符合冷数据规则的数据切换至OBS上进行存储。在数据切换至OBS上后，其元数据、Desc表信息以及索引信息仍在本地进行存储，保证了读取的性能。
冷热切换的策略名称支持LMT（last modify time）和HPN（hot partition number），LMT指按分区的最后更新时间切换，HPN指保留热分区的个数切换。
- LMT：表示切换\[day\]时间前修改的热分区数据为冷分区，将该数据迁至OBS表空间中。其中\[day\]为整型，范围\[0, 36500\]，单位为天。 如下图中，设置day为2，即在冷热切换时，根据分区数据的最晚修改时间，保留2日内所修改的分区为热分区，其余数据为冷分区数据。假设当前时间为4月30日，4月30日对\[4-26\]分区进行了delete操作，4月29日对\[4-27\]分区进行了insert操作，故在冷热切换时，保留\[4-26\]\[4-27\]\[4-29\]\[4-30\]四个分区为热分区。
  ![](https://support.huaweicloud.com/bestpractice-dws/figure/zh-cn_image_0000002076447485.png "点击放大")
  
- HPN：表示保留HPN个有数据的分区为热分区。分区顺序按照分区的Sequence ID来确定，分区的Sequence ID是根据分区边界值的大小，内置生成的序号，此序号不对外呈现。对于RANGE分区，分区的边界值越大，分区对应的Sequence ID越大；对于LIST分区，分区边界枚举值中的最大值越大，分区对应的Sequence ID越大。在冷热切换时，需要将数据迁移至OBS表空间中。其中HPN为整型，范围为\[0,1600\]。其中HPN为0时，表示不保留热分区，在进行冷热切换时，将所有有数据的分区都转为冷分区并存储在OBS上。 如下图中，设置HPN为3，即在冷热切换时，保留最新的3个有数据的分区为热分区数据，其余分区均切为冷分区。
  ![](https://support.huaweicloud.com/bestpractice-dws/figure/zh-cn_image_0000002076528885.png "点击放大")
  
#### 约束限制
- 支持对冷热表的insert、copy、delete、update、select等表相关的DML操作。
- 支持对冷热表的权限管理等DCL操作。
- 支持对冷热表进行analyze、vacuum、merge into等操作和一些分区的操作。
- 支持从普通列存分区表升级为冷热数据表。
- 支持带有冷热数据管理表的升级、扩容、缩容和重分布。
- 8.3.0及以上版本支持冷热分区互相转换，8.3.0版本之前仅支持从热数据切换为冷数据。

- 对于同时存在冷热分区的表，查询时会变慢，因为冷数据存储在OBS上，读写速度和时延都比在本地查询要慢。
- 目前冷热表只支持列存2.0版本的分区表，外表不支持冷热分区。
- 只支持修改冷热表的冷热切换策略，不支持修改冷热表的冷数据的表空间。
- 冷热表的分区操作约束：
  - 不支持对冷分区的数据进行exchange操作。
  
  - Merge partition分区只支持热分区和热分区合并、冷分区和冷分区合并，不支持冷热分区合并。
  
  - ADD/Merge/Split Partition等分区操作不支持指定表空间为OBS表空间。
  
  - 不支持创建时指定和修改冷热表分区的表空间。
   
- 冷热切换并非满足条件就立刻执行，依赖用户手动调用切换命令，或者通过调度器调用切换命令后才真正进行数据切换。目前自动调度时间为每日0点，可进行修改。
- 冷热数据表不支持物理细粒度备份和恢复，物理备份时只备份热数据，在备份恢复前后OBS上冷数据为同一份，不支持truncate和drop table等涉及删除文件操作语句的备份恢复操作。
 
#### 基本流程
本实践预计时长：30分钟，基本流程如下：
1. [创建集群]。
2. [使用gsql命令行客户端连接集群]。
3. [创建冷热表]。
4. [冷热数据切换]。
5. [查看冷热表数据分布]。
 
 #### 创建集群
1. 在[DWS控制台](https://console.huaweicloud.com/dws)上创建集群，具体操作步骤请参考[创建DWS存算一体集群](https://support.huaweicloud.com/mgtg-dws/dws_01_0019.html)。
 #### 使用gsql命令行客户端连接集群
1. 使用root用户远程登录到需要安装gsql的Linux主机，然后在Linux命令窗口，执行以下命令下载gsql客户端： 
   ```
   wget https://obs.cn-north-1.myhuaweicloud.com/dws/download/dws_client_8.1.x_redhat_x64.zip --no-check-certificate
   ```
   
   
2. 执行以下命令解压客户端工具。 
   ```
   cd <客户端存放路径> unzip dws_client_8.1.x_redhat_x64.zip
   ```
   其中：
   - \<客户端存放路径\>：请替换为实际的客户端存放路径。
   
   - dws_client_*8.1.x*_redhat_x64.zip：这是"RedHat x64"对应的客户端工具包名称，请替换为实际下载的包名。
   
   
   
   
3. 执行以下命令配置客户端。 
   ```
   source gsql_env.sh
   ```
   提示以下信息表示客户端已配置成功。
   ```
   All things done.
   ```
   
   
4. 执行以下命令，使用gsql客户端连接DWS集群中的数据库，其中password为用户创建集群时自定义的密码。 
   ```
   gsql -d gaussdb -p 8000 -h 192.168.0.86 -U dbadmin -W password -r
   ```
   显示如下信息表示gsql工具已经连接成功：
   ```
   gaussdb=>
   ```
   
   
 
 #### 创建冷热表
创建列存冷热数据管理表lifecycle_table，指定热数据有效期LMT为100天。
```
CREATE TABLE lifecycle_table(i int, val text) WITH (ORIENTATION = COLUMN, storage_policy = 'LMT:100')
PARTITION BY RANGE (i)
(
PARTITION P1 VALUES LESS THAN(5),
PARTITION P2 VALUES LESS THAN(10),
PARTITION P3 VALUES LESS THAN(15),
PARTITION P8 VALUES LESS THAN(MAXVALUE)
)
ENABLE ROW MOVEMENT;
```
 #### 冷热数据切换
将热分区数据切换成冷分区数据。
- 自动切换：每日0点调度框架自动触发，无需关注切换情况。 可使用函数pg_obs_cold_refresh_time(table_name, time)自定义自动切换时间。例如，根据业务情况调整自动触发时间为每天早晨6点30分。
  ```
  SELECT * FROM pg_obs_cold_refresh_time('lifecycle_table', '06:30:00');
  pg_obs_cold_refresh_time
  --------------------------
   SUCCESS
  (1 row)
  ```
  
- 手动切换。 使用ALTER TABLE语句手动切换单表：
  ```
  ALTER TABLE lifecycle_table refresh storage;
  ALTER TABLE
  ```
  使用函数pg_refresh_storage()批量切换所有冷热表：
  ```
  SELECT pg_catalog.pg_refresh_storage();
   pg_refresh_storage
  --------------------
   (1,0)
  (1 row)
  ```
  
 
将冷分区数据转换成热分区数据。该功能**仅8.3.0及以上版本支持**。
- 将冷热表的所有冷分区转换成热分区：
  ```
  SELECT pg_catalog.reload_cold_partition('lifecycle_table');
  ```
  
- 将冷热表的指定冷分区转换成热分区：
  ```
  SELECT pg_catalog.reload_cold_partition('lifecycle_table', 'cold_partition_name');
  ```
  
 #### 查看冷热表数据分布
- 查看单表数据分布情况。
  ```
  SELECT * FROM pg_catalog.pg_lifecycle_table_data_distribute('lifecycle_table');
  schemaname |    tablename    |   nodename   | hotpartition | coldpartition | switchablepartition | hotdatasize | colddatasize | switchabledatasize
  ------------+-----------------+--------------+--------------+---------------+---------------------+-------------+--------------+--------------------
   public     | lifecycle_table | dn_6001_6002 | p1,p2,p3,p8  |               |                     | 96 KB       | 0 bytes      | 0 bytes
   public     | lifecycle_table | dn_6003_6004 | p1,p2,p3,p8  |               |                     | 96 KB       | 0 bytes      | 0 bytes
   public     | lifecycle_table | dn_6005_6006 | p1,p2,p3,p8  |               |                     | 96 KB       | 0 bytes      | 0 bytes
  (3 rows)
  ```
  
- 查看所有冷热表数据分布情况。
  ```
  SELECT * FROM pg_catalog.pg_lifecycle_node_data_distribute();
  schemaname |    tablename    |   nodename   | hotpartition | coldpartition | switchablepartition | hotdatasize | colddatasize | switchabledatasize
  ------------+-----------------+--------------+--------------+---------------+---------------------+-------------+--------------+--------------------
   public     | lifecycle_table | dn_6001_6002 | p1,p2,p3,p8  |               |                     |       98304 |            0 |                  0
   public     | lifecycle_table | dn_6003_6004 | p1,p2,p3,p8  |               |                     |       98304 |            0 |                  0
   public     | lifecycle_table | dn_6005_6006 | p1,p2,p3,p8  |               |                     |       98304 |            0 |                  0
  (3 rows)
  ```
  
 
#### 查看冷热表大小
1. 查看某张表的冷数据，热数据的大小。 
   ```
   SELECT * FROM pg_lifecycle_table_data_distribute ('lifecycle_table');
   ```
   
   
2. 查看所有冷热表的冷数据、热数据的大小。 
   ```
   SELECT * FROM pg_lifecycle_node_data_distribute() ORDER BY tablename;
   ```
   
   
 
#### 删除冷热分区及分区数据
- 删除冷热表的指定分区数据：
  ```
  ALTER TABLE lifecycle_table TRUNCATE PARTITION P1;
  ```
  
- 删除冷热表的指定分区：
  ```
  ALTER TABLE lifecycle_table DROP PARTITION P2;
  ```
  
 
