一、DM内存结构

1.1 内存结构简介

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

(1) 内存池

  • 共享内存池:是DM Server在启动时从操作系统申请的一大片内存。默认大小500M,可在dm.ini修改参数MEMORY_POOL调整大小,参数MEMORY_EXTENT_SIZE指定共享内存池每次扩展的大小,参数MEMORY_TARGET  指定共享内存池能扩展到的最大值。
  • 运行时内存池:是从操作系统申请一片内存作为本功能模块的内存池来使用,如会话内存池、虚拟机内存池等。

(2) 缓冲区

  • 数据缓冲区:DM Server在将数据页写入磁盘之前以及从磁盘上读取数据页之后,数据页所存储的地方。这是DM Server至关重要的内存区域之一,将其设定得太小,会导致缓冲页命中率低,磁盘IO频繁;将其设定得太大,又会导致操作系统内存本身不够用。
  • 日志缓冲区:日志缓冲区是用于存放重做日志的内存缓冲区。为了避免由于直接的磁盘IO而使系统性能受到影响,系统在运行过程中产生的日志并不会立即被写入磁盘,而是和数据页一样,先将其放置到日志缓冲区中。
  • 字典缓冲区:主要存储一些数据字典信息,如模式信息、表信息、列信息、触发器信息等。每次对数据库的操作都会涉及到数据字典信息,访问数据字典信息的效率直接影响到相应的操作效率。DM8 采用的是将部分数据字典信息加载到缓冲区中,并采用 LRU 算法进行字典信息的控制。
  • SQL缓冲区:提供在执行SQL语句过程中所需要的内存,包括计划、SQL语句和结果集缓存。

(3) 排序区

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

(4) 哈希区

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

1.2 相关参数说明

内存结构

说明

dm.ini参数

参数说明

共享内存池

 DM Server 在启动时从操作系统申请的一大片内存。

MEMORY_POOL

共享内存池大小,最大扩展到MAX_OS_MEMORY的值。

MAX_OS_MEMORY

限制 dmserver 进程从操作系统中申请的最大内存百分比。

MEMORY_TARGET

共享内存池在扩充到此大小以上后,空闲时收缩回此指定大小。

MEMORY_EXTENT_SIZE

如果在运行时所需内存大于配置值,共享内存池也可进行自动扩展, MEMORY_EXTENT_SIZE 指定了共享内存池每次扩展的大小。

运行时内存池

会话内存池,一个会话有一个私有的内存池。会话的事务及SQL分析都在此进行。

SESS_POOL_SIZE

会话缓冲区大小。

虚拟机内存池。实际执行SQL时创建,用于提供每个操作符使用的内存空间。

VM_POOL_SIZE

虚拟机内存池大小。

数据缓冲区

在将数据页写入磁盘之前以及从磁盘上读取数据页之后,数据页所存储的地方。用来存储包信息、执行计划、结果集缓存的一片专用缓存区域。数据缓冲区存在三条链来管理被缓冲的数据页。

BUFFER

分为NORMAL、FAST、KEEP、RECYCLE。

FAST_POOL_PAGES

快速缓冲区页数。

RECYCLE

RECYCLE缓冲区大小。

KEEP

KEEP缓冲区大小。

字典缓冲区

主要存储一些数据字典信息。采用 LRU 算法进行字典信息的控制。

DICT_CACHE_SIZE

字典缓冲区大小。

SQL缓冲区

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

CACHE_POOL_SIZE

SQL缓冲区大小。

日志缓冲区

用于存放重做日志的内存缓冲区,避免直接的磁盘 IO 而使系统性能受到影响。

RLOG_BUF_SIZE

数据库日志将对磁盘的随机写转换为顺序写。

排序区

提供数据排序所需要的内存空间。每个排序会话都会申请排序空间,排序结束后释放内存。排序、去重、分区等操作。

SORT_BUF_SIZE

排序缓冲区大小。由系统内部排序算法和排序数据结构决定,建议使用默认值2M。

HASH

为了哈希连接而设定的虚拟缓冲区,实际申请内存时从MEM_POOL申请。

HJ_*

HJ_BUF_SIZE用于限制大小和哈希连接效率。系统进行哈希连接时对排序的数据量进行计算,如果超过哈希缓冲区大小,则用外存哈希方式,未超过则使用内存池进行哈希操作。

HAGR_*


二、SQL执行

2.1 核心动词与基本对象

SQL功能

动词

基本对象

数据定义

CREATE、DROP、ALTER

表空间

用户

模式

视图

存储过程

存储函数

存储包

触发器

序列

索引

数据字典

TABLESPACE

USER

SCHEMA

TABLE

VIEW

COLUMN

PROCEDURE

FUNCTION

PACKAGE

TRIGGER

SEQUENCE

INDEX

DICTIONARY

数据查询

SELECT

数据操纵

INSERT、UPDATE、DELETE

数据控制

GRANT、REVOKE

2.2 分析流程

        SQL – 词法语法分析 – 语义分析 – 关系代数转换 – 生成逻辑计划 – 生成物理计划

将mysql数据库的sql转换为达梦数据库的sql 达梦数据库导出sql文件_数据库

2.3 执行顺序

(1) select 语句执行顺序:

from – on – join – where – group by – agg_func – with rollup或cube – having – select – distinct – order by – limit

(2) update 语句执行顺序:

from – where – set – update

将mysql数据库的sql转换为达梦数据库的sql 达梦数据库导出sql文件_系统架构_02

三、DM内存结构与SQL执行

3.1 概念说明

缓冲区(Buffer):核心作用是用来缓冲。在输入输出设备和CPU之间存储数据,使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作,同时减少操作硬件的次数。

缓存区(Cache):核心作用是加快取用的速度。在CPU与内存间设置了作为CPU的数据快取区。解决CPU运算速度太快导致内存的数据存取速度无法跟上CPU速度的问题。

软解析:首先判断是否存在数据缓冲区,如果存在且可用,则直接获取该数据而不是从数据文件中去查询。

硬解析:若数据不在缓冲区缓存中,查看数据缓冲区块头是否有事务(数据缓冲区有事务,称为热点块)。如果有,则需要从回滚段(undo)中读取数据,(一致性读取,逻辑读)。如果没有,则比较select的SCN和热点块的SCN号码,如果前者小于后者则仍需要从undo回滚段中读取,如果前者大于后者说明这是一段非脏数据缓存,直接读取就可以。

3.2 处理过程

将mysql数据库的sql转换为达梦数据库的sql 达梦数据库导出sql文件_系统架构_03

(1) 连接数据库,由连接器负责跟客户端建立连接、获取权限、维持和管理连接。

        首先,客户端通过TCP协议与数据库端口建立连接,此时监听线程dm_lsnr_thd在服务器端口上进行循环监听,一旦有来自客户的连接请求,监听线程被唤醒并生成一个会话申请任务,加入工作线程dm_wrkgrp_thd的任务队列,等待工作线程进行处理。

(2) 语法检查

        主要是对SQL语句的语法和拼写进行检查,看其是否合乎语法规则。不符合则不再进行,直接返回语法错误。

(3) 语义检查

        检查SQL语句中的访问对象是否存在及该用户是否具备相应的权限。达梦也遵循“先解析SQL语句,把小写字母转换成大写字母再执行”的规则。先将表名字转换为大写,去对象字典中查询是否存在,如果存在进行下一步对sql语句涉及的表、字段、视图、索引等对象进行解析,如果不存在,则直接报错对象不存在返回客户端。

(4) 语句解析

        客户端会话链接缓存在达梦数据库的会话内存池 (SESS_POOL,相当Oracle的PGA中的UGA),即用户线程的信息存储到会话内存池,完成三次握手。会话建立完成以后,SQL语句通过服务器进程传递给实例,然后在共享池进行判断走软分析还是硬分析。然后通过数据字典找出该SQL语句涉及的表属于哪一个表空间,行属于表空间的哪一个数据文件中,(数据字典也是属于共享池的一个数据缓冲区),然后进行一个取行的工作,最后在NORMAL数据缓冲区中判断要取的数据是否缓存。

语句解析即分析器主要有以下任务:

  • 查询高速缓存
  • 语句合法性检查
  • 语言含义检查
  • 获得对象解析锁
  • 数据访问权限的核对
  • 确定最佳执行计划

(5) 优化器

        CBO通过计算各种可能的执行计划的“代价”,即COST,从中选用COST最低的执行方案作为实际运行方案,这里影响CBO的因素有很多,除了统计信息之外还有索引、数据分布、高水位线、聚簇因子、系统资源竞争等。CBO根据各方面因素寻找最低代价的执行计划生成最终的执行计划。

(6) 执行器。接受CBO的执行计划树,执行。

(7) 封装结果集。将执行的结果集封装后通过I/O线程缓存后返回客户端。

(8) 断开连接、释放资源。执行完毕根据相关参数设置对线程资源进行释放。

3.3 数据流向

将mysql数据库的sql转换为达梦数据库的sql 达梦数据库导出sql文件_数据库_04

当收到SQL请求时,数据从磁盘加载到内存的数据缓冲区,有三种数据流向情况:

(1) 数据库进程先在SQL缓冲区中,查找计划缓存。如果存在计划缓存,则查找结果集缓存。如果存在结果集缓存,则直接生成结果集。

(2) 数据库进程先在SQL缓冲区中,查找计划缓存。如果存在计划缓存,则查找结果集缓存。如果不存在结果集缓存,则在数据缓冲区中按照缓存的计划执行。请求SQL语句分为增删改语句和查询语句。对于SELECT查询语句,执行完缓存计划后直接生成结果集。对于INSERT/DELETE/UPDATE增删改语句,执行完缓存计划后,要进行日志刷盘,在日志缓冲区存放重做日志,将新数据从内存持久化到磁盘。

(3) 数据库进程先在SQL缓冲区中,查找计划缓存。如果不存在计划缓存,则先在字典缓冲区解析缓存计划,生成执行计划后,再将执行计划缓存回SQL缓冲区,接着按照计划执行。对于SELECT查询语句,执行完计划后直接生成结果集。对于INSERT/DELETE/UPDATE增删改语句,执行完计划后,进行日志刷盘,在日志缓冲区存放重做日志,将新数据从内存持久化到磁盘。

总结

        本文简单介绍达梦数据库的内存结构和SQL执行相关知识,帮助初学者理解SQL请求及数据在DM内存结构中如何进行加载解析输出。文中只列举部分参数,有需要可以在达梦官网下载《DM8系统管理员手册》进行阅读以及更深入的学习。