DM数据库体系结构
1. 逻辑结构
1.1 数据库和实例
- 数据库 (Database): 指磁盘上存放的DM数据库数据的物理集合,主要包括数据文件、日志文件、控制文件以及临时数据文件等。
- 实例 (Instance): 指操作DM数据库的手段,由一组正在运行的DM后台进程/线程和一个大型的共享内存组成。实例存储在服务器内存中,用于访问数据库。
- 关系: 数据库存储在磁盘,实例存储在内存。一个实例同一时间只能关联(装载、打开或挂起)一个数据库。通常一个数据库对应一个实例。在DM数据共享集群(DMDSC)中,多个实例可同时操作一个位于共享磁盘上的数据库。
1.2 逻辑存储结构
DM数据库为所有对象分配逻辑空间,存储在数据文件中。数据文件组合成表空间,数据库对象存放在表空间中。表空间进一步细分为段、簇和页(块),以提高磁盘空间利用率。层次关系如下:

- 数据库 由一个或多个表空间组成。
- 表空间 由一个或多个数据文件组成。
- 数据文件 由一个或多个簇组成。
- 段 是簇的上级逻辑单元,一个段可跨多个数据文件。
- 簇 由同一数据文件中连续的16、32或64个页组成,一个簇总在一个数据文件中。
- 页 是数据库最小的分配单元和I/O单元。
1.2.1 表空间 (Tablespace)
- 组成:由一个或多个数据文件组成,对象逻辑存于表空间,物理存于其数据文件。
- 类型:
- 普通表空间: 不能存储HUGE表。
- 混合表空间: 可同时存储普通表和HUGE表(HUGE文件存于指定路径)。普通表空间可通过添加HUGE路径升级为混合表空间。
- 初始化表空间:创建数据库时自动创建5个:
- SYSTEM: 存放数据字典,用户不能创建表和索引。
- ROLL: 自动维护,存放事务DML操作前的值,提供读一致性视图。
- RLOG: 存放重做日志,初始化创建2个.log文件,可添加或扩展。日志文件循环使用。
- MAIN: 初始化包含MAIN.DBF(128M)和HMAIN目录(HUGE路径),是混合表空间。未指定默认表空间的用户,其默认表空间为MAIN。
- TEMP: 自动维护,为需磁盘空间的操作(如大排序、创建索引、临时表)分配临时段。
- 用户默认表空间:SYS, SYSSSO, SYSAUDITOR默认SYSTEM;SYSDBA默认MAIN;新建用户未指定则默认MAIN。创建表时指定表空间A(与用户默认B不同),则表及其索引存于A,用户默认表空间仍为B。
- 建议:用户自建表空间存放业务数据或使用MAIN。
- 查看:
用户可以通过执行如下语句来查看 SYSTEM、ROLL、MAIN 以及 TEMP 的表空间相关信息
SELECT * FROM V$TABLESPACE;
用户可以通过执行如下语句来查看 RLOG 表空间相关信息:
SELECT * FROM V$RLOG;
--查看日志空间信息
SELECT * FROM V$RLOGFILE;
--RLOG文件信息
SELECT * FROM V$LOG_HISTORY;
--日志文件切换历史。
1.2.2 记录 (Record)
- 数据库表中的每一行是一条记录(HUGE表除外)。
- 记录存储在数据页中,不能跨页存储,因此记录总长度不能超过页大小的一半。
1.2.3 页 (Page/Block)

- 最小的数据存储和I/O单元。
- 大小:创建数据库时可指定4KB, 8KB, 16KB, 32KB(默认8KB),创建后不可更改。
- 结构:包含页头控制信息、数据区和行偏移数组(管理页内空间)。
- FILLFACTOR 参数:
- 指定数据页初始化后插入数据可用空间的百分比(创建表/索引时指定)。
- 平衡空间利用率与性能:高值(如100)节约空间但可能导致更新时页分裂频繁(I/O多);低值(非过低)预留空间减少页分裂(提升I/O性能)但空间利用率低。
1.2.4 簇 (Extent)
- 页的上级逻辑单元,由同一数据文件中连续的16、32或64个页组成(大小在创建库时指定,默认16,创建后不可改)。
- 分配: 创建表/索引时至少分配一个簇(含空闲页)。空间用完或需更多空间时自动分配新簇。默认初始分配1个簇,支持延迟段分配(创建时不立即分配)。
- 释放:
- 用户表空间:DROP表/索引前保留至少1个簇。DELETE记录时释放簇(变空闲)。删光记录仍保留1-2个簇。DROP对象则回收所有簇。
- 临时表空间:自动释放SQL执行产生的临时段及簇。
- 回滚表空间:定期检查并释放回滚段的簇。
1.2.5 段 (Segment)
- 簇的上级逻辑分区单元,由一组簇组成(可跨文件,簇内页连续但簇间不一定连续)。
- 类型:
- 数据段: 存储表或索引数据。CREATE时创建。分区表每个分区一个数据段;非分区索引一个索引段;分区索引每个分区一个索引段。表段和索引段可存于不同表空间。存储参数影响分配效率。
- 临时段: 存于TEMP表空间,处理SQL中间结果(如大排序、临时表)。自动分配释放,用户不可干预。
- 回滚段: 存于ROLL表空间,保存恢复信息(用于回滚、故障恢复、读一致性)。DM采用全自动回滚管理。
- 延迟段分配:
- 功能:创建表/索引时不立即申请空间,插入数据时才申请(全局索引/online索引除外)。
- 开启:INI参数
DEFERRED_SEGMENT_CREATION=1
或建表语句指定。
- 查看:
V$SEGMENT_INFOS
。
- 好处:避免空分区表(尤其分区多时)初始分配过多空间。
- 特殊场景:
查询空表可能触发申请段;
表指定自增列起始边界会忽略延迟分配;
重建已延迟分配的索引会导致申请段。
2. 物理存储结构
DM使用多种物理文件存储和管理数据,包括:配置文件、控制文件、数据文件、重做日志文件、归档日志文件、备份文件、SQL日志文件、事件日志文件。

2.1 配置文件 (.ini)
- 文本文件,设置功能选项和性能参数。
- dm.ini: 数据库核心配置文件,必需。参数分三种:
- 手动(Manual): 必须手动修改文件并重启生效。非法值设置会参考默认值,小于最小值实际采样为最小值,大于最大值实际采样为最大值。
- 静态(Static): 可以被动态修改,修改后重启服务器才能生效。
- 动态(Dynamic): 可动态修改,即时生效(分会话级和系统级)。非法值设置报错。
动态修改是指 DBA 用户可以在数据库服务器运行期间,通过调用系统过程 SP_SET_PARA_VALUE()、SP_SET_PARA_DOUBLE_VALUE()和 SP_SET_PARA_STRING_VALUE()对参数值进行修改。
- dm_svc.conf: 分全局配置区和服务配置区(
[服务名]
开头),服务配置区优先级高。全局配置区的配置项影响所有会话,除非会话所属服务配置区中单独进行了配置,修改需重启客户端程序。
2.2 控制文件 (.ctl)
- 二进制文件,记录数据库必要初始信息。
- dm.ctl: 记录数据库名、模式、OGUID、版本、启动次数、近一次启动时间、表空间信息、校验码。
- dmtemp.ctl: 记录临时表空间信息,主要为表空间名及文件路径。
- 备份策略: 常在修改前备份
策略一.修改控制文件之前,先执行一次备份,确定控制文件修改成功后,再将备份删除,如果控制文件修改失败或中途出现故障,则保留备份文件(裸设备无效);
策略二.修改后按CTL_BAK_PATH/CTL_BAK_NUM
备份(路径无效则不备份)。
新库初始化后在SYSTEM_PATH/CTL_BAK
备份原始控制文件。
2.3 数据文件 (.dbf)
- 存储真实数据,每个库至少一个,通常多个。
- 空间用尽可自动扩展(可设
MAXSIZE
限制)。
- 按组织形式分类:
- B树数据: 行存储(普通表、分区表、B树索引)。包含内节点段和叶子段。
- 堆表数据: 挂链存储(最多128链),物理ROWID,插入效率高。
- 列存储数据: 按列组织,特殊场景效率高。
- 位图索引: 索引项指向多行,存储映射位图。
- 特殊数据文件:
- ROLL文件: ROLL表空间的DBF文件,保存回滚记录。
- TEMP文件 (TEMP.DBF): 临时文件,大小由
TEMP_SIZE
配置。存储大临时结果集和用户临时表。
2.4 重做日志文件 (联机日志, .log)
- 记录所有数据操作(增删改对象或数据),默认扩展名.log。
- 每个实例至少2个(默认DAMENG01.log, DAMENG02.log),循环使用。
- 作用:用于数据库备份与恢复(故障时恢复至意外前状态),保障数据安全。
2.5 归档日志文件
- 在归档模式下,重做日志写入联机日志文件的同时写入归档日志文件,当产生检查点时,系统将系统缓冲区中的日志和脏数据页都写入磁盘,以保证当前日志所“保护”的数据页都已安全写入磁盘,这样日志文件即可被安全重用。(按归档时间命名,扩展名默认同联机日志)。
- 作用:提供更安全恢复(介质故障时可恢复至故障点或指定时间点),非归档模式只能利用备份恢复。启用影响性能。
2.6 物理逻辑日志文件
- 存储特定格式的逻辑操作,供
DBMS_LOGMNR
包挖掘历史语句。
- 开启条件:
- 设置
RLOG_APPEND_LOGIC = 1/2/3/4
。
- 设置
RLOG_IGNORE_TABLE_SET=1
(记录所有表)或在建/改表时指定ADD LOGIC LOG
并设置RLOG_IGNORE_TABLE_SET=0
(记录特定表)。
2.7 备份文件 (.bak)
- 非必需联机文件。由备份操作产生,包含备份名称、数据库、类型、时间等信息。故障恢复时至关重要。
2.8 SQL日志文件 (.log)
- 纯文本文件(需
SVR_LOG
开启)。记录用户执行的SQL、参数、错误等,用于分析错误和性能。
- 文件名格式:
dmsql_实例名[_模式名][_用户名][_日期_时间].log
PART_STOR=1 时,日志文件名中会添加_用户名
SWITCH_MODE 不为 0 时,日志文件名中会添加_日期_时间
(sqllog.ini
参数决定)。
- 缺省路径:
DM安装目录/log
,可通过sqllog.ini
的FILE_PATH
设置。
- 性能影响:开启影响性能,一般查错调优时使用。可通过
SQL_TRACE_MASK
, MIN_EXEC_TIME
过滤记录,ASYNC_FLUSH
异步刷盘提升性能。
- 管理:可动态修改
sqllog.ini
(SP_SET_SQLLOG_INI()
, SP_DELETE_SQLLOG_INI_MODE()
),刷新配置(SP_REFRESH_SVR_LOG_CONFIG()
)。查看:V$DM_SQLLOG_INI
(文件中SQL日志参数), V$DM_SQLLOG_CONFIG
(内存中SQL日志参数)。
2.9 事件日志文件 (ELOG)
-
记录数据库运行时关键事件(启动、关闭、内存申请失败、IO错误、日志信息、备份阶段信息等),用于故障定位。
-
格式:时间 + 日志类型(INFO/WARNING/ERROR/FATAL)+ 进程(database)+ 进程 ID(P 开头)+ 线程(dm_sql_thd/main_thread 等)+ 日志内容
。
-
模式:

ELOG_FLAG=1
: 所有日志记录到单个文件dm_实例名.log
(如dm_DMSERVER.log
)。
ELOG_FLAG=0
(默认): 日志拆分:
- 月度日志: 当月所有日志到
dm_实例名_年月.log
(如图dm_DMSERVER_202209.log
)。
- 分时日志: 按
SVR_ELOG_FREQ
频率(月/日/时)切换时,将最近时段日志剪切到dm_实例名_日期_整点.log
(如按小时切换dm_DMSERVER_20220914_09.log
)。
-
初始化日志:保存在ELOG_PATH
,名称如dminit20220914090452.log
。
-
启动失败日志:命名为dm_unknown_年月
(如dm_unknown_202212
)。
-
管理:查看V$ELOG_FILE
,删除使用SP_ELOG_FILE_DELETE
。
3. 内存结构
DM通过自有内存申请、释放管理提升效率、掌握内存使用情况、发现泄露和越界问题。
DM 数据库管理系统的内存结构主要包括内存池、缓冲区、排序区、哈希区等。根据系统中子模块的不同功能,对内存进行了上述划分,并采用了不同的管理模式。
主要包括:
3.1 内存池
- 共享内存池: 启动时申请大片内存,供运行期间申请释放小片内存用,减少系统调用。大小由
MEMORY_POOL
(默认500M) 设置,可自动扩展(MEMORY_EXTENT_SIZE
)/内存池扩展到超过该值后收缩(MEMORY_TARGET
)。查看:V$MEM_POOL
。
- 运行时内存池: 各功能模块自有内存池(如会话池、虚拟机池),从操作系统申请。
3.2 缓冲区
- 数据缓冲区: 缓存磁盘读写的数据页。关键区域,影响命中率和I/O。管理链:自由链(未用页)、LRU链(已用页)、脏链(已修改页)。
- 类型:
NORMAL
:默认缓冲区,大小由BUFFER
(默认8000MB) 设置。
KEEP
:很少淘汰,大小由KEEP
(默认8MB) 设置。表空间可指定。
RECYCLE
:供临时表空间用,大小由RECYCLE
(默认300MB) 设置。
FAST
:系统自动管理,大小由FAST_POOL_PAGES
(默认3000页) 设置。
- 读多页: 参数
MULTI_PAGE_GET_NUM
(默认1页) 控制单次I/O读取页数,需权衡设置。
- 日志缓冲区: 缓存重做日志(格式不同、连续写、优先级高)。大小由
RLOG_BUF_SIZE
(页数) 设置,内存来自共享池。
- 字典缓冲区: 缓存数据字典信息(模式、表、列等),LRU管理。大小由
DICT_BUF_SIZE
(默认5M) 设置。访问分区多的水平分区表需调大。
- SQL缓冲区: 缓存SQL执行所需内容(计划、语句、结果集)。
- 计划重用: 由
USE_PLN_POOL
(非0开启) 控制。缓冲区大小由CACHE_POOL_SIZE
(默认20M) 设置。
- 结果集缓存: 需
RS_CAN_CACHE=1
且USE_PLN_POOL
非0。客户端缓存通过dm_svc.conf
配置 (ENABLE_RS_CACHE = (1)
//表示启用缓存;
RS_CACHE_SIZE = (100)
//表示缓存区的大小为100M, 可配置为1-65535
RS_REFRESH_FREQ = (30)
//表示每30秒检查缓存的有效性,如果失效,自动重查;
0表示不检查
),服务器端用CLT_CACHE_TABLES
设置缓存表,FIRST_ROWS
控制可缓存结果集的行上限。
3.3 排序区
- 提供数据排序所需内存。大小由
SORT_BUF_SIZE
(默认2M) 设置,建议默认。
3.4 哈希区
- 虚拟缓冲区,用于哈希连接。大小由
HJ_BUF_SIZE
设置,建议默认或更大。处理集函数哈希表个数由HAGR_HASH_SIZE
(默认100000) 设置。
4. 管理DM线程
DM采用单进程、多线程的对称服务器架构。主要线程类型:
4.1 监听线程
- 循环监听服务器端口,接收连接请求,生成会话任务加入工作线程队列。优先级高。启动后启动,关闭时首先关闭。
4.2 工作线程
- 核心线程,处理各类任务和数据操作。
- 任务工作线程: 处理内部任务(如清理缓存、异步执行任务)。初始数由
TASK_THREADS
设置,任务堆积时自动增加。
- 会话工作线程: 处理会话请求。模式由
STHD_FLAG
控制:
- 非线程池: 一会话一线程。
- 线程池: 初始线程数=
WORKER_THREADS * STHD_THREAD_NUM
。会话轮询线程接收请求加入队列,工作线程取任务处理。
4.3 IO线程
- 处理耗时的IO操作(读数据页、缓冲区满写脏页、检查点写脏页)。通常睡眠,收到IO请求唤醒处理。个数由
IO_THR_GROUPS
(默认2) 设置。尽量使用异步IO,DM Server 需要进行 IO 操作的时机主要有以下三种:
- 需要处理的数据页不在缓冲区中,此时需要将相关数据页读入缓冲区;
- 缓冲区满或系统关闭时,此时需要将部分脏数据页写入磁盘;
- 检查点到来时,需要将所有脏数据页写入磁盘。
4.4 调度线程
- 每秒轮询一次,接管定时任务:
- 检查系统时间触发器。
- 清理失效/超限的SQL/计划缓存。
- 动态扩展/收缩缓冲池。
- 执行自动检查点(根据间隔参数)。
- 检测会话超时并断开。
- 必要时执行数据页刷盘。
- 唤醒等待的工作线程。
4.5 日志FLUSH线程
- 负责重做日志(REDO)刷盘(必须在数据页刷盘前)。事务提交或检查点触发。优化:刷盘前合并不同缓冲区日志减少IO。若配实时归档,刷盘前直接发送日志到备库;若配本地归档,生成任务给归档线程。
4.6 日志归档线程
- 处理非实时归档任务(异步归档线程)。从任务队列取任务按类型归档。与FLUSH线程分离避免性能损失。
4.7 日志APPLY线程 (数据守护备库)
- 备库特有。接收主库REDO日志生成APPLY任务,在备库重做日志保持数据同步/一致。备库只读,可分担查询负载。
4.8 定时器线程
- 处理定时操作:逻辑日志异步归档、异步归档日志发送(PRIMARY OPEN状态)、作业调度。默认不启动,设置
TIMER_INI=1
开启。每秒检测定时器链表触发任务。
4.9 MAL系统相关线程
- 实现DM内部高速通信(TCP/IP),支持数据守护、MPP、远程归档等。包含MAL监听、发送、接收工作线程等。
4.10 其他线程
- 如回滚段清理(PURGE)线程、审计写文件线程等。
4.11 线程信息查看
- 相关动态视图:
V$LATCHES
(等待线程), V$THREADS
(活动线程), V$PROCESS
(进程信息)。
达梦社区地址 https://eco.dameng.com