love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

Phone:18180207355 提供专业Oracle/MySQL/PostgreSQL数据恢复、性能优化、迁移升级、紧急救援等服务

达梦数据库学习笔记之 — 线程架构

本站文章除注明转载外,均为本站原创: 转载自love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

本文链接地址: 达梦数据库学习笔记之 — 线程架构

这里接着前面的系列文章继续进行学习探索(本文就是纯技术研究,仅代表个人观点,与公司无关)。达梦数据库本质上是一个单进程多线程架构,跟MySQL类似。如下所示;

可以看到这里的PID即是dmserver的操作系统进程号。跟Oracle 中的pid不同。 接下来我们看看dm8中有哪些线程:

下面我们针对上述线程简单进行描述和总结。

1、dm_lsnr_thd 监听线程

类似Oracle的listener 程序,任务是在服务器端口上进行循环监听,一旦有来自客户的连接请求,监 听线程被唤醒并生成一个会话申请任务,加入工作线程的任务队列,等待工作线程进行处理。

达梦数据库中监听线程的监听端口范围为1024 – 65534;默认监听的端口为5236。通过分析参数文件配置,可以看到与端口相关的一些参数:

根据达梦官方手册的描述,为了保证在处理大量客户连接 时系统具有较短的响应时间,监听线程比普通线程优先级更高。从目前来看,DM8中只能有一个监听线程;在高并发场景,可能面临请求处理不及时的情况(大家知道在Oracle中,如果单个监听进程无法处理时,我们可以还有创建多个监听程序)

2、dm_tskwrk_thd 工作线程

这是达梦数据库的核心线程;它从任务队列中取出任务,并根据任务的类型进行相应的处理,负责所有实际的数据相关操作。
DM8 的初始工作线程个数由配置文件指定,随着会话连接的增加,工作线程也会同步增加,以保持每个会话都有专门的工作线程处理请求。
看上去其默认值是cpu core的2倍。高并发场景下,该参数应该是需要调大的。

3、dm_io_thd 即IO thread

该线程也是核心线程,负责脏数据写出,类似Oracle中的DB writer进程。根据官方的手册描述,有如下几种情况下,需要IO线程来完成工作。

DM Server需要进行IO操作的时机主要有以下三种:
1)需要处理的数据页不在缓冲区中,此时需要将相关数据页读入缓冲区;
2)缓冲区满或系统关闭时,此时需要将部分脏数据页写入磁盘;
3)检查点到来时,需要将所有脏数据页写入磁盘。

通过如下2个参数来进行IO线程数量的控制;

这里简单创建测试表,并触发检查点,来观察一下IO thread的行为:

我们可以通过perf top -p 9956 来观察IO线程的函数调用情况:

这里我创建一个测试表,插入数十万数据,触发全量检查点,对进程进行跟踪一下看看具体的数据写出行为:

看上去这里DM的IO线程是单page写入(DM默认page size是8k);居然不会进行IO合并。这看起来不太对,否则性能太低。使用blktrace来深入分析看看IO情况。

通过btt格式化后可以进一步进行观察btt -i sda3.blktrace.0 -B sda3_io_thread.log

由此可见,还是会存在IO合并的操作,不是单page写入,page应该是最小IO单元。

 

4、dm_sched_thd 调度进程

类似Oracle中的job 进程,负责定时任务的调度,默认情况下每秒轮询一次。不过达梦数据库中的调度线程,
不单单是这些功能,从官方手册来看,包括了如下一系列功能:

1) 检查系统级的时间触发器,如果满足触发条件则生成任务加到工作线程的任务队列 由工作线程执行;
2) 清理 SQL 缓存、计划缓存中失效的项,或者超出缓存限制后淘汰不常用的缓存项;
3) 检查数据重演捕获持续时间是否到期,到期则自动停止捕获;
4) 执行动态缓冲区检查。根据需要动态扩展或动态收缩系统缓冲池;
5) 自动执行检查点。为了保证日志的及时刷盘,减少系统故障时恢复时间,根据 INI参数设置的自动检查点执行间隔定期执行检查点操作;
6) 会话超时检测。当客户连接设置了连接超时时,定期检测是否超时,如果超时则自动断开连接;
7) 必要时执行数据更新页刷盘;
8) 唤醒等待的工作线程

可以通过perf top -p 10219 来简单窥视一下调度进程的一些函数调用:

5、dm_redolog_thd 即日志flush 线程

该线程作用类似Oracle LGWR进程,负责将日志缓冲区中的buffer写出到redo日志文件中,用于确保事务中断或异常时可以进行恢复,保证事务一致性。

在DM8之前的版本中,是没有redolog flush线程的,统一由IO线程负责。DM8中对这个性能瓶颈点进行了优化拆分,将redolog flush线程独立了出来;从这点来看DM8
在日志写方面比之前老版本应该有较大的性能提升。不过仍然是一个单线程。当redo产生量极大的情况下,单线程应该还是会存在瓶颈。

大家知道Oracle 12c版本之前,redo buffer的写出进程lgwr也是单进程,从12c版本开始,Oracle引入了多进程模式,解决了最后一个瓶颈。

那么多redolog flush线程会合并写入吗? 这里看看过滤看看前面的strace跟踪即可:

可见达梦8中,redolog flush线程会进行日志缓冲的合并写出。这也是正常的处理逻辑,否则性能上不去的。最后还有一些其他线程,如dm_chkpnt_thd 即检查点线程;purge线程,则主要是负责回滚段的清理;归档线程、审计线程等等。

总结:

看达梦数据库的14类线程,不少核心线程原理似乎跟Oracle类似(实际上关系型数据库应该都差不多);不过仍然有一些差别。

这里不发表太多评论,防止被喷。从上面测试来看,监听线程,redolog flush线程 是可能存在瓶颈的点。

 

Leave a Reply

You must be logged in to post a comment.