admin管理员组

文章数量:1443939

【赵渝强老师】达梦数据库的内存结构

数据库管理系统是一种对内存申请和释放操作频率很高的软件,如果每次对内存的使用都使用操作系统函数来申请和释放,效率会比较低,加入自己的内存管理是DBMS系统所必须的。通常内存管理系统会带来以下好处:

  • 申请、释放内存效率更高;
  • 能够有效地了解内存的使用情况;
  • 易于发现内存泄露和内存写越界的问题。

达梦数据库管理系统的内存结构主要包括内存池、缓冲区、排序区、哈希区等。根据系统中子模块的不同功能,对内存进行了上述划分,并采用了不同的管理模式。

视频讲解如下:

一、 内存池

DM Server的内存池包括共享内存池和其他一些运行时内存池。动态视图v$mem_pool详细记录了当前系统中所有的内存池的状态,可通过查询这个动态视图掌握DM Server的内存使用情况。

代码语言:sql复制
SQL> select name,sum(total_size) from v$mem_pool group by name;

# 输出的信息如下:

行号     NAME                  			 SUM(TOTAL_SIZE)     
---------- ---------------------- --------------------
1          SHARE POOL 000        	 	524288000
2          BACKUP POOL            		4194304
3          RT_MEMOBJ_VPOOL        		49283072
4          MON ITEM ARR           		134217728
5          LARGE_MEM_SQL_MONITOR  		2097152
6          DSQL BIND DATA HISTORY 	10485760
7          CYT_CACHE              		327680
8          XMAL SYS               		65536
9          XBOX SYS               		65536
10         DICT CACHE             		52428800
11         TRX                    		704512
12         INJECT HINT            		65536
13         CHECK POINT            		131072
14         HUGE AUX               		65536
15         SQL CACHE MANAGERMENT  	104857600
16         MEM FOR PIPE           		65536
17         FLASHBACK SYS          		22879992
18         DBLINK POOL          		131072
19         NSEQ CACHE           		65536
20         PARALLEL LOADER POOL 		65536
21         POLICY GRP           		2162688
22         PURG_POOL            		65536
23         DSQL STAT HISTORY    		15728640
24         DSQL ET POOL         		11534336
25         SESSION              			30736384
26         RT_HEAP              			344064
27         VIRTUAL MACHINE      		12910592

27 rows got

内存池又分为共享内存池和运行时内存池。

1.1 共享内存池

共享内存池是DM Server在启动时从操作系统申请的一大片内存。在DM Server的运行期间,经常会申请与释放小片内存,而向操作系统申请和释放内存时需要发出系统调用,此时可能会引起线程切换,降低系统运行效率。采用共享内存池则可一次向操作系统申请一片较大内存,即为内存池,当系统在运行过程中需要申请内存时,可在共享内存池内进行申请,当用完该内存时,再释放掉,即归还给共享内存池。

DM系统管理员可以通过DM Server的配置文件(dm.ini)来对共享内存池的大小进行设置,共享池的参数为MEMORY_POOL,该配置默认为500M。如果在运行时所需内存大于配置值,共享内存池也可进行自动扩展,INI参数MEMORY_EXTENT_SIZE指定了共享内存池每次扩展的大小,参数MEMORY_TARGET则指定了共享内存池扩展到超过该值后,空闲时会收缩到的大小。

代码语言:sql复制
SQL> select para_name,para_value from v$dm_ini 
    where para_name in ('MEMORY_POOL','MEMORY_TARGET','MEMORY_EXTENT_SIZE');

# 输出的信息如下:
行号     PARA_NAME          		PARA_VALUE
---------- ------------------ ----------
1          MEMORY_POOL        		500
2          MEMORY_TARGET      		15000
3          MEMORY_EXTENT_SIZE 	32

1.2 运行时内存池

除了共享内存池,DM Server的一些功能模块在运行时还会使用自己的运行时内存池。这些运行时内存池是从操作系统申请一片内存作为本功能模块的内存池来使用,如会话内存池、虚拟机内存池等。

二、 缓冲区

DM数据库中的缓冲区分为数据缓冲区、日志缓冲区、字典缓冲区和SQL缓冲区。

2.1 数据缓冲区

数据缓冲区是DM Server在将数据页写入磁盘之前以及从磁盘上读取数据页之后,数据页所存储的地方。这是DM Server至关重要的内存区域之一,将其设定得太小,会导致缓冲页命中率低,磁盘IO频繁;将其设定得太大,又会导致操作系统内存本身不够用。

代码语言:sql复制
SQL> select para_name,para_value from v$dm_ini
     where para_name in ('BUFFER','KEEP','FAST','RECYCLE');

# 输出的信息如下:
行号     		PARA_NAME PARA_VALUE
---------- --------- ----------
1          	BUFFER    	1000
2          	KEEP      	8
3          	RECYCLE   	300

# PARA_VALUE的数值为默认值分别对应 NORMAL缓冲区大小、KEEP缓冲区大小、
# RECYCLE缓冲区大小数据页总数。

DM数据库中有四种类型的数据缓冲区,分别是 NORMAL、KEEP、FAST、RECYCLE。下表说明了每种数据缓冲区的作用。

系统启动时,首先根据配置的数据缓冲区大小向操作系统申请一片连续内存并将其按数据页大小进行格式化,并置入“自由”链中。数据缓冲区存在三条链来管理被缓冲的数据页,一条是“自由”链,用于存放目前尚未使用的内存数据页,一条是“LRU”链,用于存放已被使用的内存数据页(包括未修改和已修改),还有一条即为“脏”链,用于存放已被修改过的内存数据页。

2.2 日志缓冲区

日志缓冲区是用于存放重做日志的内存缓冲区。为了避免由于直接的磁盘IO而使系统性能受到影响,系统在运行过程中产生的日志并不会立即被写入磁盘,而是和数据页一样,先将其放置到日志缓冲区中。那么为何不在数据缓冲区中缓存重做日志而要单独设立日志缓冲区呢?主要是基于以下原因:

  1. 重做日志的格式同数据页完全不一样,无法进行统一管理;
  2. 重做日志具备连续写的特点;
  3. 在逻辑上,写重做日志比数据页IO优先级更高。

DM数据库提供了参数RLOG_BUF_SIZE对日志缓冲区大小进行控制,日志缓冲区所占用的内存是从共享内存池中申请的,单位为页数量,且大小必须为2的N次方,否则采用系统默认大小1024页。

代码语言:sql复制
SQL> select para_name,para_value from v$dm_ini 
     where para_name='RLOG_BUF_SIZE';

# 输出的信息如下:

行号     		PARA_NAME     PARA_VALUE
---------- ------------- ----------
1          	RLOG_BUF_SIZE 1024

2.3 字典缓冲区

字典缓冲区主要存储一些数据字典信息,如模式信息、表信息、列信息、触发器信息等。每次对数据库的操作都会涉及到数据字典信息,访问数据字典信息的效率直接影响到相应的操作效率。DM8 采用的是将部分数据字典信息加载到缓冲区中,并采用 LRU 算法进行字典信息的控制。配置参数 DICT_BUF_SIZE 控制缓冲区的大小,默认大小为50M。缓冲区配置得太大,会浪费内存空间;配置得太小,可能会频繁地进行淘汰。

代码语言:sql复制
SQL> select para_name,para_value from v$dm_ini 
     where para_name='DICT_BUF_SIZE';

# 输出的信息如下:

行号     		PARA_NAME     PARA_VALUE
---------- ------------- ----------
1          	DICT_BUF_SIZE 50

2.4 SQL缓冲区

SQL缓冲区提供在执行SQL语句过程中所需要的内存,包括计划、SQL语句和结果集缓存。配置参数USE_PLN_POOL控制是否需要计划重用,非0时启动计划重用,为0时禁用计划重用。配置参数CACHE_POOL_SIZE设置SQL缓冲区的大小,默认值为100M。结果集缓存包括SQL查询结果集缓存和DMSQL程序函数结果集缓存,同时设置参数RS_CAN_CACHE=1且USE_PLN_POOL非0时,才会缓存结果集。

代码语言:sql复制
SQL> select para_name,para_value from v$dm_ini 
     where para_name in ('USE_PLN_POOL','CACHE_POOL_SIZE');

# 输出的信息如下:

行号     		PARA_NAME       PARA_VALUE
---------- --------------- ----------
1          	USE_PLN_POOL  		1
2          	CACHE_POOL_SIZE 	100

三、 排序区

排序缓冲区提供数据排序所需的内存空间。当用户执行SQL语句时,常常需要进行排序,所使用的内存就是排序缓冲区提供的。在每次排序过程中,都首先申请内存,排序结束后再释放内存。配置文件dm.ini中的参数SORT_BUF_SIZE用来指定排序缓冲区的大小。

代码语言:sql复制
SQL> select para_name,para_value from v$dm_ini 
     where para_name='SORT_BUF_SIZE';

# 输出的信息如下:

行号     		PARA_NAME     PARA_VALUE
---------- ------------- ----------
1          	SORT_BUF_SIZE 20

四、 哈希区

DM8 提供了为哈希连接而设定的缓冲区,不过该缓冲区是个虚拟缓冲区。之所以说是虚拟缓冲区,因为系统没有真正创建特定属于哈希缓冲区的内存,是在进行哈希连接时,对排序的数据量进行了计算。如果计算出的数据量大小超过了哈希缓冲区的大小,则使用DM8创新的外存哈希方式;如果没有超过哈希缓冲区的大小,实际上使用的还是内存池来进行哈希操作。配置文件 dm.ini 中的参数 HJ_BUF_SIZE 控制缓冲区大小,建议保留默认值,或设置更大的值。

代码语言:sql复制
SQL> select para_name,para_value from v$dm_ini 
     where para_name='HJ_BUF_SIZE';

# 输出的信息如下:

行号     		PARA_NAME   PARA_VALUE
---------- ----------- ----------
1          	HJ_BUF_SIZE 500

本文标签: 赵渝强老师达梦数据库的内存结构