DM 数据库管理系统的内存结构主要包括内存池、缓冲区、排序区、哈希区等。根据系统中子模块的不同功能,对内存进行了上述划分,并采用了不同的管理模式。
1.内存池
DM Server 的内存池包括共享内存池和其他一些运行时内存池。
动态视图 V$MEM_POOL 详细记录了当前系统中所有的内存池的状态,可通过查询这个动态视图掌握 DM Server 的内存使用情况。
查询该视图中的信息:
SQL> select addr, name, file_name, file_line from v\$mem_pool;
LINEID ADDR NAME FILE_NAME FILE_LINE
---------- -------------------- --------------------- -------------------------------- -----------
1 140616840089696 SHARE POOL /ssd/ztn/trunk8_rel/knl/mem2.c 1527
2 140616835891296 BACKUP POOL /ssd/ztn/trunk8_rel/knl/mem2.c 1583
3 140616822075488 MON ITEM ARR /ssd/ztn/trunk8_rel/mon/dthrd.c 317
4 140616821022816 LARGE_MEM_SQL_MONITOR /ssd/ztn/trunk8_rel/mon/dsql.c 3434
5 97612416 CYT_CACHE /ssd/ztn/trunk8_rel/crypto/cyt.c 374
6 97679888 XMAL SYS /ssd/ztn/trunk8_rel/xmal/xmal.c 34
7 97747360 XBOX SYS /ssd/ztn/trunk8_rel/xmal/xbox.c 179
8 140616080670816 DICT CACHE /ssd/ztn/trunk8_rel/dict/ndct.c 209
9 98547088 CHECK POINT /ssd/ztn/trunk8_rel/log/ckpt2.c 229
10 98693376 HUGE AUX /ssd/ztn/trunk8_rel/hfs/haux.c 71
11 140615172935776 SQL CACHE MANAGERMENT /ssd/ztn/trunk8_rel/mgr/scp.c 291
LINEID ADDR NAME FILE_NAME FILE_LINE
---------- -------------------- -------------------- ----------------------------------- -----------
12 98761472 MEM FOR PIPE /ssd/ztn/trunk8_rel/pub/ifun_pipe.c 233
13 98881744 FLASHBACK SYS /ssd/ztn/trunk8_rel/trx/fback.c 57
14 140615145455712 RT_MEMOBJ_VPOOL /ssd/ztn/trunk8_rel/job/job.c 227
15 99014624 DBLINK POOL /ssd/ztn/trunk8_rel/dblnk/dblnk.c 9772
16 99147632 NSEQ CACHE /ssd/ztn/trunk8_rel/npar/nseq.c 944
17 99215728 PARALLEL LOADER POOL /ssd/ztn/trunk8_rel/bldr_dll/bldr.c 86
18 99511408 POLICY GRP /ssd/ztn/trunk8_rel/dict/ndctpgrp.c 237
19 101816752 PURG_POOL /ssd/ztn/trunk8_rel/trx/purg2.c 3703
20 140614962835552 DSQL STAT HISTORY /ssd/ztn/trunk8_rel/mon/dsql.c 6038
21 140615618661968 SESSION /ssd/ztn/trunk8_rel/mgr/sess4.c 1399
22 140615619778192 RT_HEAP /ssd/ztn/trunk8_rel/mgr/sess4.c 1220
LINEID ADDR NAME FILE_NAME FILE_LINE
---------- -------------------- --------------- ------------------------------ -----------
23 140615419436992 VIRTUAL MACHINE /ssd/ztn/trunk8_rel/op/vm.c 1070
24 140614959685728 DSQL ET POOL /ssd/ztn/trunk8_rel/mon/dsql.c 4975
24 rows got
used time: 0.183(ms). Execute id is 8.
通过查看动态视图V$MEM_POOL,达梦数据库返回了24条内存池的信息,V$MEM_POOL能提供的内存池信息相当丰富,我们通过desc命令可以查看这个视图所能提供的全部信息。
SQL> desc v$mem_pool
LINEID NAME TYPE$ NULLABLE
---------- ------------- ------------ --------
1 ADDR BIGINT Y
2 NAME VARCHAR(128) Y
3 IS_SHARED CHAR(1) Y
4 CHK_MAGIC CHAR(1) Y
5 CHK_LEAK CHAR(1) Y
6 IS_OVERFLOW CHAR(1) Y
7 IS_DSA_ITEM CHAR(1) Y
8 ORG_SIZE BIGINT Y
9 TOTAL_SIZE BIGINT Y
10 RESERVED_SIZE BIGINT Y
11 DATA_SIZE BIGINT Y
LINEID NAME TYPE$ NULLABLE
---------- ------------------ ------------ --------
12 EXTEND_SIZE BIGINT Y
13 TARGET_SIZE BIGINT Y
14 EXTEND_LEN INTEGER Y
15 N_ALLOC INTEGER Y
16 N_EXTEND_NORMAL INTEGER Y
17 N_EXTEND_EXCLUSIVE INTEGER Y
18 N_FREE INTEGER Y
19 MAX_EXTEND_SIZE BIGINT Y
20 MIN_EXTEND_SIZE BIGINT Y
21 FILE_NAME VARCHAR(256) Y
22 FILE_LINE INTEGER Y
LINEID NAME TYPE$ NULLABLE
---------- ------- ------- --------
23 CREATOR INTEGER Y
23 rows got
used time: 135.461(ms). Execute id is 9.
1.1 共享内存池
采用共享内存池则可一次向操作系统申请一片较大内存,即为内存池,当系统在运行过程中需要申请内存时,可在共享内存池内进行申
请,当用完该内存时,再释放掉,即归还给共享内存池。
DM 系统管理员可以通过 DM Server 的配置文件(dm.ini)来对共享内存池的大小进行设置,共享池的参数为 MEMORY_POOL,该配置默认为 200M。如果在运行时所需内存大于配置值,共享内存池也可进行自动扩展,INI 参数 MEMORY_EXTENT_SIZE 指定了共享内存池每次扩展的大小,参数 MEMORY_TARGET 则指定了共享内存池能扩展到的最大大小。
查看共享池基本信息:
SQL> select name, org_size, total_size, data_size, target_size from v$mem_pool where name like 'SHARE%';
LINEID NAME ORG_SIZE TOTAL_SIZE DATA_SIZE TARGET_SIZE
---------- ---------- -------------------- -------------------- -------------------- --------------------
1 SHARE POOL 67108864 311427072 160704099 0
used time: 0.893(ms). Execute id is 15.
查看共享池配置参数,
SQL> select para_name, para_value from v$dm_ini where para_name like '%MEMORY_TAR%';
LINEID PARA_NAME PARA_VALUE
---------- ------------- ----------
1 MEMORY_TARGET 0
used time: 4.795(ms). Execute id is 18.
MEMORY_TARGET 共享内存的总大小 。0:表示不限制。
1.2 运行时内存池
除了共享内存池,DM Server 的一些功能模块在运行时还会使用自己的运行时内存池。
这些运行时内存池是从操作系统申请一片内存作为本功能模块的内存池来使用,如会话内存池、虚拟机内存池等。
2 缓冲区
2.1 数据缓冲区
数据缓冲区是 DM Server 在将数据页写入磁盘之前以及从磁盘上读取数据页之后,数据页所存储的地方。这是 DM Server 至关重要的内存区域之一,将其设定得太小,会导致缓冲页命中率低,磁盘 IO 频繁;将其设定得太大,又会导致操作系统内存本身不够用。
系统启动时,首先根据配置的数据缓冲区大小向操作系统申请一片连续内存并将其按数据页大小进行格式化,并置入“自由”链中。数据缓冲区存在三条链来管理被缓冲的数据页,一条是自由链,用于存放目前尚未使用的内存数据页,一条是LRU链,用于存放已被使用的内存数据页(包括未修改和已修改),还有一条即为“脏”链,用于存放已被修改过的内存数据页。
LRU 链对系统当前使用的页按其最近是否被使用的顺序进行了排序。这样当数据缓冲区中的自由链被用完时,从 LRU 链中淘汰部分最近未使用的数据页,能够较大程度地保证被淘汰的数据页在最近不会被用到,减少 IO。
在系统运行过程中,通常存在一部分“非常热”(反复被访问)的数据页,将它们一直留在缓冲区中,对系统性能会有好处。对于这部分数据页,数据缓冲区开辟了一个特定的区域 用于存放它们,以保证这些页不参与一般的淘汰机制,可以一直留在数据缓冲区中。
通过以下四个视图可以查看缓冲区信息:
v$bufferpool,用来记录页面缓冲区结构的信息。v$buffer_lru_first:显示所有缓冲区LRU链首页信息。v$buffer_lru_last:显示所有缓冲区LRU链末页信息。v$buffer_upd_first:显示所有缓冲区update链首页信息。v$buffer_upd_last显示所有缓冲区update链末页信息。
2.2 日志缓冲区
日志缓冲区是用于存放重做日志的内存缓冲区。为了避免由于直接的磁盘 IO 而使系统性能受到影响,系统在运行过程中产生的日志并不会立即被写入磁盘,而是和数据页一样,先将其放置到日志缓冲区中。那么为何不在数据缓冲区中缓存重做日志而要单独设立日志缓冲区呢?主要是基于以下原因:
1.重做日志的格式同数据页完全不一样,无法进行统一管理;
2.重做日志具备连续写的特点;
3.在逻辑上,写重做日志比数据页 IO 优先级更高。
DM Server 提供了参数 RLOG_BUF_SIZE 对日志缓冲区大小进行控制,日志缓冲区所占用的内存是从共享内存池中申请的,单位为页数量,且大小必须为 2 的 N 次方,否则采用系统默认大小 512 页。
2.3 字典缓冲区
字典缓冲区主要存储一些数据字典信息,如模式信息、表信息、列信息、触发器信息等。每次对数据库的操作都会涉及到数据字典信息,访问数据字典信息的效率直接影响到相应的操作效率,如进行查询语句,就需要相应的表信息、列信息等,这些字典信息如果都在缓冲区里,则直接从缓冲区中获取即可,否则需要 I/O 才能读取到这些信息。 DM8 采用的是将部分数据字典信息加载到缓冲区中,并采用 LRU 算法进行字典信息的控制。缓冲区大小设置问题,如果太大,会浪费宝贵的内存空间,如果太小,可能会频繁的进行淘汰,该缓冲区配置参数为 DICT_BUF_SIZE,默认的配置大小为 5M。
DM8 采用缓冲部分字典对象,那会影响效率吗?数据字典信息访问存在热点现像,并不是所有的字典信息都会被频繁的访问,所以按需加载字典信息并不会影响到实际的运行效率。
但是如果在实际应用中涉及对分区数较多的水平分区表访问,例如上千个分区,那么就需要适当调大 DICT_BUF_SIZE 参数值。
2.4 SQL 缓冲区
SQL 缓冲区提供在执行 SQL 语句过程中所需要的内存,包括计划、SQL 语句和结果集缓存。很多应用当中都存在反复执行相同 SQL 语句的情况,此时可以使用缓冲区保存这些语句和它们的执行计划,这就是计划重用。这样带来的好处是加快了 SQL 语句执行效率,但同时给内存也增加了压力。
DM Server 在配置文件 dm.ini 提供了参数来支持是否需要计划重用,参数为USE_PLN_POOL,当指定为非 0 时,则启动计划重用;为 0 时禁止计划重用。DM 同时还提供了参数 CACHE_POOL_SIZE(单位为 MB),来改变 SQL 缓冲区大小,系统管理员可以设置该值以满足应用需求,默认值为 20M。
结果集缓存包括 SQL 查询结果集缓存和 DMSQL 程序函数结果集缓存,在 INI 参数文件中同时设置参数 RS_CAN_CACHE=1 且 USE_PLN_POOL 非 0 时 DM 服务器才会缓存结果集。
DM 还提供了一些手动设置结果集缓存的方法。客户端结果集也可以缓存,但需要在配置文件 dm_svc.conf 中设置参数:
ENABLE_RS_CACHE = (1) //表示启用缓存;
RS_CACHE_SIZE = (100) //表示缓存区的大小为 100M, 可配置为 1-65535
RS_REFRESH_FREQ = (30) //表示每 30 秒检查缓存的有效性,如果失效,自动重查; 0 表示不检查。
同时在服务器端使用INI参数文件中的CLT_CACHE_TABLES参数设置哪些表的结果集需要缓存。另外,FIRST_ROWS 参数表示当查询的结果达到该行数时,就返回结果,不再继续查询,除非用户向服务器发一个 FETCH 命令。这个参数也用于客户端缓存的配置,仅当结果集的行数不超过 FIRST_ROWS 时,该结果集才可能被客户端缓存。
3 排序区
排序缓冲区提供数据排序所需要的内存空间。当用户执行 SQL 语句时,常常需要进行排序,所使用的内存就是排序缓冲区提供的。在每次排序过程中,都首先申请内存,排序结束后再释放内存。
DM Server 提供了参数来指定排序缓冲区的大小,参数SORT_BUF_SIZE 在 DM 配置文件 dm.ini 中,系统管理员可以设置其大小以满足需求,由于该值是由系统内部排序算法和排序数据结构决定,建议使用默认值 2M。
4 哈希区
DM8 提供了为哈希连接而设定的缓冲区,不过该缓冲区是个虚拟缓冲区。之所以说是虚拟缓冲,是因为系统没有真正创建特定属于哈希缓冲区的内存,而是在进行哈希连接时,对排序的数据量进行了计算。如果计算出的数据量大小超过了哈希缓冲区的大小,则使用 DM8 创新的外存哈希方式;如果没有超过哈希缓冲区的大小,实际上使用的还是 VPOOL 内存池来进行哈希操作。
DM Server 在 dm.ini 中提供了参数 HJ_BUF_SIZE 来进行控制,由于该值的大小可能会限制哈希连接的效率,所以建议保持默认值,或设置为更大的值。
除了提供 HJ_BUF_SIZE 参数外,DM Server 还提供了创建哈希表个数的初始化参数,其中,HAGR_HASH_SIZE 表示处理聚集函数时创建哈希表的个数,建议保持默认值 100000。
5 SSD 缓冲区
固态硬盘采用闪存作为存储介质,因没有机械磁头的寻道时间,在读写效率上比机械磁盘具有优势。在内存、SSD 磁盘、机械磁盘之间,符合存储分级的条件。为提高系统执行效率,DM Server 将 SSD 文件作为内存缓存与普通磁盘之间的缓冲层,称为“SSD 缓存”。
DM Server 在的 dm.ini 中提供参数 SSD_BUF_SIZE 和 SSD_FILE_PATH 来配置 SSD 缓冲,SSD_BUF_SIZE 指定缓冲区的大小,单位是 M,DM Server 根据该参数创建相应大小的文件作为缓冲区使用;SSD_FILE_PATH 指定该文件所在的文件夹路径,管理员需要保证设置的路径是位于固态磁盘上。
默认 SSD 缓冲区是关闭的,即 SSD_BUF_SIZE 为 0。若要配置 SSD 缓冲区,将其设置为大于 0 的数并指定 SSD_FILE_PATH 即可。