
一、DM 逻辑结构
1. 数据库与实例
在 DM7 之前版本的 DM 数据库中,“数据库”和“实例”这两个术语经常可以互相替换,意义也很相近。在 DM7 以及之后版本的数据库中,“数据库”和“实例”这两个概念之间有着很大的差别,甚至可以说它们是两个完全不同的实体。
1.1 数据库
当同时出现 DM 数据库和实例时,DM 数据库指的是磁盘上存放在 DM 数据库中的数据的集合,包括数据文件(.DBF)、控制文件(.CTL)、重做日志文件(.LOG)等。
1.2 实例
实例一般是由一组正在运行的后台进程/线程(如监听、工作线程)和共享内存区域(如内存池)组成。实例是操作 DM 数据库的一种手段,是用来访问数据库的内存结构以及后台进程的集合。
DM 数据库存储在服务器的磁盘上,而 DM 实例则存储于服务器的内存中。通过运行 DM实例,可以操作 DM 数据库中的内容。在任何时候,一个实例只能与一个数据库进行关联(装载、打开或者挂起数据库)。
2. DM 逻辑存储结构
达梦数据库的逻辑结构以“数据文件-表空间-段-簇-页”为核心层级,实现数据的有序存储与高效管理。
DM 数据库为数据库中的所有对象分配逻辑空间,并存放在数据文件中。在 DM 数据库内部,所有的数据文件组合在一起被划分到一个或者多个表空间中,所有的数据库内部对象都存放在这些表空间中。同时,表空间被进一步划分为段、簇和页(也称块)。通过这种细分,可以使得 DM 数据库能够更加高效地控制磁盘空间的利用率。

从上图可以看出,在 DM8 中存储的层次结构如下:
1.数据库由一个或多个表空间组成;
2.每个表空间由一个或多个数据文件组成;
3.每个数据文件由一个或多个簇组成;
4.段是簇的上级逻辑单元,一个段可以跨多个数据文件;
5.簇由磁盘上连续的页组成,一个簇总是在一个数据文件中;
6.页是数据库中最小的分配单元,也是数据库中使用的最小的 IO 单元。
2.1表空间
在 DM 数据库中,表空间由一个或者多个数据文件组成。表空间是数据库中逻辑存储的最高层,所有用户对象(表、索引、临时表等)在逻辑上均存放在表空间中,而物理上分布于所属表空间的数据文件。
DM数据库初始化时自动创建5个核心表空间:SYSTEM 表空间、ROLL 表空间、RLOG 表空间、MAIN 表空间和 TEMP 表空间。
1.SYSTEM 表空间:存储数据库字典信息(如表结构、索引定义),用户不可在此创建表或索引;
2.ROLL 表空间:存储事务DML操作前的数据快照,保障读一致性(由数据库自动维护,无需用户干预);
3.RLOG 表空间:初始化库时会自动创建 2 个后缀名为 log 的日志文件,用于存放重做日志,用户可主动添加日志文件或者扩展日志文件,日志文件包括当前活动日志文件及非活动日志文件,当前日志文件写满后系统会自动切换到下一个日志文件,日志文件可循环使用;
4.MAIN 表空间:用户默认表空间,用于存放业务数据(若创建用户未指定默认表空间,则默认使用MAIN);在初始化库时候,会自动创建一个大小为 128M 的数据文件 MAIN.DBF,同时创建一个 HMAIN 目录作为 HUGE 数据文件路径,因此 MAIN 表空间为混合表空间。
5.TEMP 表空间:存放临时数据(如排序中间结果、临时表),不记录redo日志。
每一个用户都有一个默认的表空间。对于 SYS、SYSSSO、SYSAUDITOR 系统用户,默认的用户表空间是 SYSTEM,SYSDBA 系统用户的默认表空间为 MAIN。
新创建的用户如果没有指定默认表空间,则系统自动指定 MAIN 表空间为用户默认的表空间。一般情况下,建议用户自己创建一个表空间来存放业务数据,或者将数据存放在默认的用户表空间 MAIN 中。
用户可以通过查询动态视图 V$TABLESPACE即执行如下语句来查看 SYSTEM、ROLL、MAIN 以及 TEMP 的表空间相关信息(除 RLOG 表空间外其他所有表空间的信息):
SELECT * FROM V$TABLESPACE;
通过查询动态视图 V$DATAFILE 得到系统中除 RLOG 表空间外所有数据文件的信息,通过以下查询可以得到表空间上对应的数据文件:
SELECT ts.NAME, df.PATH FROM V$TABLESPACE ts, V$DATAFILE AS df WHERE ts.ID = df.GROUP_ID;
用户可以通过执行如下语句来查看 RLOG 表空间相关信息:
SELECT * FROM V$RLOG; --查看日志空间信息
SELECT * FROM V$RLOGFILE; --RLOG文件信息
SELECT * FROM V$LOG_HISTORY; --日志文件切换历史
2.2段
段(seg)是簇的上级逻辑分区单元,它由一组簇组成。
在同一个表空间中,段可以包含来自不同文件的簇,即一个段可以跨越不同的文件。
2.2.1数据段
段可以被定义成特定对象的数据结构,如表数据段或索引数据段。
表中的数据以表数据段结构存储,索引中的数据以索引数据段结构存储。
DM 以簇为单位给每个数据段分配空间,当数据段的簇空间用完时,DM 数据库就给该段重新分配簇,段的分配和释放完全由 DM 数据库自动完成,可以在创建表/索引时设置存储参数来决定数据段的簇如何分配。
2.2.2临时段
在 DM 数据库中,所有的临时段都创建在临时表空间中,这样可以分流磁盘设备的 I/O,也可以减少由于在 SYSTEM 或其他表空间内频繁创建临时数据段而造成的碎片。
当处理一个查询时,经常需要为 SQL 语句的解析与执行的中间结果准备临时空间。DM 数据库会自动地分配临时段的磁盘空间。例如,DM 在进行排序操作时就可能需要使用临时段,当排序操作可以在内存中执行,或设法利用索引就可以执行时,就不必创建临时段。对于临时表及其索引,DM 数据库也会为它们分配临时段。
临时段的分配和释放完全由系统自动控制,用户不能手工进行干预。
2.2.3回滚段
DM 数据库在回滚表空间的回滚段中保存了用于恢复数据库操作的信息。对于未提交事务,当执行回滚语句时,回滚记录被用来做回滚变更。在数据库恢复阶段,回滚记录被用来做所有未提交变更的回滚。在多个并发事务运行期间,回滚段还为用户提供读一致性,所有正在读取受影响行的用户将不会看到行中的任何变动,直到他们事务提交后发出新的查询。
2.3簇
簇(extent)是数据页的上级逻辑单元,由同一个数据文件中 16 个或 32 个或 64 个连续的数据页组成。在 DM 数据库中,簇的大小由用户在创建数据库时指定,默认大小为 16。一旦创建好数据库,此后该数据库的簇的大小就不能够改变。可以类比与Oracle的区。假定某个数据文件大小为 32MB,页大小为 8KB,则共有 32MB/8KB/16=256 个簇,每个簇的大小为 8KB*16=128KB。
2.4页

数据页(也称数据块)(page)是DM数据库中最小的数据存储单元。可以类比与Oracle的块。
页大小可在创建数据库时指定(4KB、8KB、16KB、32KB,默认8KB),一旦创建好了数据库,则在该库的整个生命周期内,页大小都不能改变。
数据页结构包含页头(控制信息,如页类型、页地址)、数据区(存储记录)、空闲空间(用于记录增长)、行偏移数组(标识页内空间占用情况)。
2.5记录
数据库表中的每一行是一条记录。在 DM 中,除了 HUGE 表,其他的表都是在数据页中按记录存储数据的。
记录是存储在数据页中的,由于记录不能跨页存储,这样记录的长度就受到数据页大小的限制。数据页中还包含了页头控制信息等空间,因此DM 规定每条记录长度不能超过页大小的一半(若超过需启用“超长列”特性)。
二、DM物理结构
DM数据库将用户数据存放在磁盘的物理存储结构上。达梦数据库的物理结构由配置文件、控制文件、数据文件、重做日志文件、归档日志文件等组成,共同保障数据的持久性与可恢复性。

1.配置文件
配置文件是 DM 数据库用来设置功能选项的一些文本文件的集合,分为服务器配置文件和客户端配置文件两类。
客户端配置文件为 dm_svc.conf,用户可以在该文件中为 JDBC 等接口以及 Disql 等工具配置连接参数,或者启用/禁用客户端特定功能项。
服务器配置文件以 INI 为扩展名,具有固定的格式,用户可以通过修改其中的某些参数取值来达成如下两个方面的目标:
(1)启用/禁用特定功能项;
(2)针对当前系统运行环境设置更优的参数值以提升系统性能。
1.1服务器配置文件
1.1.1dm.ini
每创建一个 DM 数据库,就会自动生成 dm.ini 参数文件。文件路径在数据库安装目录下。相关参数内容详见《DM8系统管理员手册》第一部分内容。
dm.ini 是 DM 数据库启动所必须的配置文件,通过配置该文件可以设置 DM 数据库服务器的各种功能和性能选项,主要的配置模块包括:控制文件相关、实例名、内存相关、线程相关等。
参数属性分为三种:手动、静态和动态。
手动,不能被动态修改,必须手动修改 dm.ini 参数文件,然后重启才能生效。
静态,可以被动态修改,修改后重启服务器才能生效。
动态,可以被动态修改,修改后即时生效。动态参数又分为SYS/SESSIOIN系统级和会话级两种。会话级参数被修改后,新参数值只会影响当前会话和新创建的会话,之前创建的会话不受影响;系统级参数的修改则会影响所有的会话。
其中,动态修改是指 DBA 用户可以在数据库服务器运行期间,调用系统过程
SP_SET_PARA_VALUE()
SP_SET_PARA_DOUBLE_VALUE()
SP_SET_PARA_STRING_VALUE()对参数值进行修改。
当动态修改 dm.ini 参数文件时,如果遇到磁盘空间不足导致系统崩溃的情况,需要手动使用 dm.ini 文件所在目录下的dm.ini.dmbak 文件恢复 dm.ini,并重启服务器。
-- 查看参数信息
select * from v$dm_ini where “V$DM_INI”.PARA_NAME like UPPER(‘参数关键字’)||‘%’ ;
1.1.2dmmal.ini
dmmal.ini 是 MAL 系统的配置文件。dmmal.ini 的配置项详见《DM8系统管理员手册》第一部分内容。需要用到 MAL 环境的实例,所有站点 dmmal.ini 需要保证严格一致。
MAL系统是DM内部高速通信系统,基于TCP/IP协议实现。服务器的很多重要功能都是通过MAL系统实现通信的,例如数据守护、数据复制、MPP、远程日志归档等。MAL系统内部包含一系列线程,有MAL监听线程、MAL发送工作线程、MAL接收工作线程等。
注意:dmmal.ini 和 dm.ini 中都可配置 MAL_LEAK_CHECK,启动时以 dmmal.ini 中设置为准,如果 dmmal.ini 中没有配置,则以 dm.ini 中配置为准,两个都没配置时,则默认 0。此参数在 dm.ini 中可动态更改。
1.1.3dmarch.ini
dmarch.ini 为归档配置文件,用于配置归档,设置归档模式(本地/远程)、归档路径、归档文件保留策略。
1.1.4sqllog.ini
sqllog.ini 在 dm.ini 参数 SVR_LOG=1 时启用。
如果在服务器启动过程中,修改了 sqllog.ini 文件,须调用过程 SP_REFRESH_SVR_LOG_CONFIG()才会生效。
sqllog.ini 配置文件的内容分为全局配置区和模式配置区。
1.1.5dmthrd.ini
dmthrd.ini 用于为线程类型绑定 CPU 核心,当且仅当 INI 参数 DMTHRD_INI=1 时使用。
1.1.6dmtimer.ini
dmtimer.ini 用于配置定时器,用于数据守护中记录异步备库的定时器信息中记录异步复制的定时器信息。
1.2客户端配置文件
dmtimer.ini 用于配置定时器,用于数据守护中记录异步备库的定时器信息中记录异步复制的定时器信息。
1.2.1 dm_svc.conf
dm_svc.conf 是一个客户端配置文件,它包含了 DM 各接口和客户端工具所需要配置的一些参数。它必须和接口/客户端工具位于同一台机器上才能生效。
2.控制文件
每个 DM 数据库都拥有两个控制文件,即 dm.ctl 和 dmtemp.ctl 控制文件,控制文件均为二进制文件。
创建数据库时按照 CTL_PATH 参数自动创建 dm.ctl 控制文件,首次启动数据库时自动在 dm.ctl 所在目录下创建 dmtemp.ctl 控制文件。
dm.ctl 用于记录数据库必要的初始信息
dmtemp.ctl 用于记录临时表空间相关信息,主要包括临时表空间名以及临时表空间物理文件路径等。
2.1 dm.ctl
dm.ctl 用于记录数据库必要的初始信息,主要包含以下内容:
1.数据库名称;
2.数据库服务器模式;
3.OGUID 唯一标识;
4.数据库服务器版本;
5.数据文件版本;
6.数据库的启动次数;
7.数据库最近一次启动时间;
8.表空间信息,包括表空间名,表空间物理文件路径等,记录了所有数据库中使用的表空间,数组的方式保存起来;
9.控制文件校验码,校验码由数据库服务器在每次修改控制文件后计算生成,保证控制文件合法性,防止文件损坏及手工修改。
2.2 dmtemp.ctl
dmtemp.ctl 用于记录临时表空间相关信息,主要包括临时表空间名以及临时表空间物理文件路径等。
3.数据文件
数据文件以 DBF 为扩展名,它是数据库中最重要的文件类型,一个 DM 数据文件对应磁盘上的一个物理文件或者达梦分布式数据库中的一个逻辑文件,数据文件是真实数据存储的地方。
数据文件按数据组织形式,可以分为如下几种:
1.B树数据
行存储数据,也是应用最广泛的存储形式,其数据是按 B 树索引组织的。普通表、分区表、B 树索引的物理存储格式都是 B 树。
一个 B 树包含两个段,一个内节点段,存放内节点数据;一个叶子段,存放叶子节点数据。其 B 树的逻辑关系由段内页面上的记录,通过文件指针来完成。
当表上没有指定聚集索引时,系统会自动产生一个唯一标识 ROWID 作为 B 树的 key 来唯一标识一行。
2.堆表数据
堆表的数据是以挂链形式存储的,一般情况下,支持最多 128 个链表,一个链表在物理上就是一个段,堆表采用的是物理 ROWID,在插入过程中,ROWID 在事先已确定,并保证其唯一性,所以可以并发插入,插入效率很高,且由于 ROWID 是即时生成,无需保存在物理磁盘上,也节省了空间。
3.列存储数据
数据按列方式组织存储,包含每个列对应的存放列数据的一系列数据文件,以及存放列数据控制信息的辅助表。读取列数据时,只需要顺序扫描列数据文件和辅助表数据。在某些特殊应用场景下,其效率要远远高于行存储。
4.位图索引
位图索引与 B 树索引不同,每个索引条目不是指向一行数据,而是指向多行数据。每个索引项保存的是一定范围内所有行与当前索引键值映射关系的位图。
数据文件中还有两类特殊的数据文件:ROLL 和 TEMP 文件:
(1)ROLL文件
ROLL 表空间的 DBF 文件,称为 ROLL 文件。ROLL 文件用于保存系统的回滚记录,提供事务回滚时的信息。回滚文件可被分为若干回滚段,每个事务的回滚页在回滚段中各自挂链,
页内则顺序存放回滚记录。
(2)TEMP文件
TEMP.DBF 临时数据文件,临时文件可以在 dm.ini 中通过 TEMP_SIZE 配置大小。
当数据库查询的临时结果集过大,缓存已经不够用时,临时结果集就可以保存在
TEMP.DBF 文件中,供后续运算使用。系统中用户创建的临时表也存储在临时文件中。
4.重做日志(REDO)文件
重做日志(即 REDO 日志)因为是数据库正在使用的日志文件,也被称为联机日志文件。重做日志文件默认以 log 为扩展名。
重做日志文件用于存储数据库的事务日志,在 DM 数据库中添加、删除、修改对象,或者改变数据的任何修改操作,DM 都会按照特定的格式,将这些操作执行的结果写入到当前的重做日志文件中。以便系统在出现系统故障和介质故障时能够进行故障恢复。当系统出现故障时,通过分析日志可以知道在故障发生前系统做了哪些动作,并可以重做这些动作使系统恢复到故障之前的状态。
重做日志文件主要用于数据库的备份与恢复。比如电源故障、系统故障、介质故障,或者数据库实例进程被强制终止等,数据库缓冲区中的数据页会来不及写入数据文件。这样,在重启 DM 实例时,通过重做日志文件中的信息,就可以将数据库的状态恢复到发生意外时的状态。
5.归档日志文件
日志文件分为联机日志文件和归档日志文件。
DM 数据库可以在归档模式和非归档模式下运行。
非归档模式下,数据库会只将重做日志写入联机日志文件中进行存储;
归档模式下,数据库会同时将重做日志写入联机日志文件和归档日志文件中分别进行存储。
联机日志文件指的是系统当前正在使用的日志文件。对日志文件的写入是顺序连续的。
当所有联机日志文件空间被占满时,系统需要清空一部分日志以便重用日志文件的空间,为了保证被清空的日志所“保护”的数据在磁盘上是安全的,引入了“检查点”的概念,当产生检查点时,系统将系统缓冲区中的日志和脏数据页都写入磁盘,以保证当前日志所“保护”的数据页都已安全写入磁盘,这样日志文件即可被安全重用。
归档日志文件,就是在归档模式下,重做日志被连续写入到归档日志后,所生成了归档
日志文件。只有在归档模式下运行时,DM 数据库才会将重做日志写入到归档日志文件中。采用归档模式会对系统的性能产生影响,然而系统在归档模式下运行会更安全,当出现故障时其丢失数据的可能性更小,这是因为一旦出现介质故障,如磁盘损坏时,利用归档日志,系统可被恢复至故障发生的前一刻,也可以还原到指定的时间点,而如果没有归档日志文件,则只能利用备份进行恢复。
6.物理逻辑日志文件
物理逻辑日志,是按照特定的格式存储的服务器的逻辑操作,专门用于 DBMS_LOGMNR包挖掘获取数据库系统的历史执行语句。当开启记录物理逻辑日志的功能时,这部分日志内容会被存储在重做日志文件中。
7.备份文件
备份文件以 bak 为扩展名,当客户利用管理工具或直接发出备份的 SQL 命令时,DM Server 会自动进行备份,并产生一个或多个备份文件,备份文件自身包含了备份的名称、对应的数据库、备份类型和备份时间等信息。同时,系统还会自动记录备份信息及该备份文件所处的位置,但这种记录是松散的,用户可根据需要将其拷贝至任何地方,并不会影响系统的运行。
8.SQL日志文件
用户在 dm.ini 中配置 SVR_LOG 参数后就会打开 SQL 日志。
SQL 日志文件是一个纯文本文件。命名格式为“dmsql_实例名[_模式名][_用户名][_日期_间].log”。
SQL 日志文件缺省生成在 DM 安装目录的 log 子目录下面,管理员可通过 sqllog.ini 参数 FILE_PATH 设置其生成路径。
SQL 日志内容包含系统各会话上用户执行的 SQL 语句、参数信息、错误信息等。跟踪日志主要用于分析错误和分析性能问题,基于跟踪日志可以对系统运行状态有一个分析,比如,可以挑出系统现在执行速度较慢的 SQL 语句,进而对其进行优化。
打开 SQL 日志会影响系统的性能,因此一般在需要查错和调优的时候才会打开。缺省情
况下系统是关闭 SQL 日志的。
9.事件日志文件
事件日志文件记录了 DM 数据库运行时的关键事件。例如:系统启动、关闭、内存申请失败、IO 错误等一些致命错误;数据库运行过程中的日志信息;备份还原过程中备份还原操作的阶段性信息等。
事件日志文件主要用于系统出现严重错误时进行查看并定位问题。事件日志简称 ELOG。
事件日志文件随着 DM 数据库服务的运行一直存在。
事件日志文件打印的是中间步骤的信息,所以出现部分缺失属于正常现象。
系统启动和运行过程中产生的 ELOG 保存在系统 log 目录下。
三、DM内存结构

1.内存池
内存池包括共享内存池和其他一些运行时内存池。
动态视图 V$MEM_POOL详细记录了当前系统中所有的内存池的状态,可以通过查询这个动态视图掌握 DM Server 的内存使用情况。
1.1共享内存池
共享内存池是 DM Server 在启动时从操作系统申请的一大片内存。
在 DM Server 的运行期间,经常会申请与释放小片内存,而直接向操作系统申请和释放内存时需要发出系统调用,此时可能会引起线程切换,降低系统运行效率。于是 DM 采用共享内存池的方式:一次向操作系统申请一片较大内存,作为共享内存池。当系统在运行过程中需要申请小片内存时,可在共享内存池内进行申请,当用完该内存时,再释放掉,即归还给共享内存池。
DM 系统管理员可以通过 DM Server 的配置文件(dm.ini)来对共享内存池的大小进行设置,共享池大小的参数为 MEMORY_POOL,缺省大小为 500MB。如果在运行时所需内存大于配置值,共享内存池也可进行自动扩展,INI 参数 MEMORY_EXTENT_SIZE 指定了共享内存池每次扩展的大小,参数 MEMORY_TARGET 则指定了共享内存池扩展到超过该值后,空闲时会收缩到的大小。
MEMORY_POOL 决定了M为单位的共享内存池的大小,MEMORY_POOL 是静态参数,所以不能直接修改内存中的数值。只能修改 dm.ini 中的数值,然后重启生效。
1.2运行时内存池
除了共享内存池,DM Server 的一些功能模块在运行时还会使用自己的运行时内存池。这些运行时内存池是从操作系统申请一片内存作为本功能模块的内存池来使用,如会话内存池、虚拟机内存池等。
2.缓冲区
缓冲区是数据写入磁盘的“中转站”,是内存池的核心组件,用于缓存磁盘数据,减少物理I/O次数。
2.1数据缓冲区
数据缓冲区是 DM Server 在将数据页写入磁盘之前以及从磁盘上读取数据页之后,数据页所存储的地方。对应Oracle的database buffer cache。
系统启动时,首先根据配置的数据缓冲区大小向操作系统申请一片连续内存并将其按数据页大小进行格式化,并置入自由链中。数据缓冲区存在三条链来管理被缓冲的数据页,
一条是自由链,用于存放目前尚未使用的内存数据页,
一条是 LRU 链,用于存放已被使用的内存数据页(包括未修改和已修改),
还有一条即为脏链,用于存放已被修改过的内存数据页。
缓存从数据文件读取的数据页(热数据),提高查询性能。其大小由BUFFER参数设置(默认占总内存的60%~80%),采用LRU(最近最少使用)算法管理(淘汰不常用的数据页)。
LRU 链对系统当前使用的页按其最近是否被使用的顺序进行了排序。这样当数据缓冲区中的自由链被用完时,从 LRU 链中淘汰部分最近未使用的数据页,能够较大程度地保证被淘汰的数据页在最近不会被用到,减少 IO。
在系统运行过程中,通常存在一部分“非常热”(反复被访问)的数据页,将它们一直留在缓冲区中,对系统性能会有好处。对于这部分数据页,数据缓冲区开辟了一个特定的区域用于存放它们,以保证这些页不参与一般的淘汰机制,可以一直留在数据缓冲区中。
1.类别
DM Server 中有四种类型的数据缓冲区,分别是 NORMAL、KEEP、FAST 和 RECYCLE。
其中,用户可以在创建表空间或修改表空间时,指定表空间属于 NORMAL 或 KEEP 缓冲区。RECYCLE 缓冲区供临时表空间使用,FAST 缓冲区根据用户指定的 FAST_POOL_PAGES 大小由系统自动进行管理,用户不能指定使用 RECYCLE 和 FAST 缓冲区的表或表空间。
NORMAL 缓冲区主要是提供给系统处理的一些数据页,没有特定指定缓冲区的情况下,默认缓冲区为 NORMAL;KEEP 的特性是对缓冲区中的数据页很少或几乎不怎么淘汰出去,主要针对用户的应用是否需要经常处在内存当中,如果是这种情况,可以指定缓冲区为 KEEP。
DM Server 提供了可以更改这些缓冲区大小的参数,用户可以根据自己应用需求情况,指定 dm.ini 文件中 BUFFER(8000MB)、KEEP(8MB)、RECYCLE(300MB)、FAST_POOL_PAGES(3000)值(括号中为默认值),这些值分别对应是 NORMAL 缓冲区大小、KEEP 缓冲区大小、RECYCLE 缓冲区大小、FAST 缓冲区数据页总数。
2.读多页
在需要进行大量 I/O 的应用当中,DM 之前版本的策略是每次只读取一页。如果知道用户需要读取表的大量数据,当读取到第一页时,可以猜测用户可能需要读取这页的下一页,在这种情况下,一次性读取多页就可以减少 I/O 次数,从而提高了数据的查询、修改效率。
DM Server 提供了可以读取多页的参数,用户可以指定这些参数来调整数据库运行效率的最佳状态。在 DM 配置文件 dm.ini 中,可以指定参数 MULTI_PAGE_GET_NUM 大小(默认值为 1 页),来控制每次读取的页数。
2.2日志缓冲区
日志缓冲区是用于存放重做日志的内存缓冲区。为了避免由于直接的磁盘 IO 而使系统性能受到影响,系统在运行过程中产生的日志并不会立即被写入磁盘,而是和数据页一样,先将其放置到日志缓冲区中。那么为何不在数据缓冲区中缓存重做日志而要单独设立日志缓冲区呢?主要是基于以下原因:
1.重做日志的格式同数据页完全不一样,无法进行统一管理;
2.重做日志具备连续写的特点;
3.在逻辑上,写重做日志比数据页 IO 优先级更高。
DM Server 提供了参数 RLOG_BUF_SIZE 对日志缓冲区大小进行控制,日志缓冲区所占用的内存是从共享内存池中申请的,单位为页数量。
select para_name,para_value from v$dm_ini where para_name like 'RLOG_BUF_SIZE';
2.3字典缓冲区
字典缓冲区主要存储一些数据字典信息,如模式信息、表信息、列信息、触发器信息等。每次对数据库的操作都会涉及到数据字典信息,访问数据字典信息的效率直接影响到相应的操作效率,如进行查询语句,就需要相应的表信息、列信息等,这些字典信息如果都在缓冲区里,则直接从缓冲区中获取即可,否则需要 I/O 才能读取到这些信息。
DM8 采用的是将部分数据字典信息加载到缓冲区中,并采用 LRU 算法进行字典信息的控制。缓冲区大小设置问题,如果太大,会浪费宝贵的内存空间,如果太小,可能会频繁的进行淘汰,该缓冲区配置参数为 DICT_BUF_SIZE,默认的配置大小为 50MB。
DM8 采用缓冲部分字典对象,那会影响效率吗?数据字典信息访问存在热点现象,并不是所有的字典信息都会被频繁的访问,所以按需加载字典信息并不会影响到实际的运行效率。
但是如果在实际应用中涉及对分区数较多的水平分区表访问,例如上千个分区,那么就需要适当调大 DICT_BUF_SIZE 参数值。
select para_name,para_value from v$dm_ini where para_name like 'DICT_BUF_SIZE';
2.4SQL缓冲区
SQL 缓冲区提供在执行 SQL 语句过程中所需要的内存,包括计划、SQL 语句和结果集缓存。
很多应用当中都存在反复执行相同 SQL 语句的情况,此时可以使用缓冲区保存这些语句和它们的执行计划,这就是计划重用。这样带来的好处是加快了 SQL 语句执行效率,但同时给内存也增加了压力。
DM Server 在配置文件 dm.ini 提供了参数来支持是否需要计划重用,参数为 USE_PLN_POOL,当指定为非 0 时,则启动计划重用;为 0 时禁止计划重用。DM 同时还提供了参数 CACHE_POOL_SIZE(单位为 MB),来改变 SQL 缓冲区大小,系统管理员可以设置该值以满足应用需求,默认值为 0MB。
结果集缓存包括 SQL 查询结果集缓存和 DMSQL 程序函数结果集缓存,在 INI 参数文件中同时设置参数 RS_CAN_CACHE=1 且 USE_PLN_POOL 非 0 时 DM 服务器才会缓存结果集。
select para_name,para_value from v$dm_ini where para_name='USE_PLN_POOL';
客户端结果集也可以缓存,但需要在配置文件 dm_svc.conf 中设置参数:
ENABLE_RS_CACHE = (1) //表示启用缓存;
RS_CACHE_SIZE = (100) //表示缓存区的大小为100MB, 可配置为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 中,系统管理员可以设置其大小以满足需求,由于该值是由系统内部排序算法和排序数据结构决定,建议使用默认值 20MB。
select para_name,para_value from v$dm_ini where para_name like 'SORT_BUF_SIZE';
4.哈希区
DM8 提供了为哈希连接而设定的缓冲区,不过该缓冲区是个虚拟缓冲区。之所以说是虚拟缓冲,是因为系统没有真正创建特定属于哈希缓冲区的内存,而是在进行哈希连接时,对哈希连接的数据量进行了计算。如果计算出的数据量大小超过了哈希缓冲区的大小,则使用 DM8 创新的外存哈希方式;如果没有超过哈希缓冲区的大小,实际上还是使用内存池来进行哈希操作。
DM Server 在 dm.ini 中提供了参数 HJ_BUF_SIZE 来进行控制,由于该值的大小可能会限制哈希连接的效率,所以建议保持默认值,或设置为更大的值。
select para_name,para_value from v$dm_ini where para_name like 'HJ_BUF_SIZE';
除了提供 HJ_BUF_SIZE 参数外,DM Server 还提供了创建哈希表个数的初始化参数,其中,HAGR_HASH_SIZE 表示处理集函数时创建哈希表的个数,建议保持默认值 100000。
select para_name,para_value from v$dm_ini where para_name like 'HAGR_HASH_SIZE';
四、管理 DM 线程
达梦数据库采用单进程多线程模型,通过操作系统线程实现并发处理,所有线程均由dmserver主进程创建和管理。线程分工明确,协同完成连接处理、数据操作、IO管理、定时任务等功能,是DM高性能、高并发的核心支撑。
DM 进程中主要包括监听线程、IO 线程、工作线程、调度线程、日志线程等。
-- 查看服务器进程信息:
select * from V$PROCESS;
-- 查看当前系统中活动线程的信息:
select * from V$THREADS;
1.监听线程
核心职责:在服务器指定端口(默认5236)上循环监听客户端连接请求。当接收到请求时(如disql、JDBC连接),生成会话申请任务并加入工作线程任务队列,等待工作线程处理。监听线程优先级较高,确保快速响应连接请求。
关键特性:
系统启动后启动,关闭时优先终止;
优先级高于普通线程,确保快速响应大量并发连接;
客户端连接由操作系统自动分配端口(范围1024-65534),分布式数据库节点间通信也通过此线程处理。
2.工作线程
工作线程是 DM 服务器的核心线程,负责服务器各种类型任务的处理及所有实际的数据相关操作。工作线程包括任务工作线程和会话工作线程等。
任务工作线程负责处理服务器内部生成并加入对应任务队列的各项任务,如调度线程生成的清理缓存任务、异步执行的任务等,其初始个数由 INI 参数 TASK_THREADS 指定。任务工作线程空闲时从任务队列依次摘取任务并进行处理,当任务队列中的任务堆积时,系统会增加任务工作线程数量以减少任务堆积。
会话工作线程负责处理会话的请求任务,分为非线程池模式和线程池模式,由 INI 参数 STHD_FLAG 控制。非线程池模式下每一个会话对应一个会话工作线程,一个会话上的任务全部由同一个工作线程完成,这样减少了线程切换的代价,提高了系统效率。线程池模式初始工作线程个数由 INI 参数 WORKER_THREADS*STHD_THREAD_NUM 指定,由会话轮询线程接收所有用户请求,加入会话任务队列,会话工作线程从会话任务队列依次摘取请求任务进行处理。
3.IO线程
在数据库活动中,IO 操作历来都是最为耗时的操作之一。当事务需要的数据页不在缓冲区中时,如果在工作线程中直接对那些数据页进行读写,将会使系统性能变得非常糟糕,而把 IO 操作从工作线程中分离出来则是明智的做法。IO 线程的职责就是处理这些 IO 操作。
通常情况下,DM Server 需要进行 IO 操作的时机主要有以下三种:
(1)需要处理的数据页不在缓冲区中,此时需要将相关数据页读入缓冲区;
(2)缓冲区满或系统关闭时,此时需要将部分脏数据页写入磁盘;
(3)检查点到来时,需要将所有脏数据页写入磁盘。
IO 线程在启动后,通常都处于睡眠状态,当系统需要进行 IO 时,只需要发出一个 IO 请求,此时 IO 线程被唤醒以处理该请求,在完成该 IO 操作后继续进入睡眠状态。
IO 线程的个数是可配置的,可以通过设置 dm.ini 文件中的 IO_THR_GROUPS 参数来设置,默认情况下,IO 线程的个数是 2 个。
4.调度线程
调度线程用于接管系统中所有需要定时调度的任务。调度线程每秒钟轮询一次,负责的任务有以下一些:
(1)检查系统级的时间触发器,如果满足触发条件则生成任务加到任务工作线程的任务队列由任务工作线程执行;
(2)清理 SQL 缓存、计划缓存中失效的项,或者超出缓存限制后淘汰不常用的缓存项;
(3)执行动态缓冲区检查。根据需要动态扩展或动态收缩系统缓冲池;
(4)自动执行检查点。为了保证日志的及时刷盘,减少系统故障时恢复时间,根据 INI 参数设置的自动检查点执行间隔定期执行检查点操作;
(5)会话超时检测。当客户连接设置了连接超时时,定期检测是否超时,如果超时则自动断开连接;
(6)必要时执行数据更新页刷盘;
(7)唤醒等待的工作线程。
5.日志FLUSH线程
任何数据库的修改,都会产生重做 REDO 日志,为了保证数据故障恢复的一致性,REDO 日志的刷盘必须在数据页刷盘之前进行。事务运行时,会把生成的 REDO 日志保留在日志缓冲区中,当事务提交或者执行检查点时,会通知 FLUSH 线程进行日志刷盘。由于日志具备顺序写入的特点,比数据页分散 IO 写入效率更高。日志 FLUSH 线程和 IO 线程分开,能获得更快的响应速度,保证整体的性能。DM8 的日志 FLUSH 线程进行了优化,在刷盘之前,对不同缓冲区内的日志进行合并,减少了 IO 次数,进一步提高了性能。
如果系统配置了实时归档,在 FLUSH 线程日志刷盘前,会直接将日志通过网络发送到实时备库。如果配置了本地归档,则生成归档任务,通过日志归档线程完成。
6.日志归档线程
日志归档线程包含异步归档线程,负责远程异步归档任务。如果配置了非实时归档,由日志 FLUSH 线程产生的任务会分别加入日志归档线程,日志归档线程负责从任务队列中取出任务,按照归档类型做相应归档处理。
将日志 FLUSH 线程和日志归档线程分开的目的是为了减少不必要的效率损失,除了远程实时归档外,本地归档、远程异步归档都可以脱离 FLUSH 线程来做,如果放在 FLUSH 线程中一起做会严重影响系统性能。
7.日志 APPLY 线程
在配置了数据守护的系统中,创建了一个日志 APPLY 线程。当服务器作为备库时,每次接收到主库的物理 REDO 日志生成一个 APPLY 任务加入到任务队列,APPLY 线程从任务队列中取出一个任务在备库上将日志重做,并生成自己的日志,保持和主库数据的同步或一致,作为主库的一个镜像。备库数据对用户只读,可承担报表、查询等任务,均衡主库的负载。
8.定时器线程
在数据库的各种活动中,用户常常需要数据库完成在某个时间点开始进行某种操作,如备份;或者是在某个时间段内反复进行某种操作等。定时器线程就是为这种需求而设计的。
通常情况下,DM Server 需要进行定时操作的事件主要有以下几种:
(1)逻辑日志异步归档;
(2)异步归档日志发送(只有在 PRIMARY 模式下,且是 OPEN 状态下);
(3)作业调度。
定时器线程启动之后,每秒检测一次定时器链表,查看当前的定时器是否满足触发条件,如果满足,则把执行权交给设置好的任务,如逻辑日志异步归档等。
默认情况下,达梦服务器启动的时候,定时器线程是不启动的。用户可以设置 dm.ini 中的 TIMER_INI 参数为 1 来设置定时器线程在系统启动时启动。
9.MAL 系统相关线程
MAL 系统是 DM 内部高速通信系统,基于 TCP/IP 协议实现。服务器的很多重要功能都是通过 MAL 系统实现通信的,例如数据守护、MPP、远程日志归档等。MAL 系统内部包含一系列线程,有 MAL 监听线程、MAL 发送工作线程、MAL 接收工作线程等。
10.其他线程
除上述核心线程外,DM还有处理特定功能的线程:
PURGE线程:清理回滚段(ROLL表空间),删除过期的事务旧数据,维护读一致性;
审计写文件线程:将审计日志写入审计文件(.AUDIT),记录用户操作(如SQL执行、登录);
重演捕获写文件线程:将数据重演。
五、达梦与Oracle体系架构对比
1. 整体架构模式
Oracle:采用多进程结构,由多个独立的操作系统进程组成(如PMON、SMON、DBWR、LGWR等后台进程),每个进程负责特定的功能(如进程监控、系统恢复、数据写入、日志写入)。这种模式的优势是进程间隔离性好,但进程创建和管理的开销较大。
达梦:采用单进程多线程结构,所有后台功能(如监听、工作线程、IO线程、日志线程)均集成在dmserver单一进程中,通过线程实现并发处理。这种模式减少了进程切换的开销,提升了内存利用率,更适合高并发场景。
2. 内存管理机制
Oracle:内存结构分为SGA(系统全局区)和PGA(程序全局区)。SGA是所有进程共享的内存区域,包含数据库缓存(DB Cache)、共享池(Shared Pool)、日志缓冲区(Log Buffer)等组件,用于缓存数据和SQL执行计划;PGA是每个进程的私有内存区域,存储会话状态、排序数据等。Oracle 10g及以上版本支持自动内存管理(AMM),可动态调整SGA和PGA的大小。
达梦:内存结构更简洁,采用多级缓冲池体系(如数据缓冲池、日志缓冲池、SQL执行计划缓存),支持动态内存调整(在线增减缓冲池大小)和智能缓存淘汰(基于LRU-K算法,优先淘汰长期未使用的缓存)。此外,达梦的PGA设计更轻量化,减少了私有内存的占用。
3. 存储引擎设计
Oracle:传统上采用单一存储引擎(行存储),数据按行组织(堆表),适合OLTP场景(高并发事务处理)。Oracle 12c及以上版本支持索引组织表(IOT),将数据按主键索引存储,优化等值查询,但仍以行存储为主。
达梦:采用双存储引擎架构(行存储+列存储),可根据业务场景灵活选择:
(1) 行存储引擎:优化OLTP场景(如订单处理、用户注册),支持高并发插入和更新;
(2) 列存储引擎:优化OLAP场景(如数据报表、数据分析),通过列式存储减少IO和提升聚合查询性能。
这种混合架构实现了HTAP(混合事务分析处理),一套系统同时支撑OLTP和OLAP业务,降低了数据同步成本。
4. 进程/线程管理
Oracle:后台进程是独立于实例的操作系统进程,需单独管理和监控(如PMON负责进程监控、SMON负责系统恢复、DBWR负责数据写入)。监听进程(Listener)也是独立的,负责接收客户端连接请求。
达梦:后台功能均以线程形式运行在dmserver进程中,无需单独管理。例如:
监听线程(dm_lsnr_thd):集成在dmserver中,负责客户端连接;工作线程:处理SQL执行和事务;IO线程:负责数据文件的读写。
这种设计简化了运维复杂度,提升了进程间的通信效率。
5. 状态切换机制
Oracle:数据库实例的状态切换有严格限制,例如:
只能从NOMOUNT→MOUNT→OPEN依次启动;
不能从OPEN状态直接切换到MOUNT状态(需先关闭再启动到MOUNT);
无专门的“挂起”状态。
达梦:状态切换更灵活,支持:
MOUNT与OPEN状态自由切换;
新增SUSPEND(挂起)状态:数据库处于只读模式,无法执行写操作,但可快速恢复到OPEN状态。这种设计便于维护(如备份时挂起数据库)和故障排查。
6. 日志与恢复机制
Oracle:采用循环写的redo log文件(每组多个成员,冗余存储),启用归档模式后,满的redo log文件会被复制到归档目录(用于介质恢复)。恢复时通过redo log重做已提交事务,回滚未提交事务。
达梦:redo log机制与Oracle类似,但可直接扩容日志文件大小(无需添加新文件替换旧文件),简化了日志管理。此外,达梦的数据守护集群(Data Guard)支持实时归档和即时归档,主库日志同步到备库,实现故障自动切换(Active Data Guard可读),提升了数据可靠性。
7. 用户与模式管理
Oracle:用户与模式一一对应(一个用户对应一个模式),模式是用户的所有数据库对象的集合(如表、视图、存储过程)。创建用户时,会自动生成同名模式。
达梦:用户与模式一对多(一个用户可拥有多个模式,一个模式仅归属于一个用户)。创建用户时,会自动生成对应模式,但用户可额外创建其他模式。这种设计更灵活,适合多租户场景(如不同业务模块使用不同模式,但归属同一用户)。
8. 高可用性架构
Oracle:高可用方案包括:
RAC(Real Application Clusters):多节点集群,共享存储(如ASM),实现负载均衡和故障无缝切换;
Data Guard:实时数据同步,支持故障自动切换(Active Data Guard可读);
ASM(Automatic Storage Management):自动存储管理,虚拟化磁盘资源,支持动态扩展。
达梦:高可用方案更贴合国产化需求,包括:
DSC(共享存储集群):多活架构,所有节点可同时读写,通过缓存融合(RDMA高速同步)和分布式锁管理(全局锁表GLT)实现一致性;
数据守护集群:实时归档+备库同步,支持自动故障切换;
分布式集群:分片+负载均衡,支持水平扩展(如DM8的分布式事务集群)。这些方案均实现了无单点故障,提升了系统的可用性。
达梦社区地址:https://eco.dameng.com
4734

被折叠的 条评论
为什么被折叠?



