达梦数据库进程管理方式类似于Mysql,属于单进程多线程模式。数据库服务进程包含:DmServer(主服务进程)和DmAPService(备份服务进程)。线程主要包括:监听线程、IO线程、工作线程、调度线程、日志线程等。下边详细谈论一下各个线程的具体工作原理和相关信息。
进程如下图:
线程如下图:
那么达梦数据库每个线程的作用和个数是多少呢?我们都知道,在Oracle中有5大进程,包含数据库写入进程 DBWn,编号从 DBW0-DBW9以及 DBWa-DBWj,最多可以 20个进程;日志写入进程 LGWR,检查点进程CKPT、系统监控进程SMON、进程监控进程PMON;归档进程ARCn,最多可以运行10个ARCn 进程( ARC0 到 ARC9)等,那么看达梦的对应线程如何:
disql 登录数据库终端执行:
SQL> select NAME,THREAD_DESC,count(1) from v$threads group by NAME,THREAD_DESC order by 3; ( #这里的3表示按照第三列排列。)
dm_quit_thd :用于执行正常关闭数据库的线程。
dm_io_thd :IO线程,由IO_THR_GROUPS参数控制,默认为2个线程,如下我们可以从系统中获得证明。
dm_rsyswrk_thd :异步归档线程,属于归档线程,主要负责将任务队列中的任务,按照归档类型进行相应的归档处理,一般有日志flushh线程触发。
dm_chkpnt_thd :检查点线程,主要负责CKPT_LSN的管理。
dm_redolog_thd :日志flush线程,负责日志刷盘,当事物提交或者发生检查点是触发。
dm_hio_thd :IO线程,主要处理HFS相关的IO读取操作,比如HUGE表的IO读取就有该线程负责完成。
dm_sqllog_thd :Thread for writing dmsql dmserver。
dm_purge_thd :purge线程。主要负责回滚段清理。
dm_tskwrk_thd :任务线程,由参数TASK_THREADS控制,取值范围为1-1000,默认为16,主要负责完成服务端SQL的解析运行等任务。
dm_trctsk_thd :日志信息记录线程,主要负责数据库告警跟踪信息写入告警日志文件中。
dm_wrkgrp_thd :工作线程,由参数WORKER_THREADS控制,取值范围为1-64,默认值为16,主要负责所有实际的数据相关操作。
dm_audit_thd :审计线程,主要负责审计日志记录与更新。
dm_sched_thd :调度线程,每秒钟轮询一次,主要负责接管数据库内部所有需要定时调度的任务,调度线程具备唤醒工作线程、向任务队列中添加任务队列、动态缓冲区检查、SQL缓存清理等权限。
dm_lsnr_thd :监听线程。主要负责数据库服务器端口监听,处理客户端请求,并将连接请求加入到工作线程的任务队列,由工作线程完成任务处理。监听线程在数据库服务启动完成之后才启动,关闭数据库时首先被关闭。
可以看到每个线程的解释和支持最大个数,下边详细说说每个线程的作用及原理。
1、监听线程,dm_lsnr_thd
达梦数据库中监听线程的监听端口范围为1024 - 65534;默认监听的端口为5236,主要的任务是在服务器端口上进行循环监听,一旦有来自客户的连接请求,监听线程被唤醒并生成一个会话申请任务,加入工作线程的任务队列,等待工作线程进行处理。它在系统启动完成后才启动,并且在系统关闭时首先被关闭。为了保证在处理大量客户连接时系统具有较短的响应时间,监听线程比普通线程优先级更高。
由此总结监听线程dm_lsnr_thd具有以下特点:
- 优先级最高
- dmserver服务启动后才启动,关闭时最先被关闭,这里理解为2个优先:即优先关闭、优先级别最高。
- 有客户端链接才会被唤醒,无连接处于休眠状态。
2、工作线程dm_wrkgrp_thd 。
工作线程是 DM 服务器的核心线程,由参数WORKER_THREADS控制,取值范围为1-64,默认值为16,主要负责所有实际的数据相关操作。它从任务队列中取出任务,并根据任务的类型进行相应的处理,负责所有实际的数据相关操作。
- DM服务器的核心线程,最多64个核心线程,超过线程数采用LRU方式进行工作并行。
- 从任务队列中取出任务,并根据任务类型进行对应处理;
- 负责实际的数据相关操作;
- 初始数量由配置文件指定,随着会话增加,工作线程数量也会增加,确保会话都有专门工作线程处理;
- 当会话连接超过预设阈值,工作线程将不再增加,由会话轮询线程接受用户请求,加入任务队列,等待工作线程处理。
达梦工作线程超过64个线程后由会话轮询线程接受用户请求,加入任务队列,等待工作线程处理,那么问题来了:
问题1:会话轮询线程是哪个线程?
问题2:任务队列采用的是哪种算法?LRU?FIFO?LFU ?
这个问题官方FAQ也没有给出具体的相关信息,网上百度了一下也没找到相关信心,据说DM是纯C开发的数据库,为此,我专门搜索了以下C的线程轮询机制,应该是通过C实现的定义线程池中接受用户请求线程,通过阻塞时间outtime参数设置+读写锁机制形成POSIX消息对列来进行调度(dm_sched_thd线程),释放后再利用的原理。
POSIX消息队列的一个可能的设计是一个如下图所示的消息链表,链表头部有消息队列的属性信息。
线程
线程流程图:
dm_tskwrk_thd :任务线程,由参数TASK_THREADS控制,取值范围为1-1000,默认为16,主要负责完成服务端SQL的解析运行等任务。
3、IO线程,dm_io_thd、dm_hio_thd,默认情况下,IO线程可通过dm.ini文件 IO_THR_GROUPS 参数设置,默认2个。
当事务需要的数据页不在缓冲区中时,如果在工作线程中直接对那些数据页进行读写,将会使系统性能变得非常糟糕,而把IO操作从工作线程中分离出来是明智的做法。IO线程的职责就是处理这些IO操作。通常情况下,DM Server需要进行IO操作的时机主要有以下三种。
DM Server进行IO操作主要有以下三种情况:
1)需要处理的数据页不再缓冲区中,此时需要将相关数据页读入缓冲区;
2)缓冲区满或系统关闭时,此时需要将部分脏数据页写入磁盘;
3)检查点到来时,需要将所有脏数据写入磁盘
IO线程在系统启动后,通常都处于睡眠状态,当需要进行IO时,只需要发出IO请求,对IO线程唤醒,完成操作后,IO线程再次睡眠;一般情况下,IO线程使用异步的IO将数据页写入磁盘,具体步骤如下:
1)系统将所有的IO请求直接递交给操作系统。
2)操作系统完成请求。
3)操作系统通知IO线程。
4)IO线程对完成IO的一些收尾处理并发出IO完成通知。
若操作系统不支持异步,IO线程则需要完成实际的IO操作。
dm_hio_thd:IO线程,主要处理HFS相关的IO读取操作,比如HUGE表的IO读取就有该线程负责完成。
4、调度线程 dm_sched_thd
调度线程,每秒钟轮询一次,主要负责接管数据库内部所有需要定时调度的任务,调度线程具备唤醒工作线程、向任务队列中添加任务队列、动态缓冲区检查、SQL缓存清理等权限,负责的任务有以下一些。
(1)检查系统级的时间触发器,如果满足触发条件,则生成任务加到工作线程的任务队列中并由工作线程执行。
(2)清理SQL缓存、计划缓存中失效的项,或者超出缓存限制后淘汰不常用的缓存项。
(3)检查数据重演捕获持续时间是否到期,到期则自动停止捕获。
(4)执行动态缓冲区检查。根据需要动态扩展或动态收缩系统缓冲池。
(5)自动执行检查点。为了保证日志的及时刷盘,减少系统故障时恢复时间,根据INI参数设置的自动检查点执行间隔定期执行检查点操作。
(6)会话超时检测。当客户连接设置了连接超时时,定期检测是否超时,如果超时则自动断开连接。
(7)必要时执行数据更新页刷盘。
(8)唤醒等待的工作线程。
5、日志FLUSH线程 dm_redolog_thd,redolog flush线程会进行日志缓冲的合并写出。
任何数据库的修改,都会产生重做(REDO)日志,为了保证数据故障恢复的一致性,REDO日志的刷盘必须在数据页刷盘之前进行。事务运行时,会把生成的REDO日志保留在日志缓冲区中,当事务提交或者执行检查点时,会通知FLUSH线程进行日志刷盘。由于日志具备顺序写入的特点,比数据页分散IO写入效率更高,因此,日志FLUSH线程和IO线程分开,能获得更快的响应速度,保证整体的性能。DM的日志FLUSH线程进行了优化,在刷盘之前,对不同缓冲区内的日志进行合并,减少了IO次数,进一步提高了性能。如果系统配置了实时归档,在FLUSH线程日志刷盘前,会直接将日志通过网络发送到实时备机。如果配置了本地归档或者远程同步归档,则生成归档任务,通过日志归档线程完成。
日志FLUSH线程刷盘条件如下:
- 事务提交commit
- 执行检查点chkpoint
- 每3秒
- 缓冲区写满,没有剩余空间时
- 数据库关闭时。
6、日志归档线程 dm_rsyswrk_thd,异步归档线程,属于归档线程,主要负责将任务队列中的任务,按照归档类型进行相应的归档处理,一般有日志flushh线程触发。
日志归档线程包含同步归档线程和异步归档线程,前者负责本地归档和远程同步归档任务,后者负责远程异步归档任务。如果配置了非实时归档,由日志FLUSH线程产生的任务会分别加入日志归档线程,日志归档线程负责从任务队列中取出任务,按照归档类型做相应归档处理。将日志FLUSH线程和日志归档线程分开的目的是减少不必要的效率损失,除了远程实时归档外,本地归档、远程同步归档、远程异步归档都可以脱离FLUSH线程来做,如果放在FLUSH线程中一起做,则会严重影响系统性能。
1.本地逻辑日志归档线程
本地归档线程从本地归档任务列表中取出一个归档任务,生成到逻辑日志,并将逻辑日志写入到逻辑日志文件中。如果当前逻辑日志的远程归档类型是同步异地归档并且当前的刷盘机制是强制刷盘,那么就生成一个异地归档任务加入到临时列表中。
2.远程逻辑日志归档线程
远程归档线程从远程归档任务列表中取出一个归档任务,并根据任务的类型进行相应的处理。任务的类型包括同步发送和异步发送。
7 、日志APPLY线程,
- 线程存在于配置了数据守护的系统中;
- 作为备库时,接收到主库的物理REDO日志,生成一个APPLY任务加入到任务队列,APPLY线程取出任务并在备库上将日志重做;
- 线程实现效果
- 1)保持和主库数据同步一致;
- 2)备库数据对用户只读;
- 3)可承担报表、查询等任务,均衡主库的负载
8 、定时器线程
1.完成定时进行某种操作的线程;
2.DM server 需要进行定时操作的事件主要有一些几种:
1)逻辑日志异步归档;
2)异步归档日志发送(只有在PRIMARY模式下,且OPEN状态);
3)作业调度
3.每秒检测一次定时器链表,对满足触发条件的任务,把执行权交给设置好的任务;
4.达梦服务器启动时,默认定时器线程不启动;
5.dm.ini文件 TIMER_INI 参数为 1时,该线程会随系统启动
9、 MAL系统相关线程
MAL系统是DM内部高速通信系统,基于TCP/IP协议实现。服务器的很多重要功能都是通过MAL系统实现通信的,例如数据守护、数据复制、MPP、远程日志归档等。MAL系统内部包含一系列线程,有MAL监听线程、MAL发送工作线程、MAL接收工作线程等。
10、其他线程。
dm_sql_thd 用户线程
dm_quit_thd 执行正常关闭数据库的线程
dm_purge_thd purge线程 主要负责回滚段清理
dm_trctsk_thd 日志信息记录线程,主要负责数据库告警跟踪信息写入告警日志文件中
dm_audit_thd 审计线程,主要负责审计日志记录与更新
dm_chkpnt_thd 检查点线程,主要负责CKPT_LSN的管理
dm_sqllog_thd 写 dmsql dmserver。
11、线程信息的查看
名称 说明
V$LATCHES 记录当前正在等待的线程信息。
V$THREADS 记录当前系统中活动线程的信息。
V$WTHRD_HISTORY 记录自系统启动以来,所有活动过线程的相关历史信息。
V$PROCESS 记录服务器进程信息。