
# 内存管控
HTAP的数据全部存放于GaussDB的内存上，配备对应的内存管控功能，避免内存占用过多影响行存查询或导致数据库内存溢出。
HTAP的内存同时包含动态共享内存和非动态共享内存两部分。非动态共享内存部分为加载/重建/扫描等临时内存上下文等。动态共享内存为三层结构：第一层挂载在顶级动态内存上下文上，用于存放IMCV元信息以及HTAP必要的辅助数据如哈希表等；第二层挂载于第一层内存上下文，存放各IMCV表中相关元信息，主要存放IMCU元信息和TMU数据等；第三层为IMCU数据信息，挂载于第二层，包含了IMCU实际数据等。内存上下文结构如[图1]所示。全部HTAP内存中使用htap_max_mem_size看护HTAP表级内存上下文的数据部分内存开销，其他视为底噪不看护。
图1HTAP内存上下文结构   
![](https://support.huaweicloud.com/distributed-devg-v10-gaussdb/figure/zh-cn_image_0000002620720453.png "点击放大")
相关GUC参数为htap_max_mem_size和htap_memctl_policy，详情请参见《参考》中"数据库运行参数说明 \> GUC参数说明 \> HTAP混合负载"章节。
- htap_max_mem_size：设置HTAP可用内存大小。取值范围为100MB\~1TB。默认为1GB。
- htap_memctl_policy：设置HTAP特性内存管理的策略模式。取值范围为'swap'、'escape'，默认为'escape'。
HTAP在pg_total_memory_detail系统视图中新增了memorytype为max_htap_memory和htap_used_memory的两行记录，分别用于表示HTAP最大可用内存和HTAP当前已用内存，该视图详情请参见《参考》中"系统表和系统视图 \> 系统视图 \> 其他系统视图 \> PG_TOTAL_MEMORY_DETAIL"章节。
用户可以通过使用gs_global_imcv_info()系统函数确认表的IMCV基本信息，该函数详情请参见《参考》中"SQL参考 \> 函数和操作符 \> 系统管理函数 \> HTAP系统函数"章节。
#### 示例
```
--使用分布式3C2D，1主1备集群，gsql连接CN5001节点。
--查看GUC参数。
htapdb=# SHOW htap_max_mem_size;
 htap_max_mem_size 
-------------------
 1GB
(1 row)
htapdb=# SHOW htap_memctl_policy;
 htap_memctl_policy 
--------------------
 swap
(1 row)
--连接DN6001节点主机，查看DN节点内存状态以及表信息。
htapdb=# SELECT * FROM pg_total_memory_detail WHERE memorytype='max_htap_memory' OR memorytype='htap_used_memory';
   nodename   |    memorytype    | memorymbytes 
--------------+------------------+--------------
 dn_6001_6002 | max_htap_memory  |         1024
 dn_6001_6002 | htap_used_memory |            0
(2 rows)
--连接CN5001节点。
htapdb=# SELECT node_name, rel_name, imcvnattr, imcvkey, rowgroup_num, cu_num_in_mem, cu_mem_size, cu_num_in_disk, cu_disk_size FROM gs_global_imcv_info();
 node_name | rel_name | imcvnattr | imcvkey | rowgroup_num | cu_num_in_mem | cu_mem_size | cu_num_in_disk | cu_disk_size 
-----------+----------+-----------+---------+--------------+---------------+-------------+----------------+--------------
(0 rows)
--创建普通表htap_imcv_mem_ctl_1并插入少量数据。
htapdb=# CREATE TABLE htap_imcv_mem_ctl_1(
          id int,
          dept_id int,
          salary int,
          name varchar(20),
          comments varchar(30)) distribute by hash(id);
CREATE TABLE
htapdb=# INSERT INTO htap_imcv_mem_ctl_1 VALUES (generate_series(1,1000000), generate_series(1,1000000), generate_series(1,1000000), 'Jack', 'AAAA');
INSERT 0 1000000
--对小数据量的表执行ALTER COLVIEW创建IMCV。
htapdb=# ALTER TABLE htap_imcv_mem_ctl_1 COLVIEW(id, salary, name, comments);
ALTER TABLE
--执行手动加载，确保所有行存数据都已加载到IMCV。
htapdb=# SELECT total from gs_imcv_flush('htap_imcv_mem_ctl_1');
 total 
-------
 6
(1 row)
--查看DN节点内存状态以及表信息。
htapdb=# EXECUTE DIRECT ON (dn_6001_6002) $$SELECT * FROM pg_total_memory_detail WHERE memorytype='max_htap_memory' OR memorytype='htap_used_memory'$$;
   nodename   |    memorytype    | memorymbytes 
--------------+------------------+--------------
 dn_6001_6002 | max_htap_memory  |         1024
 dn_6001_6002 | htap_used_memory |            3
(2 rows)
htapdb=# SELECT node_name, rel_name, imcvnattr, imcvkey, rowgroup_num, cu_num_in_mem, cu_mem_size, cu_num_in_disk, cu_disk_size FROM gs_global_imcv_info();
  node_name   |      rel_name       | imcvnattr | imcvkey | rowgroup_num | cu_num_in_mem | cu_mem_size | cu_num_in_disk | cu_disk_size 
--------------+---------------------+-----------+---------+--------------+---------------+-------------+----------------+--------------
 dn_6001_6002 | htap_imcv_mem_ctl_1 |         4 | 1 3 4 5 |            3 |            15 |     3553162 |              0 |            0
 dn_6003_6004 | htap_imcv_mem_ctl_1 |         4 | 1 3 4 5 |            3 |            15 |     3545231 |              0 |            0
(2 rows)
-向已有IMCV的表中插入少量数据。
htapdb=# INSERT INTO htap_imcv_mem_ctl_1 SELECT * FROM htap_imcv_mem_ctl_1;
INSERT 0 1000000
--查看DN节点内存状态以及表信息，其中部分新数据可能存在于TMU中，htap_used_memory会在CU重建后增加。
--一段时间后
htapdb=# EXECUTE DIRECT ON (dn_6001_6002) $$SELECT * FROM pg_total_memory_detail WHERE memorytype='max_htap_memory' OR memorytype='htap_used_memory'$$;
   nodename   |    memorytype    | memorymbytes 
--------------+------------------+--------------
 dn_6001_6002 | max_htap_memory  |         1024
 dn_6001_6002 | htap_used_memory |            6
(2 rows)
htapdb=# SELECT node_name, rel_name, imcvnattr, imcvkey, rowgroup_num, cu_num_in_mem, cu_mem_size, cu_num_in_disk, cu_disk_size FROM gs_global_imcv_info();
  node_name   |      rel_name       | imcvnattr | imcvkey | rowgroup_num | cu_num_in_mem | cu_mem_size | cu_num_in_disk | cu_disk_size 
--------------+---------------------+-----------+---------+--------------+---------------+-------------+----------------+--------------
 dn_6001_6002 | htap_imcv_mem_ctl_1 |         4 | 1 3 4 5 |            6 |            25 |     6303358 |              0 |            0
 dn_6003_6004 | htap_imcv_mem_ctl_1 |         4 | 1 3 4 5 |            6 |            25 |     6295427 |              0 |            0
(2 rows)
htapdb=# DROP TABLE htap_imcv_mem_ctl_1;
DROP TABLE
```
