一、背景
达梦数据库使用的是单进程、多线程架构,服务器在运行时由各种内存数据结构和一系列的线程组成,线程分为多种类型,不同类型的线程完成不同的任务。线程通过一定的同步机制对数据结构进行并发访问和处理,以完成客户提交的各种任务。DM 数据库服务器是共享的服务器,允许多个用户连接到同一个服务器上,服务器进程称为共享服务器进程。
要了解达梦数据库的线程管理,我们可以先了解一下达梦数据库大致的体系结构,如图所示:
从上面可以看到,在进程里,包含各种各样的线程,其中最主要的就是监听线程、工作线程、IO线程、调度线程、日志线程等。
二、线程介绍
监听线程
监听线程主要的任务是在服务器端口上进行循环监听,一旦有来自客户的连接请求,监听线程被唤醒并生成一个会话申请任务,加入工作线程的任务队列,等待工作线程进行处理。它在系统启动完成后才启动,并且在系统关闭时首先被关闭。为了保证在处理大量客户连接时系统具有较短的响应时间,监听线程比普通线程优先级更高。
工作线程
从任务队列中取出任务,并根据任务的类型进行相应的处理,负责所有实际的数据相关操作,初始工作线程个数由配置文件指定,随着会话连接的增加,工作线程也会同步增加,以保持每个会话都有专门的工作线程处理请求,即单个会话由单个工作线程处理其所有请求;当会话连接超过预设的阀值时,工作线程数目不再增加,转而由会话轮询线程接收所有用户请求,加入任务队列,等待工作线程一旦空闲,从任务队列依次摘取请求任务处理。
IO线程
IO线程的工作主要由三种:
1. 需要处理的数据页不在缓冲区中,此时需要将相关数据页读入缓冲区;
2. 缓冲区满或系统关闭时,此时需要将部分脏数据页写入磁盘;
3. 检查点到来时,需要将所有脏数据页写入磁盘。
IO 线程在启动后,通常都处于睡眠状态,当系统需要进行 IO 时,只需要发出一个 IO请求,此时 IO 线程被唤醒以处理该请求,在完成该 IO 操作后继续进入睡眠状态。可以通过设置 dm.ini 文件中的 IO_THR_GROUPS 参数来设置,默认情况下,IO 线程的个数是 2 个;同时,IO 线程处理 IO 的策略根据操作系统平台的不同会有很大差别,一般情况下,IO 线程使用异步的 IO 将数据页写入磁盘,此时,系统将所有的 IO 请求直接递交给操作系统,操作系统在完成这些请求后才通知 IO 线程,这种异步 IO 的方式使得IO 线程需要直接处理的任务很简单,即完成 IO 后的一些收尾处理并发出 IO 完成通知,如果操作系统不支持异步 IO,此时 IO 线程就需要完成实际的 IO 操作。
调度线程
调度线程用于接管系统中所有需要定时调度的任务,每秒钟轮询一次,负责的任务有以下一些:
1. 检查系统级的时间触发器,如满足触发条件,则生成任务加到工作线程的任务队列,由工作线程执行;
2. 清理 SQL 缓存、计划缓存中失效的项,或者超出缓存限制后淘汰不常用的缓存项;
3. 检查数据重演捕获持续时间是否到期,到期则自动停止捕获;
4. 执行动态缓冲区检查。根据需要动态扩展或动态收缩系统缓冲池;
5. 自动执行检查点。为了保证日志的及时刷盘,减少系统故障时恢复时间,根据 INI参数设置的自动检查点执行间隔定期执行检查点操作;
6. 会话超时检测。当客户连接设置了连接超时时,定期检测是否超时,如果超时则自动断开连接;
7. 必要时执行数据更新页刷盘;
8. 唤醒等待的工作线程。
日志FLUSH线程
任何数据库的修改,都会产生重做 REDO 日志,为了保证数据故障恢复的一致性,REDO日志的刷盘必须在数据页刷盘之前进行。事务运行时,会把生成的 REDO 日志保留在日志缓冲区中,当事务提交或者执行检查点时,会通知 FLUSH 线程进行日志刷盘。由于日志具备顺序写入的特点,比数据页分散 IO 写入效率更高。日志 FLUSH 线程和 IO 线程分开,能获得更快的响应速度,保证整体的性能。DM7 的日志 FLUSH 线程进行了优化,在刷盘之前,对不同缓冲区内的日志进行合并,减少了 IO 次数,进一步提高了性能。如果系统配置了实时归档,在 FLUSH 线程日志刷盘前,会直接将日志通过网络发送到实时备库。如果配置了本地归档,则生成归档任务,通过日志归档线程完成。
日志归档线程
日志归档线程包含异步归档线程,负责远程异步归档任务。如果配置了非实时归档,由日志FLUSH 线程产生的任务会分别加入日志归档线程,日志归档线程负责从任务队列中取出任务,按照归档类型做相应归档处理。将日志 FLUSH 线程和日志归档线程分开的目的是为了减少不必要的效率损失,除了远程实时归档外,本地归档、远程异步归档都可以脱离 FLUSH 线程来做,如果放在 FLUSH 线程中一起做会严重影响系统性能。
日志APPLY线程
在配置了数据守护的系统中,创建了一个日志 APPLY 线程。当服务器作为备库时,每次接收到主库的物理 REDO 日志生成一个 APPLY 任务加入到任务队列,APPLY 线程从任务队列中取出一个任务在备库上将日志重做,并生成自己的日志,保持和主库数据的同步或一致,作为主库的一个镜像。备库数据对用户只读,可承担报表、查询等任务,均衡主库的负载。
定时器线程
在数据库的各种活动中,用户常常需要数据库完成在某个时间点开始进行某种操作,如备份;或者是在某个时间段内反复进行某种操作等。定时器线程就是为这种需求而设计的。通常情况下,DM Server 需要进行定时操作的事件主要有以下几种:
1. 逻辑日志异步归档;
2. 异步归档日志发送(只有在 PRIMARY 模式下,且是 OPEN 状态下);
3. 作业调度。
定时器线程启动之后,每秒检测一次定时器链表,查看当前的定时器是否满足触发条件,如果满足,则把执行权交给设置好的任务,如逻辑日志异步归档等。
默认情况下,达梦服务器启动的时候,定时器线程是不启动的。用户可以设置 dm.ini中的 TIMER_INI 参数为 1 来设置定时器线程在系统启动时启动。
逻辑日志归档线程
逻辑日志归档用于 DM7 的数据复制中,目的是为了加快异地访问的响应速度,包含本地逻辑日志归档线程和远程逻辑日志归档线程。当配置了数据复制,系统才会创建这两个线程。
1. 本地逻辑日志归档线程
本地归档线程从本地归档任务列表中取出一个归档任务,生成到逻辑日志,并将逻辑日志写入到逻辑日志文件中。如果当前逻辑日志的远程归档类型是同步异地归档并且当前的刷盘机制是强制刷盘,那么就生成一个异地归档任务加入到临时列表中。
2. 远程逻辑日志归档线程
远程归档线程从远程归档任务列表中取出一个归档任务,并根据任务的类型进行相应的处理。任务的类型包括同步发送和异步发送。
MAL系统相关
MAL 系统是 DM 内部高速通信系统,基于 TCP/IP 协议实现。服务器的很多重要功能都是通过 MAL 系统实现通信的,例如数据守护、数据复制、MPP、远程日志归档等。MAL 系统内部包含一系列线程,有 MAL 监听线程、MAL 发送工作线程、MAL 接收工作线程等。
其他线程
DM 数据库系统中还不止以上这些线程,在一些特定的功能中会有不同的线程,例如回滚段清理 PURGE 线程、审计写文件线程、重演捕获写文件线程等。
三、线程查看
达梦数据库提供了各种动态视图,以提供对数据库线程的管理,具体如下图:
视图名称 | 说明 |
V$LATCHES | 记录当前等待的线程信息 |
V$THREADS | 记录当前系统中活动的线程信息 |
V$WTHRD_HISTORY | 记录系统启动以来,所有活动过线程相关信息 |
V$PROCESS | 记录服务器进程信息 |
查询当前等待的线程信息
结果各字段说明如下:
查询当前系统中活动的线程信息:
从NAME列,就可以看到很多上面介绍到的各种类型的线程,比如IO线程 ,具体字段说明如下:
查询系统启动以来,所有活动过的线程信息:
解析各字段含义如下:
查询服务器进程信息
解析各字段含义如下:
了解更多达梦数据库相关知识,可以访问达梦官网文档学习