第一周技术博客
一. DM数据存储
1.数据库要存储的数据
- 用户数据
- 数据字典:用户数据的组织形式
- 保证ACID及数据安全的数据:重做、回滚、备份
- 用于故障及错误分析的数据
- 服务功能配置
2.配置文件
- dm.ini:服务器配置文件
- dmmal.ini:MAL通信系统配置文件
- dmmarch.ini:重做日志归档配置文件
- sqllog.ini:SQL跟踪日志的配置文件
- dm_svc.conf:客户端配置文件
3.数据文件和重做日志文件
存储数据的二进制文件,以dbf作为扩展名,在逻辑上有与之对应的表空间。数据文件大致分类如下:行存储数据文件、列存储数据文件、回滚数据文件、临时数据文件。
重做日志文件是以log为扩展名的二进制文件。每个DM数据库实例必须至少有2个重做日志文件,默认两个日志文件为DAMENG01.log、DAMENG02.log,这两个文件循环使用。
4.事件日志文件及跟踪日志文件
记录服务器运行期间信息的文本文件,用于分析定位系统错误。常用的有:服务器事件日志、SQL跟踪日志。
5.各文件的存储方式
6.逻辑存储结构
DM使用表空间对数据文件在逻辑上进行管理,除列存数据外,其他的表空间数据都使用段、簇和页分层的逻辑结构进行管理。表空间大致分类如下:
- 系统数据表空间
- 回滚数据表空间
- 临时数据表空间
- 用户存储数据表空间
段是簇的上级逻辑单元,一个段只能属于一个表空间,可以跨多个数据文件;簇由磁盘上连续的页组成,一个簇只能在一个数据文件中,簇是数据库对象分配存储空间的基本单位;页是数据库中最小的分配单元,也是数据库中使用的最小的IO单元,一旦创建好了数据库,则在该库的整个生命周期内,页大小都不能够改变。
页在头部和尾部预留一些空间,记录控制信息,称为页头和页尾,使用(表空间ID,文件ID,页号)的组合来标识定位一个数据页。
使用32Byte可以来描述一个簇,其中使用一个位图了描述该簇内数据页的使用情况,结构如下:
DM按照数据的使用类型,将段分为:数据段、回滚段。DM通过72Byte来描述一个段的控制信息,结构如下:
使用段描述页来存储段描述。一个段描述页内存放多个段描述,段描述页可以通过<段描述页链表节点>进行挂链,方便找到下一个段描述页。结构如下:
7.表数据组织形式
行存储的表有两种组织方式:B树、堆表。
B树中的每个节点都是一个数据页,实际数据全部存储在叶子节点上,中间节点(也称为B树内节点)仅用来存放B树的分支信息,其中每个记录都指向一个下级节点(页)。为B树分配两个数据段:内节点段,存放内节点数据;叶子段,存放叶子节点数据。B树根页的下一个页作为B树的控制页,其中存放B树的行数、NEXT_ROWID等控制信息,B树的根页中记录叶子节点段与内节点段的段头信息。
8.大字段
大字段数据有两种存储方式:行内存储、行外存储。如果大字段的数据无法在行内存储,则转为行外存储,其行内存放真实数据的指针。
9.列存储
优点:查询只需读取需要的列,大幅减少IO、数据压缩比非常高、任何列都能作为索引(数据即索引)。
缺点:需要组装列形成记录、INSERT、UPDATE、DELETE代价较大、不适合增删改密集的OLTP型应用。
DM的列存数用来处理大量的数据,所以也称为HUGE TABLE。列存数据不再按照数据页方式进行管理,而是通过HFS(Huge File System)存储机制来管理的,它相当于一个文件系统。创建一个列存目录,在创建一个列存表并插入数据时,数据库会在指定的HUGE目录下创建一系列的目录及文件。
二.DM并发策略
1.MVCC
MVCC允许数据具有多个版本,这个版本可以是时间戳或者是全局递增的事务ID,在同一个时间点,不同的事务看到的数据是不同的。
主要特征:写不会阻塞读,读操作永远不会被阻塞。
DM 数据库基于物理记录和回滚记录实现行级多版本支持,数据页中只保留物理记录的最新版本,通过回滚记录维护历史版本,所有事务针对特定的版本进行操作。每一条物理记录中包含了两个 字段:TID和 RPTR。TID 保存修改记录的事务号,RPTR 保存回滚段中上一个版本回滚记录的物理地址 。插入、删除和更新物理记录时,RPTR 指向操作生成的回滚记录的物理地址。根据RPTR查找回滚记录,构造前一个版本的数据,重复这个判断,直到找到可见记录。
DM 通过活动事务表,确定事务的可见性。根据事务隔离级的不同,在事务启动时(串行化),或者语句执行时(读提交),收集这一时刻所有活动事务,并记录系统中即将产生的事务号NEXT_TID。
DM 多版本可见性原则:
1.物理记录的 TRX_ID 等于当前事务号,说明是本事务修改的物理记录,物理记录可见;
2.物理记录的 TRX_ID 不在活动事务表中,并且 TRXID 小于 NEXT_TID,物理记录可见;
3.物理记录的 TRX_ID 包含在活动事务表中,或者 TRXID 大于等于 NEXT_TID,物理记录不可见。
2.锁
LOCK主要用于管理数据库中表、记录等共享资源的并发访问。DM 数据库使用四种不同的锁模式:共享锁、排他锁、意向共享锁和意向排他锁。
-
共享锁:(简称 S 锁)用于读操作,防止其他事务修改正在访问的对象。这种封锁模式允许多个事务同时并发读取相同的资源,但是不允许任何事务修改这个资源。
-
排他锁(简称 X 锁)用于写操作,以独占的方式访问对象,不允许任何其他事务访问被封锁对象;防止多个事务同时修改相同的数据,避免引发数据错误;防止访问一个正在被修改的对象,避免引发数据不一致。一般在修改对象定义时使用。
-
意向锁(Intent Lock)用于读取或修改被访问对象数据时使用,多个事务可以同时对相同对象上意向锁,DM 支持两种意向锁:
- 意向共享锁(Intent Share Lock,简称 IS 锁):一般在只读访问对象时使用;
- 意向排他锁(Intent Exclusive Lock,简称 IX 锁):一般在修改对象数据时使用。
以下是锁的相容情况:
按照封锁对象的不同,锁可以分为 TID 锁和对象锁。
TID 锁以事务号为封锁对象,为每个活动事务生成一把 TID 锁,代替了其他数据库行锁的功能,防止多个事务同时修改同一行记录。DM 实现的是行级多版本,每一行记录隐含一个 TID 字段,用于事务可见性判断。 DM 中不再有行锁。
对象锁是 DM 新引入的一种锁,通过统一的对象 ID 进行封锁,将对数据字典的封锁和表锁合并为对象锁,以达到减少封锁冲突、提升系统并发性能的目的。
- 数据字典锁:用来保护数据字典对象的并发访问,解决 DDL 并发和 DDL/DML 并发问题,防止多个事务同时修改同一个对象的字典定义,确保对同一个对象的 DDL操作是串行执行的。并防止一个事务在修改字典定义的同时,另外一个事务修改对应表的数据。
- 表锁:表锁用来保护表数据的完整性,防止多个事务同时采用批量方式插入、更新一张表,防止向正在使用 FAST LOADER 工具装载数据的表中插入数据等,保证这些优化后数据操作的正确性。此外,表锁还有一个作用,避免对存在未提交修改的表执行 ALTER TABLE、TRUNCATE TABLE 操作。
三. DM查询优化概述
1.SQL分析流程
语法树主要组成部分:查询项、FROM项、WHRER项、分组项、HAVING项、ORDER BY、TOP
语义分析顺序:
2.计划探测原理
方法:卡特兰树、左深树。以下是对比:
3.优化策略
1.规则优化
- 子查询转换
- 外连接转换
- 视图上拉
- 表达式合并
2.基于代价优化:
- 基于统计信息,如索引扫描VS全表扫描
- 连接方式选择,如HASH JOIN、INDEX JOIN、MERGE JOIN
4.优化技巧
1.INI参数(内存、JOIN、查询相关)
2.创建合适的索引
3.收集统计信息(过滤条件列、连接列、索引)
4.HINT指示
5.动态性能视图
6.相关函数
- ET:显示操作符耗时情况
- TRO:生成trace文件,展示计划生成过程
7.执行计划
计划是否符合期望、定位\优化局部热点子计划。
8.性能工具
.INI参数(内存、JOIN、查询相关)
2.创建合适的索引
3.收集统计信息(过滤条件列、连接列、索引)
4.HINT指示
5.动态性能视图
6.相关函数
- ET:显示操作符耗时情况
- TRO:生成trace文件,展示计划生成过程
7.执行计划
计划是否符合期望、定位\优化局部热点子计划。
8.性能工具
Vtune、perf
达梦社区地址:https://eco.dameng.com