加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

达梦7的线程

(2013-01-03 20:00:52)
标签:

达梦数据库

dm7

sql

dbms

并发与事务

it

DM7是一个单进程多线程服务器,查询v$threads, 可以看到当前正在运行的线程(主线程除外):

SQL>select count(*), name from v$threads group by name order by 1;

行号       COUNT(*)            NAME

---------- ------------------- --------------------

                          aud_flush_thread

                          purg2_thread

                          uthr_db_thread

                          rapply_worker_thread

                          nsvr_lsnr_thread

                          ckpt2_flush_thread

                          nsvr_schedule_thread

                          rlog4_flush_thread

                          hio_thread

10                          os_io_thread

11                          rsys_work_thread

12                          lthd_worker_thread

13                          uthr_worker_thread

14                          ntsk_worker_thread

aud_flush_thread

这个线程仅用于审计文件的刷新。当没有打开审计时,这个线程处于休眠状态。 系统中仅有一个aud_flush_thread.

Purg2_thread

这是一个非常重要的线程。Purg2_thread负责清理回滚段。它每隔一秒钟检查一次是否有可清理的回滚记录,如果有就立即清理。

uthr_db_thread

         这是对应每一个会话的服务线程,类似DM6的工作线程。   DM7中对每一个会话,服务器都会创建一个独立的线程为其服务。这种一对一的模式,简化了并发时的实现逻辑。

Apply_worker_thread

         这个线程是在数据守护环境下,备机用于重做来自主机的redo日志。常规情况下,这个线程处于休眠状态。

nsvr_lsnr_thread

         负责监听连接端口,当有新连接到达时,通知工作线程创建新会话。

ckpt2_flush_thread

         检查点(CHECKPOINT)线程,负责生成检查点,把缓冲区中的部分或全部更新页写入磁盘,并调整检查点信息。

nsvr_schedule_thread

         负责执行需要定时执行的动作,如定时触发一个检查点,定时检查是否需要动态扩展/收缩系统缓冲区等。

rlog4_flush_thread

         负责把redo日志写入日志文件,并在必要时通知rsys_worker_thread写归档日志。

hio_thread

         负责huge table数据的读写。

os_io_thread

         负责传统数据页的读写,在系统缓冲区与硬盘间传输数据。可以有配置成多个。

rsys_work_thread

         负责各类归档日志的写入。

lthd_worker_thread

         并行线程,用于实现并行(parallel)查询。

uthr_worker_thread

         工作组线程。其数量由WORKER_THREADS配置。在DM7中, WORKER_THEADS的含义与DM6不一样,一个工作组会共享一些信息。当nsvn_lsn_thread接到一个新的连接请求时,它会挑选一个uthr_worker_thread, 把新达到的连接分配给它,由uthr_worker_thread创建uthr_db_thread来提供服务,因此uthr_worker_thread自己并不作太多的工作。由同一个uthr_worker_thread创建的uthr_db_thread属于同一个工作组。

ntsk_worker_thread

         备用任务线程。其数量由TASK_THREADS配置。用于执行一些系统级的异步任务。如:处理一些邮件命令,在共享集群环境下,处理一些远程的IO请求。

 

工作组

         减少并发冲突,是引入工作组概念的原因。同一个工作组中的服务线程将共享一些信息。这些共享资源只被组内成员所共享,可以减少并发冲突。

 

批量列数据池(BDTA_COLDATA_POOL)。在执行SQL操作符时,需要创建BDTA用来在节电点之间传递数据,这些数据按照不同的数据类型,会申请/释放特定大小的空间。系统把这些以列的类型所决定的空间单位收集起来,放入一个池中,以便快速重用。这个重用池被称为批量列数据池。

        

         目前,这个池的大小固定为2M字节,后面会改为可配置,其使用状态可以查询V$POOL,

SQL>select top 10 v_size, used,  v_desc from v$vpool

where v_desc = 'RT_MEMOBJ_VPOOL' and v_size = 2097024;

 

行号       V_SIZE              USED                V_DESC

---------- ------------------- ------------------- ---------------

         2097024             588096              RT_MEMOBJ_VPOOL

         2097024             177088              RT_MEMOBJ_VPOOL

         2097024             25728               RT_MEMOBJ_VPOOL

         2097024             384                 RT_MEMOBJ_VPOOL

 

因为WORKER_THREADS = 4, 所以有4个组,上例中,每个池的使用率都不高。

 

另外,工作组的数量也决定了回滚段的数量,后者为工作组数加一。每组分配一个回滚段,另一个公共段用于异步执行的非用户连接事务。

用户态线程

     如果设置了UTHR_FLAG = 1, 为每个连接创建的服务线程将不是创建操作系统级的uthr_db_thread线程,在V$THREAD中也查不到uthr_db_thread,而是用户态线程(UTHR)

 

操作系统内核感知不到用户态线程的存在, UTHR之间的多任务执行是一种协作并发模式,只有符合下列条件时才发生切换:

Ø  主动释放 CPU, 调用uthr_yield()

Ø  缓冲区 IO等待

Ø  网络IO等待

Ø  rw_lock等待

Ø  事务锁等待

因此在任何时候,同一组内最多只有一个活动的UTHR。组内所有的UTHR都由工作组线程驱动执行,组内的共享资源不需要保护,所有的并发冲突都只可能发生在与其他组的UTHR发生竞争的时候。

 

使用用户态线程模式,系统使用有限的工作组线程来为所有的连接服务,这个模式可以极大减少线程的个数,提升大量连接下的并发性能。但是目前在非x86平台上,还有些缺陷,需要完善。

DM7用户态线程与DM6的固定工作线程模式非常类似,但是有所区别:

Ø  DM6使用状态机来实现固定工作线程。工作线程在处理另一个回话的请求前必须把当前现场信息全部存入SQL操作符的上下文中,并把堆栈退回到最初状态。

Ø  DM7的每一个UTHR都有自己独立的堆栈,可以非常方便地切换,简化了系统逻辑。

两者都是用固定的线程实现了大量连接的并发处理。

 

如果WORKER_CPU_PERCENT 不为0, 则在linux 平台下,系统试图为 工作组线程和工作线程(UTHR_DB_THREAD)指定CPU绑定,以进一步减少上下文切换。绑定的CPU个数由逻辑CPU个数 * WORKER_CPU_PERCENT / 100决定。

 

注意:用户态线程一般适合CPU/核的个数相对较少,而连接相对较多的应用。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有