内存管控
HTAP的数据全部存放于GaussDB的内存上,配备对应的内存管控功能,避免内存占用过多影响行存查询或导致数据库内存溢出。
HTAP的内存同时包含动态共享内存和非动态共享内存两部分。非动态共享内存部分为加载/重建/扫描等临时内存上下文等。动态共享内存为三层结构:第一层挂载在顶级动态内存上下文上,用于存放IMCV元信息以及HTAP必要的辅助数据如哈希表等;第二层挂载于第一层内存上下文,存放各IMCV表中相关元信息,主要存放IMCU元信息和TMU数据等;第三层为IMCU数据信息,挂载于第二层,包含了IMCU实际数据等,内存上下文结构如图1所示。全部HTAP内存中使用htap_max_mem_size看护HTAP表级内存上下文的数据部分内存开销,其他视为底噪不看护。
相关GUC参数为htap_max_mem_size和htap_memctl_policy,详情请参见《参考》中“数据库运行参数说明 > GUC参数说明 > HTAP混合负载”章节。
- htap_max_mem_size:设置HTAP可用内存大小。取值范围为100MB~1TB。默认为1GB。
- htap_memctl_policy:设置HTAP特性内存管理的策略模式。取值范围为'swap'、'escape',默认为'swap'。
HTAP在pg_total_memory_detail系统视图中新增了memorytype为max_htap_memory和htap_used_memory的两行记录,分别用于表示HTAP最大可用内存和HTAP当前已用内存,该视图详情请参见《参考》中“系统表和系统视图 > 系统视图 > 其他系统视图 > PG_TOTAL_MEMORY_DETAIL”章节。
用户可以通过使用gs_htap_imcv_info()系统函数确认表的IMCV基本信息,该函数详情请参见《参考》中“SQL参考 > 函数和操作符 > 系统管理函数 > HTAP系统函数”章节。
当前列存数据加载/重建、列存扫描等操作中的临时内存占用,不受htap_max_mem_size管控,因此实际使用中应关注此类操作内存资源占用,避免影响业务。
示例
--查看GUC参数。
gaussdb=# SHOW htap_max_mem_size;
htap_max_mem_size
-------------------
100MB
(1 row)
gaussdb=# SHOW htap_memctl_policy;
htap_memctl_policy
--------------------
escape
(1 row)
--查看内存状态以及表信息。
gaussdb=# SELECT * FROM pg_total_memory_detail WHERE memorytype='max_htap_memory' OR memorytype='htap_used_memory';
nodename | memorytype | memorymbytes
-----------+------------------+--------------
datanode1 | max_htap_memory | 100
datanode1 | htap_used_memory | 0
(2 rows)
gaussdb=# SELECT rel_name, imcvnattr, imcvkey, rowgroup_num, cu_num_in_mem, cu_mem_size FROM gs_htap_imcv_info();
rel_name | imcvnattr | imcvkey | rowgroup_num | cu_num_in_mem | cu_mem_size
----------+-----------+---------+--------------+---------------+-------------
(0 rows)
--创建普通表htap_imcv_mem_ctl_1并插入少量数据。
gaussdb=# CREATE TABLE htap_imcv_mem_ctl_1(
id int,
dept_id int,
salary int,
name varchar(20),
comments varchar(30));
CREATE TABLE
gaussdb=# 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。
gaussdb=# ALTER TABLE htap_imcv_mem_ctl_1 COLVIEW(id, salary, name, comments) PRIORITY HIGH;
ALTER TABLE
--查看内存状态以及表信息
gaussdb=# SELECT * FROM pg_total_memory_detail WHERE memorytype='max_htap_memory' OR memorytype='htap_used_memory';
nodename | memorytype | memorymbytes
-----------+------------------+--------------
datanode1 | max_htap_memory | 100
datanode1 | htap_used_memory | 6
(2 rows)
gaussdb=# SELECT rel_name, imcvnattr, imcvkey, rowgroup_num, cu_num_in_mem, cu_mem_size FROM gs_htap_imcv_info();
rel_name | imcvnattr | imcvkey | rowgroup_num | cu_num_in_mem | cu_mem_size
---------------------+-----------+---------+--------------+---------------+-------------
htap_imcv_mem_ctl_1 | 4 | 1 3 4 5 | 6 | 30 | 7038076
(1 row)
-向已有IMCV的表中插入少量数据。
gaussdb=# INSERT INTO htap_imcv_mem_ctl_1 VALUES (generate_series(1000001,3000000), generate_series(1000001,3000000), generate_series(1000001,3000000), 'Jack', 'AAAA');
INSERT 0 2000000
--查看内存状态以及表信息,其中部分新数据可能存在于TMU中,htap_used_memory会在CU重建后增加。
gaussdb=# SELECT * FROM pg_total_memory_detail WHERE memorytype='max_htap_memory' OR memorytype='htap_used_memory';
nodename | memorytype | memorymbytes
-----------+------------------+--------------
datanode1 | max_htap_memory | 100
datanode1 | htap_used_memory | 20
(2 rows)
gaussdb=# SELECT rel_name, imcvnattr, imcvkey, rowgroup_num, cu_num_in_mem, cu_mem_size FROM gs_htap_imcv_info();
rel_name | imcvnattr | imcvkey | rowgroup_num | cu_num_in_mem | cu_mem_size
---------------------+-----------+---------+--------------+---------------+-------------
htap_imcv_mem_ctl_1 | 4 | 1 3 4 5 | 16 | 75 | 20619276
(1 row)
gaussdb=# DROP TABLE htap_imcv_mem_ctl_1;
DROP TABLE
