暂无图片
暂无图片
1
暂无图片
暂无图片
2
暂无图片

达梦数据库之内存

原创 何权林 2022-05-29
3030

1 数据库自我管理内存的目的

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

1. 申请、释放内存效率更高;

2. 能够有效地了解内存的使用情况;

3. 易于发现内存泄露和内存写越界的问题。

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

2 内存划分

2.1 内存池

DM Server 的内存池包括共享内存池和其他一些运行时内存池。

2.1.1 共享内存区

共享内存池是 DM Server 在启动时从操作系统申请的一大片内存。DM 系统管理员可以通过 DM Server 的配置文件(dm.ini)来对共享内存池的大小进行设置,共享池大小的参数为 MEMORY_POOL,缺省大小为 500M。直接向OS申请。如果在运行时所需内存大于配置值,共享内存池也可进行自动扩展,INI 参数 MEMORY_EXTENT_SIZE 指定了共享内存池每次扩展的大小,参数 MEMORY_TARGET 则指定了共享内存池扩展到超过该值后,空闲时会收缩到的大小。共享内存区可以进行分片,有利于避免临界资源冲突。但是分片数过多可能会带来额外的空间消耗。

除了数据缓存区外,其他内存池都向共享内存池申请内存。

2.1.2 运行时内存区

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

当会话连接时,会从共享内存池中申请session pool,进行SQL运算、排序等操作时也是从共享池中申请内存。

2.2 缓冲区

缓存的目的在于将磁盘数据缓存在内存里,避免频繁的IO。

2.2.1 数据缓冲区

DM Server 中有四种类型的数据缓冲区,分别是 NORMAL、KEEP、FAST 和 RECYCLE。

NORMAL是默认的数据缓冲区,由参数BUFFER确定大小,BUFFER从OS中直接申请内存,也可以进行分片;

FAST是由参数FAST确定大小,从BUFFER中申请内存

KEEP是由参数KEEP确定大小,从OS中直接申请内存;

RECYCLE是由参数RECYCLE确定大小,从OS中直接申请内存。

数据缓冲区存在三条链来管理被缓冲的数据页,一条是―自由‖链,用于存放目前尚未使用的内存数据页,一条是―LRU‖链,用于存放已被使用的内存数据页(包括未修改和已修改),还有一条即为―脏‖链,用于存放已被修改过的内存数据页。

2.2.2 日志缓冲区

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

1. 重做日志的格式同数据页完全不一样,无法进行统一管理;

2. 重做日志具备连续写的特点;

3. 在逻辑上,写重做日志比数据页 IO 优先级更高。

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

2.2.3 字典缓冲区

字典缓冲区主要存储一些数据字典信息,如模式信息、表信息、列信息、触发器信息等。

字典缓冲区由参数DICT_BUF_SIZE确认大小,直接从OS中申请,默认的配置大小为 50M。 并采用 LRU 算法进行字典信息的控制。如果数据库中对象太多,可以适当调大此参数。

2.2.4 SQL缓冲区

SQL 缓冲区提供在执行 SQL 语句过程中所需要的内存,包括计划、SQL 语句和结果集缓存。

由参数 CACHE_POOL_SIZE(单位为 MB),直接从OS中申请,来改变 SQL 缓冲区大小,系统管理员可以设置该值以满足应用需求,默认值为 100M。

涉及其他参数:参数USE_PLN_POOL,当指定为非 0 时,则启动计划重用;为 0 时禁止计划重用。

2.3 排序区

排序缓冲区提供数据排序所需要的内存空间。当用户执行 SQL 语句时,常常需要进行排序,所使用的内存就是排序缓冲区提供的。在每次排序过程中,都首先申请内存,排序结束后再释放内存。

由参数 SORT_BUF_SIZE 确定大小,从共享内存池中申请,由于该值是由系统内部排序算法和排序数据结构决定,建议使用默认值 20M。 

2.4 HASH区

DM8 提供了为哈希连接而设定的缓冲区,不过该缓冲区是个虚拟缓冲区。之所以说是虚拟缓冲,是因为系统没有真正创建特定属于哈希缓冲区的内存,而是在进行哈希连接时,对排序的数据量进行了计算。如果计算出的数据量大小超过了哈希缓冲区的大小,则使用 DM8创新的外存哈希方式;如果没有超过哈希缓冲区的大小,实际上还是使用内存池来进行哈希操作。

由参数 HJ_BUF_SIZE 来进行控制大小,从共享内存池中申请,建议保持默认值,或设置为更大的值。

除了提供 HJ_BUF_SIZE 参数外,DM Server 还提供了创建哈希表个数的初始化参数,其中,HAGR_HASH_SIZE 表示处理聚集函数时创建哈希表的个数,建议保持默认值 100000。

3 与ORACLE 对比

相同点:

1. 达梦数据库与ORACLE数据库都是自我管理内存结构,先向OS申请内存,然后进行内部管理,便于分析内存使用情况;

2. 都有功能相似的数据缓冲区、日志缓冲区、字典缓冲区、SQL缓冲区、各种池,如keep池等。


不同点:

达梦数据库相较于ORACLE而言,内存的自动调节能力弱一些(也就是智能化)。


以上内容,有写的不对的地方请各位专家指正,谢谢!

DM技术学习网站:https://eco.dameng.com

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

周伟
暂无图片
1年前
评论
暂无图片 0
让人困惑的是,他们的官方文档当中,将SQL缓冲区参数 cache_pool_size 居然归纳为数据库相关参数,而不是内存相关参数,虽然硬说是数据库相关参数理解也没毛病,但是感觉上还是有点太粗糙。
1年前
暂无图片 点赞
评论
周伟
暂无图片
1年前
评论
暂无图片 0
我一直对这个共享内存池的作用存在一些不理解的地方,文章中说到“除了数据缓存区外,其他内存池都向共享内存池申请内存”,但是后面提到的log buffer 写的又是从共享池中申请,但log buffer貌似也属于数据缓存区。他们这个数据库的内存体系架构到底啥样的?了解这些信息主要是明白他们作用之后,才能在安装数据库的时候配置各种参数,不像oracle一样,ASMM之下,两个SGA+1个PGA就全搞定。他们这个内存,对那些各种缓存区的参数都需要单独配置,就像以前的老版本的oracle一样,手工管理内存时代的感觉。而他们这个共享内存池,似乎就只为排序,HASH,log buffer 服务一样。我一开始一直把这个所谓的共享内存池理解为oracle的SGA,但是感觉不是,它更像是oracle SGA当中之下的shared_pool,但是oracle的shared_pool是包含了SQL区之类的。。。哎。。感觉一团乱码。。
1年前
暂无图片 点赞
评论