最近开始学习达梦数据库(DM8),这几天主要在熟悉数据库的基本结构和运行机制。
刚开始接触的时候,表空间、段、簇、页、数据缓冲区、Redo 日志以及各种后台线程这些概念都是相对独立的,看资料的时候很容易知道每个名词是什么意思,但串起来之后又有些模糊。
所以这几天尝试从“数据存在哪里、运行时放在哪里、数据修改之后怎么保存”这几个问题出发,把目前了解到的内容简单梳理了一遍。
由于目前接触 DM8 的时间还比较短,下面的内容主要是对整体结构的初步理解,部分底层机制还没有深入验证,后续会结合实际环境继续学习。
数据库首先需要解决的问题,就是数据应该如何组织和存储。
在 DM8 中,可以从逻辑存储和物理存储两个角度来理解。
目前我的理解是,DM8 的逻辑存储结构可以按照:
数据库 → 表空间 → 段 → 簇 → 页
来进行理解。
这几个概念在刚开始学习的时候比较容易混淆,所以分别记录一下。
页是数据库进行数据存储和 I/O 管理的重要基本单位。
DM8 在创建数据库时需要指定页大小,例如 4K、8K、16K、32K 等。页大小会对数据存储以及 I/O 等方面产生影响,因此建库时需要根据实际业务情况进行考虑。
简单来说,可以先把页理解成数据库存储数据时使用的一个基本单位。
簇可以理解成由多个连续页组成的一组空间。
数据库在进行空间分配时,会涉及簇这一层级。相比直接以单个页进行空间管理,使用更大的空间分配单位,可以减少频繁进行小粒度空间分配带来的管理开销。
段可以理解成数据库对象所使用的一块逻辑空间。
例如表的数据需要占用空间,索引也需要占用空间,这些空间可以通过相应的段来进行管理。
随着表或者索引不断增长,对应的段也可以继续申请新的空间。
因此目前可以简单理解成:
表/索引 → 段 → 簇 → 页
表空间是数据库中的逻辑存储容器。
创建表、索引等数据库对象时,可以指定相应的表空间,数据库再负责进一步管理这些对象所使用的段、簇和页。
因此,如果从比较宏观的角度来看,可以把表空间理解成连接数据库对象和底层存储空间的一层逻辑结构。
上面的表空间、段、簇、页属于逻辑上的存储概念,最终数据还是需要保存到操作系统的物理文件中。
在学习 DM8 的过程中,目前接触比较多的主要有以下几类文件。
数据文件是数据库保存数据的重要物理文件。
表数据、索引数据等最终都需要持久化到相应的数据文件中。
一个表空间可以对应一个或多个数据文件,具体的文件组织方式还与数据库的配置有关。
可以简单理解为:
数据文件主要负责保存数据库的数据。
不过需要注意,数据库运行过程中并不是每次修改数据都立即写入数据文件,而是会先经过内存中的数据缓冲区。
控制文件保存数据库运行所需要的一些重要控制信息,例如数据库文件等相关信息。
数据库启动和运行过程中需要使用这些信息来识别和管理数据库的物理结构。
目前可以先把控制文件简单理解为:
数据库管理自身物理结构和运行状态的重要文件。
Redo 日志是目前学习过程中我认为比较重要的一个概念。
数据库执行 INSERT、UPDATE、DELETE 等修改操作时,会产生相应的日志信息。
这些日志主要用于记录数据库发生的修改,并为事务持久性以及数据库故障恢复提供基础。
这里有一个比较重要的理解:
数据库修改数据时,并不是每次修改都要求立即把对应的数据页写入数据文件。
数据页可以先在内存中进行修改,而相关日志则需要按照数据库的日志机制进行持久化。
事务提交时,需要保证相关日志已经达到相应的持久化要求。
所以可以先形成一个比较简单的认识:
数据修改 → 产生 Redo → 日志持久化 → 事务提交
如果数据库开启了归档模式,在线日志发生切换之后,相关历史日志会按照归档机制进行保存。
归档日志在数据库备份恢复以及 DM 高可用环境中都有比较重要的作用。
目前可以简单理解成:
在线日志主要服务于数据库当前运行,归档日志则负责保存已经切换出去的历史日志。
如果说数据文件解决的是“数据最终保存在哪里”,那么内存则主要解决的是“数据库运行过程中如何更高效地处理数据”。
数据库启动之后,会申请相应的内存空间,用于数据缓存、SQL 执行以及其他运行过程中的操作。
目前接触比较多的主要有数据缓冲区、日志相关内存以及 SQL 执行过程中使用的工作空间。
数据缓冲区(Buffer)可以理解成数据库在内存中建立的数据缓存。
当 SQL 需要访问数据时,如果对应的数据页已经在 Buffer 中,就可以直接从内存访问;如果不在,则需要从磁盘上的数据文件读取到内存。
大致可以理解成:
数据文件 → Buffer → SQL 执行
当执行 UPDATE 等修改操作时,数据页也通常是在内存中进行修改,并被标记为脏页。
之后再由数据库后台机制将这些脏页写回数据文件。
这样可以减少大量直接针对磁盘进行随机 I/O 的情况。
除了缓存数据之外,SQL 执行本身也需要使用内存。
例如:
ORDER BYGROUP BYDISTINCT这些操作在执行过程中都可能需要使用一定的工作内存。
如果需要处理的数据比较多,内存不足以完成相关操作,则可能需要借助临时表空间等机制进行处理。
所以可以把这部分内存简单理解成:
SQL 执行过程中的临时工作空间。
数据库运行过程中还需要为会话、SQL 执行以及各种内部操作分配内存。
DM8 会通过相应的内存管理机制对这些内存进行管理。
目前对 DM8 各个内存组件的具体划分还没有完全掌握,所以这里暂时不展开具体参数,而是先建立一个整体认识:
Buffer 更偏向数据缓存,而其他内存区域则更多服务于数据库运行和 SQL 执行本身。
数据库并不是只有一个线程在工作。
DM8 运行过程中存在多个线程,分别负责客户端连接、SQL 执行、日志处理、数据刷盘以及其他后台任务。
数据库需要监听指定的网络端口,接收客户端的连接请求。
DM8 默认端口通常是 5236,当然实际环境中也可以进行修改。
客户端连接数据库之后,才能进一步执行 SQL。
所以最外层可以简单理解成:
客户端 → 网络连接 → 数据库会话 → SQL 执行
客户端提交 SQL 后,数据库需要完成 SQL 解析、优化以及执行。
执行过程中可能涉及:
最终将执行结果返回给客户端。
执行事务修改操作时,会产生相应的 Redo 日志。
日志需要经过数据库的日志处理机制写入在线日志文件。
当事务执行 COMMIT 时,需要保证相关日志满足相应的持久化要求。
因此可以先形成一个比较简单的认识:
事务修改 → 产生日志 → 日志写入 → COMMIT
前面提到,数据修改之后可能首先发生在 Buffer 中。
这样就会产生脏页。
如果脏页一直停留在内存中,会造成内存压力,同时也会增加数据库异常恢复时需要处理的内容。
因此数据库需要通过后台机制,将部分脏页逐渐写回数据文件。
可以简单理解成:
Buffer → 脏页 → 后台刷盘 → 数据文件
这里需要特别区分:
日志写入和数据页刷盘并不是同一个过程。
日志主要用于事务持久性和恢复,而数据页刷盘则负责将内存中的数据逐渐持久化到数据文件。
检查点(Checkpoint)也是数据库运行过程中的一个重要机制。
数据库运行时间越长,产生的日志和脏页就越多,因此需要通过检查点等机制推进数据库状态,并控制故障恢复时需要处理的范围。
目前我对 DM8 Checkpoint 的理解较浅,这里先记住一个比较基础的概念:
Checkpoint 与脏页刷盘、数据库恢复以及日志管理都有关系。
如果数据库开启归档模式,在在线日志发生切换后,相关日志会进入归档流程。
归档后的日志可以用于数据库恢复,同时也是 DM 高可用架构中的重要基础。
目前可以先理解成:
在线日志 → 日志切换 → 归档 → 归档日志
前面分别介绍了数据库的存储、内存和后台任务,但真正理解这些内容,还是需要把它们串起来。
假设客户端执行:
UPDATE T_USER
SET NAME = 'DM'
WHERE ID = 1;
COMMIT;
那么可以从目前的理解出发,把这个过程简单描述成:
客户端
↓
网络连接
↓
数据库会话
数据库对 SQL 进行解析、优化,然后执行。
执行过程中需要访问对应的数据页。
如果数据页已经在 Buffer 中,就可以直接使用;否则需要从数据文件读取到 Buffer。
SQL
↓
解析 / 优化
↓
执行
↓
Buffer
↓
数据访问
执行 UPDATE 后,相关数据页发生变化,并成为脏页。
与此同时,数据库会产生对应的 Redo 日志。
┌→ 数据页 → Buffer → 脏页
UPDATE ──────┤
└→ Redo
执行 COMMIT 后,数据库需要保证事务相关日志达到相应的持久化要求。
COMMIT
↓
日志持久化
↓
提交成功
后台机制会根据数据库运行情况,将 Buffer 中的脏页逐渐写回数据文件。
Buffer
↓
脏页
↓
后台刷盘
↓
数据文件
随着数据库运行,在线日志会不断被使用。
发生日志切换后,如果数据库开启了归档模式,则相关历史日志会进入归档流程。
Redo
↓
在线日志
↓
日志切换
↓
归档
↓
归档日志
经过这几天的学习,目前我对 DM8 的理解可以简单总结成下面这几条线。
数据库
↓
表空间
↓
段
↓
簇
↓
页
↓
数据文件
它主要解决的是:
数据库对象的数据最终如何组织和保存。
客户端
↓
会话
↓
SQL 解析 / 优化 / 执行
↓
Buffer
↓
数据访问
它主要解决的是:
SQL 运行过程中如何访问和处理数据。
数据修改
↓
Redo
↓
日志持久化
↓
COMMIT
同时:
Buffer
↓
脏页
↓
后台刷盘
↓
数据文件
这让我对数据库中一个比较重要的概念有了初步认识:
事务日志的持久化和数据页的持久化是两个不同的过程。
数据库并不需要在每次事务提交时,都把所有修改过的数据页立即写入数据文件,而是通过日志机制和后台刷盘机制,在保证事务持久性的同时减少磁盘 I/O 压力。
文章
阅读量
获赞
