一、DM数据库逻辑结构概述
1.1 数据库与实例
在DM7版本之前,达梦数据库中“数据库”和“实例”概念经常混用。DM7及之后版本,数据库与实例是完全独立的两个实体,必须严格区分。
-
数据库(Database)
数据库是存放在服务器磁盘上的全部数据集合,是静态磁盘对象。包含数据文件、控制文件、重做联机日志、归档日志、临时数据文件等一系列物理磁盘文件。数据库本身不会运行,只是保存数据。
-
实例(Instance)
实例是一组运行在内存中的后台线程 + 共享内存池,驻留在服务器内存中,是访问磁盘数据库的手段。实例是动态运行对象,数据库启动才会创建实例,数据库关闭实例就销毁。
运行关系:
- 单机环境:任何时刻,一个实例只能关联、装载、打开一个数据库;绝大多数场景一个数据库只被一个实例访问。
- DMDSC共享存储集群环境:多个实例可以同时装载并打开同一个数据库,多台服务器节点通过共享磁盘访问同一套数据库文件,实现集群。
通俗理解:数据库=磁盘上一堆数据文件;实例=内存+后台线程,用来读写磁盘数据库。数据库是数据仓库,实例就是打开仓库干活的工人。
1.2 DM逻辑存储完整层次
DM数据库逻辑存储层级,从上到下顺序:
数据库 → 表空间 → 数据文件 → 段 → 簇 → 页 → 记录
- 数据库:由一个或者多个表空间构成。
- 表空间:逻辑存储容器,所有表、索引等对象逻辑上存放于表空间;物理数据存放在表空间下属的数据文件。
- 普通表空间:不能存储HUGE列存储表。
- 混合表空间:既可以存储普通行存表,也可以存储HUGE列存储表。普通表空间可以通过增加HUGE数据文件路径升级为混合表空间。
创建DM数据库,系统会自动生成4个基础系统表空间:
| 表空间名称 |
详细说明 |
| SYSTEM系统表空间 |
存储数据库全部数据字典信息(模式、用户、表、索引、约束、存储过程元数据)。禁止普通用户在SYSTEM表空间创建表、索引。系统用户SYS、SYSSSO、SYSAUDITOR默认表空间是SYSTEM。 |
| ROLL回滚表空间 |
完全由数据库自动维护,用户不可手动干预。保存DML执行前的数据镜像,用来实现事务回滚、MVCC多版本读一致性,保证查询可以读到数据修改前的快照。 |
| MAIN主表空间 |
混合表空间,初始化自带MAIN.DBF数据文件,同时配置HMAIN作为HUGE表文件路径。新建用户没有指定默认表空间,自动分配MAIN作为默认表空间;SYSDBA用户默认表空间就是MAIN。 |
| TEMP临时表空间 |
自动维护,存放各类临时段。创建索引、大表排序、分组运算、SQL中间结果集、用户创建临时表,内存放不下时,数据会落到TEMP表空间。事务结束、会话断开后,临时段空间会被系统回收复用。 |
查询表空间信息SQL:
SELECT * FROM V$TABLESPACE;
- 数据文件:表空间对应的物理
.dbf磁盘文件,一个表空间可以包含 1 个或者多个数据文件;一个数据文件只能归属于一个表空间,不能跨表空间。
- 段(Segment):簇的上级逻辑单元,一个段可以跨多个数据文件;一个簇只能属于一个数据文件。段按照用途分为三类:
- 数据段:普通表、索引对应的段;分区表中,每一个分区都拥有独立的数据段。普通索引一个索引对应一个索引段。
- 临时段:全部创建在 TEMP 临时表空间。排序、group by、临时表产生,分配和释放全部系统自动管理,用户不能手动干预。
- 回滚段:位于 ROLL 回滚表空间,保存回滚记录。用于事务回滚、故障恢复、多版本读一致性。DM 采用全自动回滚管理,不需要 DBA 手动创建回滚段。
段分配规则:创建表 / 索引的时候,DM 至少分配 1 个簇;簇全部用完,数据库自动扩展分配新簇。DROP 删除表 / 索引,整个段的所有簇全部回收给表空间复用。只 delete 全部记录,不会回收段,至少保留 1~2 个簇。
- 簇(Extent,区):由同一个数据文件内连续的多个数据页组成。簇永远不会跨数据文件。
- 簇大小在建库的时候指定,建库完成后不能修改;默认每个簇包含 16 个页。
- 簇是 DM 给段分配空间的最小粒度,数据库给表、索引分配空间,是以簇为单位,不是以页为单位。
- 页(Page,数据块):DM 数据库最小 IO 单元,也是磁盘分配最小单元。
- 页大小支持:4KB、8KB、16KB、32KB,数据库初始化时指定,创建数据库之后,整个生命周期不可更改,默认 8KB。
- 页内部结构四部分:页头控制信息、业务数据区、空闲空间、行偏移数组。
- 页头控制信息:记录页类型、页地址、校验信息;
- 数据区:存放表记录;
- 空闲空间:预留空闲位置;
- 行偏移数组:管理页内每条记录的位置。
记录不能跨页存储。所以单条记录总长度不能超过页面大小的一半。
1.2.1 FILLFACTOR 填充因子
FILLFACTOR 填充因子,在建表、创建索引语句可以指定。含义:数据页插入数据允许填充的最大百分比。
- 预留剩下空间,留给后续 UPDATE 更新变长字段,减少页分裂。
- FILLFACTOR=100:页完全填满。空间利用率最高,但是后续更新变长字段,极易发生页分裂,产生大量 IO,适合几乎不更新、以插入查询为主的静态表。
- FILLFACTOR 设置较低:页预留较多空闲,更新不容易页分裂,性能更好,但是浪费磁盘存储空间。
- 默认参数
DEFAULT_FILLFACTOR控制全局默认填充因子,0 等价于 100,代表全满填充。
页分裂:当页没有空闲空间,更新记录变长,数据库把页一部分数据迁移到新页,这个操作叫页分裂,会消耗 IO,产生碎片,影响性能。
- 记录(行):表中每一行就是一条记录。除 HUGE 列存储表,记录全部保存在数据页中。记录不是存储分配单元,页才是存储分配单元。记录禁止跨页存储。
1.3 DM 逻辑存储层级总结文字
数据库(多个表空间) └──表空间(1~N 个数据文件) └──数据文件 └──段(跨多个数据文件,由多个簇组成) └──簇(同一个数据文件内连续多个页,不跨文件) └──页(最小 IO 单元) └──记录(业务行数据,不能跨页)
二、DM 数据库物理存储结构
DM 数据库实例运行时,磁盘上存在多种类型物理文件,分为:配置 INI 文件、控制文件、数据文件、重做联机日志、归档日志文件、备份文件、各类日志跟踪文件。
2.1 各类配置 INI 文件
配置文件是文本 INI 格式,修改参数控制数据库行为。
表格
| 配置文件名 |
功能说明 |
| dm.ini |
数据库实例核心配置文件,每一个数据库实例对应一个 dm.ini。控制内存、线程、事务、查询优化、检查点、IO、安全、兼容模式等几乎全部实例参数。 |
| dmmal.ini |
MAL 系统通信配置,DSC 共享集群、数据守护主备、MPP 分布式集群,节点之间网络通信参数,集群环境所有节点该文件必须保持完全一致。 |
| dmarch.ini |
归档配置文件,配置本地归档、实时归档、即时归档、异步归档、RAFT 归档等归档相关参数。主备环境必须配置。 |
| dm_svc.conf |
客户端配置文件!!不是数据库服务端文件。部署在应用、客户端机器。JDBC、disql、dexp 等客户端读取;配置服务地址、读写分离、故障自动切换、连接参数。Linux 路径/etc/dm_svc.conf,Windows 在 system32 目录。可以设置环境变量DM_SVC_PATH自定义路径。 |
| sqllog.ini |
SQL 日志配置,控制 SQL 语句捕获,慢 SQL,用于性能调优、故障排查。 |
| dmthrd.ini |
CPU 绑核配置文件,绑定各个后台线程运行 CPU 核心,大服务器调优使用。 |
| dmtimer.ini |
定时器配置,数据库作业、异步归档定时器任务。 |
dm.ini 参数三种属性,非常重要
- 手动参数:只能手动编辑 dm.ini 磁盘文件,修改之后重启数据库实例才生效;运行时无法使用存储过程在线修改。
- 静态参数:可以调用系统存储过程在线修改内存值,但是修改磁盘 dm.ini 文件,需要重启实例,新参数永久生效。
- 动态参数:修改之后内存立刻生效,不需要重启实例。分为:
- 会话级动态:修改后,仅对当前会话以及之后新建会话生效;历史已经建立会话不受影响。
- 系统级动态:修改之后,全局所有会话立刻生效。
修改动态参数系统存储过程:
SP_SET_PARA_VALUE(); --整数
SP_SET_PARA_DOUBLE_VALUE(); --浮点
SP_SET_PARA_STRING_VALUE(); --字符串
2.2 控制文件 dm.ctl
二进制控制文件,记录数据库核心元数据信息:数据库名称、数据库版本、各个表空间信息、全部数据文件路径、文件校验信息、检查点信息。
- 执行 DDL 修改表空间、新增 / 删除数据文件,会实时更新控制文件。
- 数据库会自动备份控制文件,备份路径由
CTL_BAK_PATH参数控制,保留备份数量由CTL_BAK_NUM控制,防止控制文件损坏数据库无法启动。
- 不建议手动修改控制文件。
2.3 数据文件(*.dbf)
真正存放业务数据的磁盘物理文件,不同表空间对应不同 dbf。
- 普通行存表、索引数据;ROLL 回滚数据;TEMP 临时数据;堆表数据;HUGE 表元数据全部存放在 dbf。
- 支持自动扩展:设置初始大小,写满后自动增长;可以设置 MAXSIZE 最大上限,防止占满磁盘。
- 可以手动给表空间增加、删除、修改路径、调整大小。
查询数据文件:
SELECT * FROM V$DATAFILE;
2.4 重做联机日志文件 REDO(*.log)
- DM 数据库至少需要 2 个联机重做日志文件,循环复用。
- 所有 DML 增删改操作,修改的数据先生成 REDO 日志写入日志缓冲区,最终刷入联机重做日志文件;先写日志原则(WAL)。数据缓冲区脏页不需要立刻刷磁盘。
- 数据库异常宕机重启,实例恢复依靠 REDO 联机日志,重做缓冲区没有刷入数据文件的脏页,保证数据一致性。
- 联机日志循环覆盖,开启归档模式,覆盖之前内容拷贝到归档日志。
查询重做日志文件:
SELECT * FROM V$RLOGFILE;
2.5 归档日志文件
只有数据库开启归档模式,才会生成归档日志。联机日志即将被循环覆盖的时候,把联机日志完整复制出来保存为归档文件。
- 作用:介质故障恢复。数据文件损坏,可以使用备份 + 归档日志,恢复到故障发生前任意时间点。
- DM 归档类型:
- LOCAL 本地归档:本机磁盘保存归档;
- REALTIME 实时归档:主库写联机日志同时发送给备库;
- TIMELY 即时归档;
- ASYNC 异步归档;
- SYNC 同步归档;
- RAFT 归档,用于多副本集群。
查询归档信息:
SELECT * FROM V$ARCH_FILE;
2.6 其他物理文件
- 物理逻辑日志文件:配置参数
RLOG_APPEND_LOGIC开启,会在 REDO 日志记录原始 DML 逻辑语句,用于 logmnr 日志挖掘。
- 备份文件 *.bak:dmbackup 物理备份生成;dexp 逻辑备份是 dmp 文件。
- SQL 日志文件:根据 sqllog.ini 捕获的 SQL 语句,用于性能分析。
- ELOG 事件日志文件:服务器事件日志,记录数据库启动关闭、报错、告警、IO 故障,排错优先查看 ELOG 日志。
- TRACE 跟踪文件:打开 TRACE 跟踪生成,调试底层问题。
三、DM 内存结构
DM 实例启动,操作系统分配一大块内存,内存分为内存池、各类缓冲区、排序区、哈希区。
3.1 内存池
内存池减少频繁向操作系统申请释放内存带来的开销。
- 共享内存池 MEMORY_POOL 实例启动向操作系统申请一块大内存,数据库内部各类小块内存申请都优先从共享内存池分配。
MEMORY_POOL:共享内存池初始大小 MB;
MEMORY_EXTENT_SIZE:内存池不够时每次扩展粒度;
MEMORY_TARGET:负载下降空闲内存过多,收缩回的目标大小。
- 运行时内存池 独立的内存池:会话内存池 SESS_POOL、虚拟机 VM_POOL,服务 PL/SQL、会话运行使用。
3.2 缓冲区
缓冲区是内存和磁盘中间缓存,减少磁盘 IO,是数据库性能核心。
3.2.1 数据缓冲区 BUFFER
存放从磁盘读取出来的数据页(dbf 页)。DM 数据缓冲区分为 4 个子缓冲区:
- NORMAL 普通缓冲区:绝大多数普通表空间默认使用;
- KEEP 缓冲区:尽量不淘汰,存放热点高频访问数据页;
- RECYCLE 缓冲区:主要用于 TEMP 临时表空间,临时数据;
- FAST_POOL 快速缓冲区:专门存放访问频率极高的数据页,减少磁盘 IO。
缓冲区内部维护 3 条链表
- 自由链:空闲还没有存放数据的内存页;
- LRU 链:已经加载数据的页,按照访问时间排序;内存不足,淘汰很久没有访问的冷页;
- 脏链:页内数据被修改,内存和磁盘文件不一致,还没有刷入磁盘,等待检查点刷盘。
相关 dm.ini 参数:
BUFFER:NORMAL 缓冲区总大小,MB;生产环境建议配置物理内存 60%~80%。
BUFFER_POOLS:缓冲区分片数量。
KEEP:KEEP 缓冲区大小。
RECYCLE:RECYCLE 缓冲区大小。
3.2.2 日志缓冲区 RLOG_BUF_SIZE
专门存放 REDO 重做日志内容,独立缓冲区,不和数据缓冲区混用。事务提交,日志缓冲区内容刷入联机 REDO 日志磁盘文件。
3.2.3 字典缓冲区 DICT_BUF_SIZE
缓存系统字典元数据:用户、模式、表、列、索引、约束、存储过程等字典对象。DDL 操作、SQL 解析大量访问字典。表数量、分区数量多的业务,建议调大DICT_BUF_SIZE。
3.2.4 SQL 缓冲区 CACHE_POOL_SIZE
缓存 SQL 文本、解析树、执行计划。实现执行计划重用,避免重复解析 SQL,降低 CPU 消耗。 参数USE_PLN_POOL控制是否开启计划缓存。
3.3 排序区
参数:SORT_BUF_SIZE、SORT_BUF_GLOBAL_SIZE。 用于ORDER BY、GROUP BY、DISTINCT、CREATE INDEX 索引创建等排序运算。
- 如果排序数据量小,全部放在内存排序,速度快。
- 如果数据量太大内存放不下,排序数据溢出写入 TEMP 临时表空间磁盘,执行磁盘排序,性能下降。 DM 支持新旧两套排序机制,参数
SORT_FLAG控制。
3.4 哈希区
参数HJ_BUF_SIZE。用于哈希连接 HASH JOIN。
- 数据量小,全部内存完成哈希;
- 数据量过大内存放不下,溢出到 TEMP 临时表做外存哈希。
3.5 其他内存组件
- HUGE_BUFFER:专门用于 HUGE 列存储表内存缓冲区;
- 虚拟机内存 VM_POOL_SIZE:PL/SQL 存储过程、函数运行虚拟机内存;
- 会话池 SESS_POOL_SIZE:每个会话运行内存。
查询内存使用情况动态视图
SELECT * FROM V$MEM_POOL;
SELECT * FROM V$BUFFER_POOL;
四、DM 线程管理
DM 数据库是单进程多线程架构。Linux 平台下只有一个 dmserver 主进程,进程内部启动大量不同职责后台线程,各个线程并发工作。Windows 平台为多进程。
4.1 各个后台线程详细说明
- 监听线程 负责监听客户端 TCP 连接请求(端口 PORT_NUM,默认 5236)。收到客户端连接,建立会话上下文,把会话任务交给工作线程处理。
- 工作线程
WORKER_THREADS会话工作线程:处理客户端发来的 SQL 请求,执行 DML、DQL、DDL 语句。支持线程池模式,参数STHD_FLAG开启 SESS/ESESS 线程池,高并发场景优化。
TASK_THREADS任务线程:处理系统内部后台任务,缓存清理、异步任务、统计信息收集。
- IO 线程 IO_THR_GROUPS 专门处理磁盘读写 IO 请求。把 IO 操作从业务工作线程剥离。业务线程发出 IO 请求,IO 线程完成磁盘读写。防止磁盘慢 IO 阻塞业务 SQL 执行。
- 调度线程 系统定时轮询后台调度线程,周期性执行大量系统任务:
- 会话超时断开检测;
- 触发检查点;
- 缓冲区管理;
- 触发器轮询;
- 内存池伸缩管理。
- 日志 FLUSH 线程 专门负责 REDO 重做日志缓冲区刷入磁盘联机日志文件。事务提交、检查点执行,触发日志刷盘。
- 日志归档线程 执行本地归档、远程归档,把联机日志拷贝成归档日志。和 FLUSH 线程解耦,归档慢不会直接阻塞业务 DML。
- **日志 APPLY 重演线程(仅备库)**数据守护备库独有线程。接收主库发送过来的 REDO 重做日志,在备库重演日志,保持主备库数据同步。
- 定时器线程 TIMER_INI 数据库定时作业、异步归档定时器任务。dm.ini 参数
TIMER_INI=1才会启动。
- MAL 系统相关线程 集群环境(DSC、数据守护、MPP)才会大量启用。负责集群各个节点之间 MAL 网络消息收发。单机环境 MAL_INI=0 不会启动。
- PURGE 清理线程 回滚段清理,MVCC 旧版本回滚记录过期之后,PURGE 线程清理回收回滚段空间。
- 检查点线程 执行检查点操作,把缓冲区脏页批量写入数据文件,减少故障恢复时间。检查点分为自动定时检查点、日志大小触发检查点。
- 审计线程 开启审计功能,负责审计记录刷盘写入审计文件。
4.2 查看线程相关动态视图
SELECT * FROM V$THREADS;
SELECT * FROM V$LATCHES;
SELECT * FROM V$SESSIONS;
五、学习总结
5.1 逻辑结构
- 数据库与实例区分:数据库是磁盘静态文件集合;实例 = 共享内存 + 后台线程,运行时对象;单机 1 实例对应 1 数据库;DSC 多实例共享一个数据库。
- 逻辑存储层级:数据库→表空间→数据文件→段→簇→页→记录。页是最小 IO 分配单元,簇是段分配空间最小粒度,记录不可跨页。
- 4 个系统表空间:SYSTEM(字典)、ROLL(回滚 MVCC)、MAIN(用户默认混合表空间)、TEMP(临时运算)。
- 段分为数据段、临时段、回滚段;FILLFACTOR 填充因子控制页预留空闲,权衡空间利用率和 update 页分裂风险。
5.2 物理存储结构
- 服务端 INI 配置文件:dm.ini 核心参数、dmmal.ini 集群通信、dmarch.ini 归档;dm_svc.conf 属于客户端配置文件。
- 控制文件 dm.ctl 保存数据库元数据,系统自动备份;
- 数据文件 dbf 存储业务数据;重做日志 log 遵循 WAL 先写日志;归档日志用于介质恢复。
- ELOG 事件日志是排错首要日志。
5.3 内存结构
- 内存池:共享内存池、运行时内存池,减少频繁操作系统内存调用。
- 四大缓冲区:数据缓冲区(NORMAL/KEEP/RECYCLE/FAST_POOL)、日志缓冲区、字典缓冲区、SQL 计划缓冲区。掌握脏页、LRU 淘汰、自由链概念。
- 排序区、哈希区,内存充足内存运算,内存不足溢出 TEMP 磁盘。
5.4 线程管理
- DM 单进程多线程模型(Linux)。区分监听线程、工作线程、IO 线程、调度线程、FLUSH 日志线程、归档线程、APPLY 备库重演线程、PURGE 清理线程。
- 线程相关视图 V$THREADS 查看实例所有后台线程。
关键理解:
逻辑结构:数据的逻辑组织方式,面向 DBA/SQL 开发人员视角。
物理结构:磁盘上真实存在的各类文件,操作系统视角。
内存 + 线程 = DM 实例运行时刻,数据库干活的运行载体。