# 配置Hive分区元数据冷热存储
#### Hive分区元数据冷热存储介绍
为了减轻集群元数据库压力，将长时间未使用过的指定范围的分区相关元数据移动到备份表，这一过程称为分区数据冻结，冻结的分区数据称为冷分区，未冻结的分区称为热分区，存在冷分区的表称为冻结表。将被冻结的数据重新移回原元数据表中，这一过程称为分区数据解冻。
一个分区从热分区变成冷分区，仅仅是在元数据中进行标识，其HDFS业务侧分区路径、数据文件内容并未发生变化。
#### 约束与限制
- 默认元数据库冻结分区类型只支持int、string、varchar、date、timestamp类型。
- 外置元数据库只支持PostgreSQL数据库，且冻结分区类型只支持int、string、varchar、timestamp类型。
- 对冻结后的表进行Msck元数据修复时，需要先解冻数据。如果对冻结表进行过备份后恢复操作，则可以直接执行Msck元数据修复操作，且解冻只能通过**msck repair**命令进行操作。
- 对冻结后的分区进行**rename**时，需要先解冻数据，否则会提示分区不存在。
- 删除存在冻结数据的表时，被冻结的数据会同步删除。
- 删除存在冻结数据的分区时，被冻结的分区信息不会被删除，HDFS业务数据也不会被删除。
- **select**查询数据时，会自动添加排查冷分区数据的过滤条件，查询结果将不包含冷分区的数据。
- **show partitions** *table* ;查询表下的分区数据时，查询结果将不包含冷分区，可通过**show frozen partitions** *table*;进行冻结分区查询。
 
#### 前提条件
- 已安装集群客户端，安装客户端具体操作请参见[安装客户端](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0089.html)。
- 已准备Hive组件业务用户，对应用户需具有创建Hive表的权限，例如，该用户属于"hive"、"hadoop"用户组，主组为"hive"。创建Hive用户具体操作请参见[创建Hive用户并绑定角色](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_0949.html#mrs_01_0949__section15172119027)。
 
#### 配置Hive分区元数据冷热存储
1. 以客户端安装用户，登录客户端所在的节点。
2. 执行以下命令，切换到客户端安装目录。 
   ```
   cd /opt/hadoopclient
   ```
   
   
3. 执行以下命令配置环境变量。 
   ```
   source bigdata_env
   ```
   
   
4. 执行以下命令认证用户，未启用Kerberos认证的用户请跳过此步骤： 
   ```
   kinit Hive组件业务用户
   ```
   
   
5. 执行以下命令登录Hive客户端： 
   ```
   beeline
   ```
   
   
6. 执行以下命令创建数据库，并切换至新创建的数据库中：
   
   1. 删除名为"test"的数据库及其所有相关对象：
      ```
      drop database if exists test cascade;
      ```
      
   
   2. 创建数据库：
      ```
      create database test;
      ```
      
   
   3. 切换至新创建的数据库中：
      ```
      use test;
      ```
      
   
   4. 创建1级和多级静态分区表并插入数据，例如"partition_1"、"partition_multi"。
      - 创建1级静态分区表"partition_1"，并插入数据。 创建分区表"partition_1"：
        ```
        CREATE TABLE partition_1 (st string, tt timestamp) partitioned by (dt timestamp)STORED AS parquet;
        ```
        插入数据：
        ```
        insert into table partition_1 partition(dt='2021-01-01 12:00:00') values('a1','2021-06-01 12:00:00');
        ```
        插入数据：
        ```
        insert into table partition_1 partition(dt='2021-02-01 12:00:00') values('a2','2021-07-01 12:00:00');
        ```
        查询分区数据：
        ```
        show partitions test.partition_1;
        ```
        查询到的分区数据为：
        ```
        +-----------------------------+
        |          partition          |
        +-----------------------------+
        | dt=2021-01-01 12%3A00%3A00  |
        | dt=2021-02-01 12%3A00%3A00  |
        +-----------------------------+
        ```
        
      
      - 创建多级静态分区表"partition_multi"，并插入数据。 创建分区表"partition_multi"：
        ```
        create table partition_multi (id int,name string) partitioned by (pt1 int , pt2 string, pt3 string, pt5 date) row format delimited fields terminated by ',' stored as sequencefile;
        ```
        插入数据：
        ```
        insert into table partition_multi partition(pt1=11,pt2='string1',pt3='abc@ABC',pt5='2021-01-01') values(1,'name1');
        ```
        插入数据：
        ```
        insert into table partition_multi partition(pt1=22,pt2='string2',pt3='HAPPY@happy',pt5='2021-02-01') values(2,'name2');
        ```
        查询分区数据：
        ```
        show partitions partition_multi;
        ```
        查询到的分区数据为：
        ```
        +----------------------------------------------------+
        |                     partition                      |
        +----------------------------------------------------+
        | pt1=11/pt2=string1/pt3=abc@ABC/pt5=2021-01-01      |
        | pt1=22/pt2=string2/pt3=HAPPY@happy/pt5=2021-02-01  |
        +----------------------------------------------------+
        ```
        
       
   
   
   
   
7. 冻结[6]创建的分区表。
   
   系统支持创建表的用户按照条件过滤的方式对一个或多个分区进行冻结，命令格式为：
   ```
   freeze partitions 数据库名称.表名称 where 分区过滤条件
   ```
   例如：
   - 冻结1级分区表"partition_1"：
     ```
     freeze partitions test.partition_1 where dt < '2021-02-01 12:00:00.0';
     ```
     
   
   - 冻结多级分区表"partition_multi"：
     ```
     freeze partitions test.partition_multi where pt1>11 and pt2<='string2' and pt3='HAPPY@happy' and pt5>'2021-01-01';
     ```
     
   
   
   
   
8. 查询Hive表分区数据。 
   - 查看1级表分区数据：
     ```
     show partitions test.partition_1;
     ```
     查询结果中，将不再包含冷分区的数据。
     ```
     +-----------------------------+
     |          partition          |
     +-----------------------------+
     | dt=2021-02-01 12%3A00%3A00  |
     +-----------------------------+
     ```
     
   
   - 查看多级表分区：
     ```
     show partitions test.partition_multi;
     ```
     查询结果中如下：
     ```
     +------------------------------------------------+
     |                   partition                    |
     +------------------------------------------------+
     | pt1=11/pt2=string1/pt3=abc@ABC/pt5=2021-01-01  |
     +------------------------------------------------+
     ```
     
   
   
   
   
9. 查询Hive表冻结分区的数据。 
   - 查询"partition_1"表的冻结分区：
     ```
     show frozen partitions test.partition_1;
     ```
     查询结果如下：
     ```
     +-----------------------------+
     |          partition          |
     +-----------------------------+
     | dt=2021-01-01 12%3A00%3A00  |
     +-----------------------------+
     ```
     
   
   - 查询"partition_mult"表的冻结分区：
     ```
     show frozen partitions test.partition_multi;
     ```
     查询结果如下：
     ```
     +----------------------------------------------------+
     |                     partition                      |
     +----------------------------------------------------+
     | pt1=22/pt2=string2/pt3=HAPPY@happy/pt5=2021-02-01  |
     +----------------------------------------------------+
     ```
     
   
   
   
   
10. 查询含有冻结数据的表。 
    - 查询当前数据库下的所有冻结表：
      ```
      show frozen tables;
      ```
      
    
    - 查询指定数据库下的所有冻结表：
      ```
      show frozen tables in 数据库名称;
      ```
      
    
    
    
    
11. 解冻分区。 
    支持创建表的用户按照条件过滤的方式对一个或多个分区进行解冻，命令为：
    ```
    unfreeze partitions 数据库名称.表名称 where 分区过滤条件;
    ```
    例如：
    - 解冻被冻结的"partition_1"的分区：
      ```
      unfreeze partitions test.partition_1 where dt < '2021-02-01 12:00:00.0';
      ```
      
    
    - 解冻被冻结的"partition_multi"的分区：
      ```
      unfreeze partitions test.partition_multi where pt1>11 and pt2<='string2' and pt3='HAPPY@happy' and pt5>'2021-01-01';
      ```
      
    
    
    
    
12. 查询Hive表分区数据。 
    - 查看1级表分区数据：
      ```
      show partitions test.partition_1;
      ```
      查询结果与插入的数据一致。
      ```
      +-----------------------------+
      |          partition          |
      +-----------------------------+
      | dt=2021-01-01 12%3A00%3A00  |
      | dt=2021-02-01 12%3A00%3A00  |
      +-----------------------------+
      ```
      
    
    - 查看多级表分区：
      ```
      show partitions test.partition_multi;
      ```
      查询结果与插入的数据一致。
      ```
      +----------------------------------------------------+
      |                     partition                      |
      +----------------------------------------------------+
      | pt1=11/pt2=string1/pt3=abc@ABC/pt5=2021-01-01      |
      | pt1=22/pt2=string2/pt3=HAPPY@happy/pt5=2021-02-01  |
      +----------------------------------------------------+
      ```
      
    
    
    
    
 
#### 冻结分区数据命令说明
创建表的用户可按照分区条件过滤，对一个或多个分区进行冻结。
**语法** ：**freeze partitions** *数据库名称* .*表名* **where** *分区过滤条件*
**说明**：where后仅支持使用分区字段编写过滤条件，多条件使用and连接。
**示例**：
```
freeze partitions testdb.test where year <= 2021;
```
```
freeze partitions testdb.test where year<=2021 and month <= 5;
```
```
freeze partitions testdb.test where year<=2021 and month <= 5 and day <= 27;
```
#### 解冻分区数据命令说明
创建表的用户可按照分区条件过滤，对已冻结的分区执行解冻。
**语法** ：**unfreeze partitions** *数据库名称* .*表名* **where** *分区过滤条件*
**说明**：where后仅支持使用分区字段编写过滤条件，仅能对已经冻结的分区执行解冻。
**示例**：
```
unfreeze partitions testdb.test where year <= 2021;
```
```
unfreeze partitions testdb.test where year<=2021 and month <= 5;
```
```
unfreeze partitions testdb.test where year<=2021 and month <= 5 and day <= 27;
```
#### 查询含有冻结数据的表命令说明
- 查询当前数据库下所有存在冻结分区的表。
  ```
  show frozen tables;
  ```
  
- 查询指定数据库下所有存在冻结分区的表。
  ```
  show frozen tables in 数据库名称;
  ```
  
- 查询指定表中处于冻结状态的分区。
  ```
  show frozen partitions 表名;
  ```
  ```
  show frozen partitions 数据库名称.表名;
  ```
  
 
