达梦数据库(DM)体系结构详解
1) 了解DM逻辑存储结构包含哪些,各结构含义及之间的关系;
2) 了解DM物理存储结构,每种物理文件的功能;
3) 了解DM内存结构有哪些,每种内存结构的功能;
4)了解DM线程结构,了解DM单线程与多线程,线程有哪些,每种线程的功能。
1. DM逻辑存储结构
达梦数据库的逻辑存储结构主要包括以下几个层次:
1.1 表空间(Tablespace)
- 含义:表空间是数据库的逻辑划分,一个数据库由多个表空间组成
- 功能:用于存储数据库对象(如表、索引等)
- 分类: DM 数据库中的表空间可以分为普通表空间和混合表空间。普通表空间不能存储 HUGE 表,而混合表空间可以同时存储普通(非 HUGE)表和 HUGE 表,其中 HUGE 数据文件存储在混合表空间定义中指定的 HUGE 数据文件路径下。可以通过为普通表空间增加指定 HUGE 数据文件路径将普通表空间升级为混合表空间。
- 类型:
-
- SYSTEM表空间:存储数据字典信息
- TEMP表空间:存储临时表和数据
- ROLL表空间:存储回滚段
- MAIN表空间:默认用户表空间(MAIN表空间为混合表空间)
- RLOG 表空间:日志表空间,初始化库时会自动创建 2 个后缀名为 log 的日志文件,用于存放重做日志,用户可主动添加日志文件或者扩展日志文件
- 用户自定义表空间
- 表空间被进一步划分为段、簇和页(也称块)
1.2 段(Segment)
- 含义:表空间内分配的对象存储空间
- 类型:
-
- 数据段:存储表数据
- 索引段:存储索引数据
- 回滚段:存储事务回滚信息
- 临时段:临时工作区
- 段是簇的上级逻辑分区单元
- DM 支持了延迟段分配的功能,在创建表或索引时先暂时不申请存储空间,当对表中插入数据时,才尝试申请存储空间。对于已延迟段分配的表创建二级索引时,新建的索引同样也会延迟段分配。(除了全局索引、online 方式创建索引,此时二级索引总是会申请段)。可以通过设置 ini 参数 DEFERRED_SEGMENT_CREATION=1 开启延迟段分配功能,也可以在建表语句中进行指定,具体的段分配情况可以通过查看 V$SEGMENT_INFOS 获取。该功能可以有效改善创建分区表时,分区数较多导致初始为空的分区表分配过多空间的问题。
对表或索引进行延迟段分配,可能存在以下特殊场景:
- 对已延迟段分配的表进行查询插入,即便查询空表不会插入任何数据,目标表也会申请段。 因此需要注意,在启用 DDL 相关优化如 ALTER_TABLE_OPT 参数时,DM 可能会选择使用查询插入的方式来加速 DDL 执行,此时即便目标表已延迟段分配,该 DDL 的执行会导致目标表申请段。
- 表指定了自增列起始边界,即便建表时指定了延迟段分配也会被忽略。
- 重建已延迟段分配的索引将导致该索引申请段。
1.3 页(Page)
- 含义:簇由多个页组成,页是I/O操作的最小单位,数据页(也称数据块)是 DM 数据库中最小的数据存储单元
- 大小:默认8KB(可配置,在 DM 数据库中,页大小可以为 4KB、8KB、16KB 或者 32KB)
- 类型:
-
- 数据页
- 索引页
- 回滚页
- 位图页等
图1.2 DM数据页的组成
页头控制信息包含了关于页类型、页地址等信息。页的中部存放数据,为了更好地利用数据页,在数据页的尾部专门留出一部分空间用于存放行偏移数组,行偏移数组用于标识页上的空间占用情况以便管理数据页自身的空间。
在绝大多数情况下,用户都无需干预 DM 数据库对数据页的管理。但是 DM 数据库还是提供了选项供用户选择,使得在某些情况下能够为用户提供更佳的数据处理性能。
FILLFACTOR 是 DM 数据库提供的一个与性能有关的数据页级存储参数,它指定一个数据页初始化后插入数据时最大可以使用空间的百分比(100),该值在创建表/索引时可以指定。设置 FILLFACTOR 参数的值,是为了指定数据页中的可用空间百分比(FILLFACTOR)和可扩展空间百分比(100-FILLFACTOR)。可用空间用来执行更多的 INSERT 操作,可扩展空间用来为数据页保留一定的空间,以防止在今后的更新操作中增加列或者修改变长列的长度时,引起数据页的频繁分裂。当插入的数据占据的数据页空间百分比低于 FILLFACTOR 时,允许数据插入该页,否则将当前数据页中的数据分为两部分,一部分保留在当前数据页中,另一部分存入一个新页中。
对于 DBA 来说,使用 FILLFACTOR 时应该在空间和性能之间进行权衡。为了充分利用空间,用户可以设置一个很高的 FILLFACTOR 值,如 100,但是这可能会导致在后续更新数据时,频繁引起页分裂,而导致需要大量的 I/O 操作。为了提高更新数据的性能,可以设置一个相对较低(但不是过低)的 FILLFACTOR 值,使得后续执行更新操作时,可以尽量避免数据页的分裂,提升 I/O 性能,不过这是以牺牲空间利用率来换取性能的提高。
1.4 簇(Extent)
- 含义:簇是数据页的上级逻辑单元,由同一个数据文件中 16 个或 32 个或 64 个连续的数据页组成
- 大小:默认16
- 计算方法: 假定某个数据文件大小为 32MB,页大小为 8KB,则共有 32MB/8KB/16=256 个簇,每个簇的大小为 8K*16=128K。
- 和数据页的大小一样,一旦创建好数据库,此后该数据库的簇的大小就不能够改变。
1.4.1 分配数据簇
一般的,当创建一个表/索引的时候,DM 数据库会为表/索引的数据段分配至少一个簇,同时数据库会自动生成对应数量的空闲数据页,供后续操作使用。如果初始分配的簇中所有数据页都已经用完,或者新插入/更新数据需要更多的空间,DM 数据库将自动分配新的簇。在缺省情况下,DM 数据库在创建表/索引时,初始分配 1 个簇,当初始分配的空间用完时,DM 数据库会自动扩展。另外,DM 还提供了延迟段分配的功能,特点为不会在进行创建表/索引时马上为表/索引分配存储结构,具体介绍在 1.2.5 段中进行进一步说明。
当 DM 数据库的表空间为新的簇分配空闲空间时,首先在表空间按文件从小到大的顺序在各个数据文件中查找可用的空闲簇,找到后进行分配;如果各数据文件都没有空闲簇,则在各数据文件中查找空闲空间足够的,将需要的空间先进行格式化,然后进行分配;如果各文件的空闲空间也不够,则选一个数据文件进行扩充。
1.4.2 释放数据簇
对于用户数据表空间,在用户将一个数据段对应的表/索引对象 DROP 之前,该表对应的数据段会保留至少 1 个簇不被回收到表空间中。在删除表/索引对象中的记录的时候,DM 数据库通过修改数据文件中的位图来释放簇,释放后的簇被视为空闲簇,可以供其他对象使用。当用户删除了表中所有记录时,DM 数据库仍然会为该表保留 1-2 个簇供后续使用。若用户使用 DROP 语句来删除表/索引对象,则此表/索引对应的段以及段中包含的簇全部收回,并供存储于此表空间的其他模式对象使用。
对于临时表空间,DM 数据库会自动释放在执行 SQL 过程中产生的临时段,并将属于此临时段的簇空间还给临时表空间。
对于回滚表空间,DM 数据库将定期检查回滚段,并确定是否需要从回滚段中释放一个或多个簇。
1.5 记录
- 含义:数据库表中的每一行是一条记录。在 DM 中,除了 HUGE 表,其他的表都是在数据页中按记录存储数据的。也就是说,记录是存储在数据页中的,记录并不是 DM 数据库的存储单位,页才是。由于记录不能跨页存储,这样记录的长度就受到数据页大小的限制。数据页中还包含了页头控制信息等空间,因此 DM 规定每条记录的总长度不能超过页面大小的一半。
各结构之间的关系
数据库 → 表空间 → 段 → 簇 → 页 → 记录(行)
2. DM物理存储结构
达梦数据库的物理存储结构主要由以下文件组成:
2.1 配置文件
配置文件是 DM 数据库用来设置功能选项的一些文本文件的集合,配置文件以 ini 为扩展名,它们具有固定的格式,用户可以通过修改其中的某些参数取值来达成如下两个方面的目标:
- 启用/禁用特定功能项;
- 针对当前系统运行环境设置更优的参数值以提升系统性能。
2.1.1 DM数据库服务配置
- dm.ini:主配置文件,包含数据库实例的配置参数(参数属性:手动、静态、动态)
- dmarch.ini:归档配置文件
- dmmal.ini:MAL系统配置文件(用于分布式环境)
- sqllog.ini: sqllog.ini 配置文件的内容分为全局配置区和模式配置区。
- dmthrd.ini: 用于为线程类型绑定 CPU 核心,当且仅当 INI 参数 DMTHRD_INI=1 时使用。
- dmtimer.ini: 用于配置定时器,用于数据守护中记录异步备库的定时器信息中记录异步复制的定时器信息
2.1.2 客户端配置文件
- dm_svc.conf:服务名解析配置文件
2.2 控制文件
- CTL文件:记录数据库的物理结构信息,如表空间、数据文件的位置等
- 每个 DM 数据库都拥有两个控制文件,即 dm.ctl 和 dmtemp.ctl 控制文件,控制文件均为二进制文件。
dm.ctl 用于记录数据库必要的初始信息,主要包含以下内容:
- 数据库名称;
- 数据库服务器模式;
- OGUID 唯一标识;
- 数据库服务器版本;
- 数据文件版本;
- 数据库的启动次数;
- 数据库最近一次启动时间;
- 表空间信息,包括表空间名,表空间物理文件路径等,记录了所有数据库中使用的表空间,数组的方式保存起来;
- 控制文件校验码,校验码由数据库服务器在每次修改控制文件后计算生成,保证控制文件合法性,防止文件损坏及手工修改。
dmtemp.ctl 用于记录临时表空间相关信息,主要包括临时表空间名以及临时表空间物理文件路径等。
在服务器运行期间,执行表空间的 DDL 等操作后,服务器内部需要同步修改控制文件内容。如果在修改过程中服务器故障,可能会导致控制文件损坏,为了避免出现这种情况,在修改控制文件时系统内部会执行备份操作。备份策略如下:
- 策略一
在修改控制文件之前,先执行一次备份,确定控制文件修改成功后,再将备份删除,如果控制文件修改失败或中途出现故障,则保留备份文件。 - 策略二
在修改控制文件成功之后,根据 dm.ini 中指定的 CTL_BAK_PATH/CTL_BAK_NUM 对最新的控制文件执行备份,如果用户指定的 CTL_BAK_PATH 是非法路径,则不再生成备份文件,在路径有效的情况下,生成备份文件时根据指定的 CTL_BAK_NUM 判断是否删除老的备份文件。
注意:
- 如果控制文件存放在裸设备上,则【策略一】不会生效。
- 如果指定的 CTL_BAK_PATH 是无效路径,则【策略二】也不会生效。
- 如果【策略一】和【策略二】的条件都满足,则都会生效执行,否则只执行满足条件的备份策略,如果都不满足,则不会再生成备份文件。
- 如果是初始化新库,在初始化完成后,会在“SYSTEM_PATH/CTL_BAK”路径下对原始的控制文件执行一次备份。
2.3 数据文件
- DBF文件:数据库中最重要的文件类型,存储实际数据的文件,每个表空间对应一个或多个数据文件
- 特点:
-
- 预分配空间
- 自动扩展(可配置)
- 数据组织形式:
-
- B数数据
-
-
- 行存储数据,也是应用最广泛的存储形式,其数据是按 B 树索引组织的。
- 普通表、分区表、B 树索引的物理存储格式都是 B 树。
- 一个 B 树包含两个段,一个内节点段,存放内节点数据;一个叶子段,存放叶子节点数据。其 B 树的逻辑关系由段内页面上的记录,通过文件指针来完成。
-
-
- 堆表数据
-
-
- 以挂链形式存储
- 一般情况下,支持最多 128 个链表
- 堆表采用的是物理 ROWID,在插入过程中,ROWID 在事先已确定,并保证其唯一性,所以可以并发插入,插入效率很高
- ROWID 是即时生成,无需保存在物理磁盘上,也节省了空间
-
-
- 列存储数据
-
-
- 读取列数据时,只需要顺序扫描列数据文件和辅助表数据
-
-
- 位图索引
-
-
- 每个索引项保存的是一定范围内所有行与当前索引键值映射关系的位图
-
- 两类特殊的数据文件:ROLL 和 TEMP 文件。
-
- ROLL 文件
-
-
- ROLL 表空间的 DBF 文件,称为 ROLL 文件。ROLL 文件用于保存系统的回滚记录,提供事务回滚时的信息。回滚文件可被分为若干回滚段,每个事务的回滚页在回滚段中各自挂链,页内则顺序存放回滚记录。
-
-
- TEMP 文件
-
-
- TEMP.DBF 临时数据文件,临时文件可以在 dm.ini 中通过 TEMP_SIZE 配置大小。
- 当数据库查询的临时结果集过大,缓存已经不够用时,临时结果集就可以保存在 TEMP.DBF 文件中,供后续运算使用。系统中用户创建的临时表也存储在临时文件中。
-
2.4 重做日志文件(联机日志文件)
- REDO文件:记录数据库的所有修改操作
- 重做日志文件默认以 log 为扩展名,可在初始化数据库时使用建库参数 RLOG_POSTFIX_NAME 指定重做日志文件的扩展名。每个 DM 数据库实例必须至少有 2 个重做日志文件,默认两个日志文件为 DAMENG01.log、DAMENG02.log,这两个文件循环使用。
- 特点:
-
- 循环写入
- 用于数据库恢复
- 通常有多个日志文件组
2.5 归档日志文件
- ARCH文件:已满的重做日志文件的归档副本(在归档模式下,重做日志被连续写入到归档日志后,所生成了归档日志文件)
- 归档日志文件以归档时间命名,扩展名默认与初始化数据库时指定的参数 RLOG_POSTFIX_NAME 一致,也可通过 INI 参数 LOG_FILE_POSTFIX_NAME 指定归档日志文件的扩展名
- 功能:用于时间点恢复和数据库复制
2.6 物理逻辑日志文件
是按照特定的格式存储的服务器的逻辑操作,专门用于 DBMS_LOGMNR 包挖掘获取数据库系统的历史执行语句。当开启记录物理逻辑日志的功能时,这部分日志内容会被存储在重做日志文件中。
2.7 备份文件
- BAK文件:数据库备份文件
- 当系统正常运行时,备份文件不会起任何作用,它也不是数据库必须有的联机文件类型之一
- 特点:
-
- 全量备份
- 增量备份
- 差异备份
2.8 SQL 日志文件
- SQL 日志文件是一个纯文本文件
- SQL 日志内容包含系统各会话上用户执行的 SQL 语句、参数信息、错误信息等。跟踪日志主要用于分析错误和分析性能问题,基于跟踪日志可以对系统运行状态有一个分析
2.9 事件日志文件
- 事件日志文件记录了 DM 数据库运行时的关键事件
- 事件日志文件主要用于系统出现严重错误时进行查看并定位问题。事件日志简称 ELOG。事件日志文件随着 DM 数据库服务的运行一直存在。
3. DM内存结构
3.1 内存池
内存分为 共享内存池 和 运行时内存池:
共享内存池是 DM Server 在启动时从操作系统申请的一大片内存。
运行时内存池是从操作系统申请一片内存作为本功能模块的内存池来使用,如会话内存池、虚拟机内存池等。
| 内存区 | 功能 |
|---|---|
| 排序区 | 处理 ORDER BY、GROUP BY 等排序操作。 |
| 哈希区 | 处理哈希连接(Hash Join)操作。 |
| 会话堆栈 | 存储会话变量、游标状态等私有信息。 |
| 大对象缓存 | 缓存 CLOB/BLOB 大字段数据。 |
内存管理:
- 通过参数
MEMORY_POOL、BUFFER_POOLS等动态调整。 - 支持
V$MEM_POOL、V$BUFFERPOOL视图实时监控。
3.2 缓冲区
- 数据缓冲区(Buffer Pool) :
-
- 功能:缓存从数据文件读取的数据页
- 数据缓冲区存在三条链来管理被缓冲的数据页,一条是自由链,用于存放目前尚未使用的内存数据页,一条是 LRU 链,用于存放已被使用的内存数据页(包括未修改和已修改),还有一条即为脏链,用于存放已被修改过的内存数据页。
- 类型:NORMAL、KEEP、FAST 和 RECYCLE等缓冲池
- 读多页:减少 I/O 次数,从而提高了数据的查询、修改效率。
- 日志缓冲区(Log Buffer) :
-
- 功能:缓存重做日志记录,然后批量写入日志文件
- 字典缓冲区(Dictionary Cache) :
-
- 功能:缓存数据字典信息,如模式信息、表信息、列信息、触发器信息等
- 该缓冲区配置参数为 DICT_BUF_SIZE,默认的配置大小为 5M。
- SQL缓冲区(SQL Cache) :
-
- 功能:缓存SQL执行计划
3.3 排序区(Sort Area)
-
- 功能:序缓冲区提供数据排序所需要的内存空间(排用于排序操作)
3.4 哈希区(Hash Area)
-
- 功能:为哈希连接而设定的缓冲区(用于哈希连接操作)
- 虚拟缓冲区
4. DM线程结构
DM 服务器使用“对称服务器构架”的单进程、多线程结构。主要线程包括:
4.1 监听线程(Listener Thread)
- 功能:监听客户端连接请求
- 特点:通常只有一个监听线程
4.2 工作线程(Worker Thread)
- 功能:服务器各种类型任务的处理及所有实际的数据相关操作。
- 工作线程包括任务工作线程和会话工作线程等。
- 特点:
-
- 线程池管理
- 可配置最小和最大线程数
- 核心线程
4.3 I/O线程
- 特点: 最耗时
- 数据文件I/O线程:负责数据文件的读写
- 日志文件I/O线程:负责日志文件的读写
- 归档I/O线程:负责归档日志的写入
4.4 调度线程(Dispatcher Thread)
- 功能:接管系统中所有需要定时调度的任务。调度线程每秒钟轮询一次
4.5 日志FLUSH线程
- 功能:任何数据库的修改,都会产生重做 REDO 日志,为了保证数据故障恢复的一致性,REDO 日志的刷盘必须在数据页刷盘之前进行。事务运行时,会把生成的 REDO 日志保留在日志缓冲区中,当事务提交或者执行检查点时,会通知 FLUSH 线程进行日志刷盘
4.6 日志归档线程
- 功能:管理归档日志文件
4.7 日志APPLY线程
4.8 定时器线程
4.9 MAL 系统相关线程
MAL 系统是 DM 内部高速通信系统,基于 TCP/IP 协议实现。
5.1 DM 系统管理员的类型
- 数据库管理员(DBA)
- 数据库安全员(SSO)
- 数据库审计员(AUDITOR)
- 数据库对象操作员(DBO)
参考链接:
eco.dameng.com/document/dm…【达梦技术文档】