Oracle 12c 特性之 多线程模式- -Multithreaded Oracle Database Model

在《Database Concepts》的Process Architecture部分,讲到12c引入的一个新的特性,叫做Multithreaded Oracle Database Model。

之前在Unix/Linux等环境下,数据库是以多进程的方式运行的,当一个会话连接进来,就会通过监听,然后在服务器上创建一个前台进程,数据库后台进程也是以多进程方式运行的。而在Windows上面以多线程的方式来运行,windows下的oracle db的一个进程有很多个线程,而到了12c这个版本,Oracle在Unix/Linux平台上做出了一些改变,引入了多线程的模式。

这个特性由threaded_execution这个参数来控制,通过这个参数,可以控制数据库以多进程方式运行或者以多线程方式运行,该参数默认是false。数据库以多进程方式运行。

在默认情况下,查看linux下oracle的进程如下:

在此不一一介绍这些进程了。之后修改参数。

重启数据库会报错:

这是正常的。因为改为多线程模式之后,本地OS验证会失效,需使用密码+TNS方式登录。这里无法启动的解决办法有三个,如果是RAC的话,可以通过srvctl start database方式启动,单实例的话,一是可以用/nolog+conn sys as sysdba输入密码登录来继续数据库mount和open,二是可以设置export ORA_SERVER_THREAD_ENABLED=false这个环境变量来实现sqlplus / as sysdba登录启动数据库。

这个时候,数据库的进程就非常少了:

可以看到,消失了大量的进程,包括之前我们说的非常核心的后台进程,如ckpt,smon等等等等。

官方的解释如下:

In a database running in threaded mode, PMON and DBW might run as operating system processes, whereas LGWR and CMON might run as threads within a single process. Two foreground processes and a parallel execution (PX) server process might run as threads in a second operating system process. A third operating system process might contain multiple foreground threads. Thus, “Oracle process” does not always mean “operating system process.”

PMON,DBW必须继续用操作系统进程方式运行,LGWR和CMON在同一个进程里。两个前台进程和并行PX进程运行在一个OS进程里。第三个OS进程包含了其他所有的前台进程。

此时,如果从客户端连接数据库,每一个连接依然会独立创建一个操作系统进程。我从客户端连接连个会话,会看到两个LOCAL=NO的进程:

官方文档中描述:

Also, when this initialization parameter is set to TRUE, the DEDICATED_THROUGH_BROKER_listener-name=ON parameter should be added to the listener.ora file, where listener-name is the name of the Oracle Net listener. This enables the server to spawn threads when connections to the database are requested through the listener.

需要修改监听参数
DEDICATED_THROUGH_BROKER_listener-name=ON

修改如下:

之后通过远程客户端连接,不再生成LOCAL=NO的进程,OS上生成了一个类似ora_u00b_ORA19x的进程,跟文档描述一致。

对v$session和v$process关联查询:

这个查询结果很明显的可以看出来,PMON依然是进程,SCMN,CLMN,GEN0,MMAN,DBRM,PMAN,CKPT,SMON,LREG是线程模式,被封装在11496这个进程里,这个进程是ora_u002_ORA19x。PSP0和VKTM依然是进程模式。第二个SCMN和GEN1被分装在11512进程里,这个进程是ora_gen1_ORA19x。SCMN,DIAG,VKRM,SVCB,DIA0,SMCO,RECO,W000,W001,PXMN,MMON,MMNL,M000,W002,AQPC,CJQ0,W003,M001,M002,W004,M003,M004,QM02,Q003,Q004,Q008,W005,W006,W007被封装在11515进程里,这个进程是ora_u006_ORA19x。第三个SCMN和OFSD封装在11518(ora_ofsd_ORA19x)里。DBW0依然是进程模式。SCMN,LGWR,LG00,LG01被封装在11528(ora_lgwr_ORA19x)里。SCMN,TMON,TT00,ARC0,TT01,ARC1,ARC2,ARC3,TT02被封装在11546(ora_u00a_ORA19x)里。4个客户端连接被封装在单独的一个进程19368(ora_u00b_ORA19x)里。

可以看到每个启用了多线程的进程都有个SCMN线程,这个线程作为本进程内监听其他线程的线程。这个SCMN在MOS上检索会发现一个12.1.0.2上的BUG。

下面尝试在OS层面来杀这些进程,看看数据库表现。

首先PMON就不测试了。。。

kill u002进程,数据库会挂掉:

CLMN是一个很重要的进程:

Cleanup Main Process (CLMN)
PMON delegates cleanup work to the cleanup main process (CLMN). The task of detecting abnormal termination remains with PMON.
CLMN periodically performs cleanup of terminated processes, terminated sessions, transactions, network connections, idle sessions, detached transactions, and detached network connections that have exceeded their idle timeout.
Cleanup Helper Processes (CLnn)
CLMN delegates cleanup work to the CLnn helper processes.
The CLnn processes assist in the cleanup of terminated processes and sessions. The number of helper processes is proportional to the amount of cleanup work to be done and the current efficiency of cleanup.
A cleanup process can become blocked, which prevents it from proceeding to clean up other processes. Also, if multiple processes require cleanup, then cleanup time can be significant. For these reasons, Oracle Database can use multiple helper processes in parallel to perform cleanup, thus alleviating slow performance.
The V$CLEANUP_PROCESS and V$DEAD_CLEANUP views contain metadata about CLMN cleanup. The V$CLEANUP_PROCESSview contains one row for every cleanup process. For example, if V$CLEANUP_PROCESS.STATE is BUSY, then the process is currently engaged in cleanup.

PMON将清理工作委托给清理主进程(CLMN)。检测异常终止的任务仍然是PMON。
CLMN定期执行已终止进程,已终止会话,事务,网络连接,空闲会话,分离事务以及已超出其空闲超时的已分离网络连接的清除。
清理助手进程(CLnn)
CLMN将清理工作委托给CLnn帮助程序进程。
CLnn进程有助于清除已终止的进程和会话。辅助进程的数量与要完成的清理工作量和当前清理效率成正比。
清理过程可能会被阻止,从而阻止其继续清理其他进程。此外,如果多个进程需要清理,那么清理时间可能很长。由于这些原因,Oracle数据库可以并行使用多个辅助进程来执行清理,从而缓解性能下降。

可以看到Pmon将进程清理的工作交给了CLMN,我们遇到过多次PMON清理进程时候,拿不到LATCH,导致PMON挂掉等等故障。不知道Oracle把这个功能独立出来是不是为了解决这个问题?

杀PSP0进程也会导致数据库crash:

PSP是Process SPawner的意思,它负责创建job进程及管理其他进程的小工进程等等,显然是个很重要的进程。

杀VKTM进程也会导致数据库crash:

VKTM作为两组时间的发布者,必要在数据库中扮演重要的角色。

杀GEN1进程,GEN1会自动重启:

GEN1跟GEN0一样,都是所谓常规任务的执行进程,执行客户端的DML和DQL类的SQL任务。看来并不是核心进程。

杀u006进程,上文提到这个进程包含了除了几个核心进程之外的其他进程(线程),杀了这个进程之后,这个进程会重启,相关的线程也会跟着重启。

这些线程相关的小工线程(000,001之类)也会被重启。

杀OFSD进程,进程也会自动重启。OFS是Oracle Filesystem Server,一种类似DBFS的FS,也是基于表空间的文件系统。

杀LGWR进程,注意这个进程包含了几个log write相关的线程。可以预见数据库会crash的。

杀DBW0进程,数据库也会crash,这跟db block write及部分检查点功能相关。

杀u00a进程,这个进程包含跟归档ARC相关和redo日志传输到备库相关的TT进程。理论上杀这个进程,也不会影响数据库,数据库的PMON会重启TMON,TMON会重启这些归档和redo传输进程,日志也是如此:

最后是u00b进程,这个进程全部都是客户端的连接进程。这个杀了就杀了吧。

在《Database Concepts》的Process Architecture部分,讲到12c引入的一个新的特性,叫做Multithreaded Oracle Database Model。

之前在Unix/Linux等环境下,数据库是以多进程的方式运行的,当一个会话连接进来,就会通过监听,然后在服务器上创建一个前台进程,数据库后台进程也是以多进程方式运行的。而在Windows上面以多线程的方式来运行,windows下的oracle db的一个进程有很多个线程,而到了12c这个版本,Oracle在Unix/Linux平台上做出了一些改变,引入了多线程的模式。

这个特性由threaded_execution这个参数来控制,通过这个参数,可以控制数据库以多进程方式运行或者以多线程方式运行,该参数默认是false。数据库以多进程方式运行。

在默认情况下,查看linux下oracle的进程如下:

在此不一一介绍这些进程了。之后修改参数。

重启数据库会报错:

这是正常的。因为改为多线程模式之后,本地OS验证会失效,需使用密码+TNS方式登录。这里无法启动的解决办法有三个,如果是RAC的话,可以通过srvctl start database方式启动,单实例的话,一是可以用/nolog+conn sys as sysdba输入密码登录来继续数据库mount和open,二是可以设置export ORA_SERVER_THREAD_ENABLED=false这个环境变量来实现sqlplus / as sysdba登录启动数据库。

这个时候,数据库的进程就非常少了:

可以看到,消失了大量的进程,包括之前我们说的非常核心的后台进程,如ckpt,smon等等等等。

官方的解释如下:

In a database running in threaded mode, PMON and DBW might run as operating system processes, whereas LGWR and CMON might run as threads within a single process. Two foreground processes and a parallel execution (PX) server process might run as threads in a second operating system process. A third operating system process might contain multiple foreground threads. Thus, “Oracle process” does not always mean “operating system process.”

PMON,DBW必须继续用操作系统进程方式运行,LGWR和CMON在同一个进程里。两个前台进程和并行PX进程运行在一个OS进程里。第三个OS进程包含了其他所有的前台进程。

此时,如果从客户端连接数据库,每一个连接依然会独立创建一个操作系统进程。我从客户端连接连个会话,会看到两个LOCAL=NO的进程:

官方文档中描述:

Also, when this initialization parameter is set to TRUE, the DEDICATED_THROUGH_BROKER_listener-name=ON parameter should be added to the listener.ora file, where listener-name is the name of the Oracle Net listener. This enables the server to spawn threads when connections to the database are requested through the listener.

需要修改监听参数
DEDICATED_THROUGH_BROKER_listener-name=ON

修改如下:

之后通过远程客户端连接,不再生成LOCAL=NO的进程,OS上生成了一个类似ora_u00b_ORA19x的进程,跟文档描述一致。

对v$session和v$process关联查询:

这个查询结果很明显的可以看出来,PMON依然是进程,SCMN,CLMN,GEN0,MMAN,DBRM,PMAN,CKPT,SMON,LREG是线程模式,被封装在11496这个进程里,这个进程是ora_u002_ORA19x。PSP0和VKTM依然是进程模式。第二个SCMN和GEN1被分装在11512进程里,这个进程是ora_gen1_ORA19x。SCMN,DIAG,VKRM,SVCB,DIA0,SMCO,RECO,W000,W001,PXMN,MMON,MMNL,M000,W002,AQPC,CJQ0,W003,M001,M002,W004,M003,M004,QM02,Q003,Q004,Q008,W005,W006,W007被封装在11515进程里,这个进程是ora_u006_ORA19x。第三个SCMN和OFSD封装在11518(ora_ofsd_ORA19x)里。DBW0依然是进程模式。SCMN,LGWR,LG00,LG01被封装在11528(ora_lgwr_ORA19x)里。SCMN,TMON,TT00,ARC0,TT01,ARC1,ARC2,ARC3,TT02被封装在11546(ora_u00a_ORA19x)里。4个客户端连接被封装在单独的一个进程19368(ora_u00b_ORA19x)里。

可以看到每个启用了多线程的进程都有个SCMN线程,这个线程作为本进程内监听其他线程的线程。这个SCMN在MOS上检索会发现一个12.1.0.2上的BUG。

下面尝试在OS层面来杀这些进程,看看数据库表现。

首先PMON就不测试了。。。

kill u002进程,数据库会挂掉:

CLMN是一个很重要的进程:

Cleanup Main Process (CLMN)
PMON delegates cleanup work to the cleanup main process (CLMN). The task of detecting abnormal termination remains with PMON.
CLMN periodically performs cleanup of terminated processes, terminated sessions, transactions, network connections, idle sessions, detached transactions, and detached network connections that have exceeded their idle timeout.
Cleanup Helper Processes (CLnn)
CLMN delegates cleanup work to the CLnn helper processes.
The CLnn processes assist in the cleanup of terminated processes and sessions. The number of helper processes is proportional to the amount of cleanup work to be done and the current efficiency of cleanup.
A cleanup process can become blocked, which prevents it from proceeding to clean up other processes. Also, if multiple processes require cleanup, then cleanup time can be significant. For these reasons, Oracle Database can use multiple helper processes in parallel to perform cleanup, thus alleviating slow performance.
The V$CLEANUP_PROCESS and V$DEAD_CLEANUP views contain metadata about CLMN cleanup. The V$CLEANUP_PROCESSview contains one row for every cleanup process. For example, if V$CLEANUP_PROCESS.STATE is BUSY, then the process is currently engaged in cleanup.

PMON将清理工作委托给清理主进程(CLMN)。检测异常终止的任务仍然是PMON。
CLMN定期执行已终止进程,已终止会话,事务,网络连接,空闲会话,分离事务以及已超出其空闲超时的已分离网络连接的清除。
清理助手进程(CLnn)
CLMN将清理工作委托给CLnn帮助程序进程。
CLnn进程有助于清除已终止的进程和会话。辅助进程的数量与要完成的清理工作量和当前清理效率成正比。
清理过程可能会被阻止,从而阻止其继续清理其他进程。此外,如果多个进程需要清理,那么清理时间可能很长。由于这些原因,Oracle数据库可以并行使用多个辅助进程来执行清理,从而缓解性能下降。

可以看到Pmon将进程清理的工作交给了CLMN,我们遇到过多次PMON清理进程时候,拿不到LATCH,导致PMON挂掉等等故障。不知道Oracle把这个功能独立出来是不是为了解决这个问题?

杀PSP0进程也会导致数据库crash:

PSP是Process SPawner的意思,它负责创建job进程及管理其他进程的小工进程等等,显然是个很重要的进程。

杀VKTM进程也会导致数据库crash:

VKTM作为两组时间的发布者,必要在数据库中扮演重要的角色。

杀GEN1进程,GEN1会自动重启:

GEN1跟GEN0一样,都是所谓常规任务的执行进程,执行客户端的DML和DQL类的SQL任务。看来并不是核心进程。

杀u006进程,上文提到这个进程包含了除了几个核心进程之外的其他进程(线程),杀了这个进程之后,这个进程会重启,相关的线程也会跟着重启。

这些线程相关的小工线程(000,001之类)也会被重启。

杀OFSD进程,进程也会自动重启。OFS是Oracle Filesystem Server,一种类似DBFS的FS,也是基于表空间的文件系统。

杀LGWR进程,注意这个进程包含了几个log write相关的线程。可以预见数据库会crash的。

杀DBW0进程,数据库也会crash,这跟db block write及部分检查点功能相关。

杀u00a进程,这个进程包含跟归档ARC相关和redo日志传输到备库相关的TT进程。理论上杀这个进程,也不会影响数据库,数据库的PMON会重启TMON,TMON会重启这些归档和redo传输进程,日志也是如此:

最后是u00b进程,这个进程全部都是客户端的连接进程。这个杀了就杀了吧。

基本到这儿就看的基本明了了。但是这个特性是为了解决什么问题的 ?是为了避免操作系统进程过多,消耗资源?归根到底,在UNIX/LINUX下的oracle到底用哪种模式好? 提升性能吗?让维护变的更复杂吗?

网上找到的

祭出神器…swingbench…

200个会话,多线程模式测试:

首先,虽然多线程模式,但是数据库依然认为连接数受process参数来限制,超出的依然会报错:

跑出来的结果大概是:

大概TPM是39248

观察OS的TOP,负载较高,主要消耗资源的是这几个u00x进程的scmn监听线程,每个里面大概四五十个线程,都是来自客户端的会话。

scmn这几个线程监听程序消耗资源很高,这里不显示为u00x

200个会话,多进程模式测试:

34835左右

单从两种模式的测试结果来看,多线程模式的测试性能最多要比多进程模式好13%左右。

多次测试的结果多线程模式都好于多进程模式,提升幅度有大有小。看起来多线程模式确实是有利于性能提升。但是CPU的使用率要比多进程模式高10%到15%。这个应该是CPU上下文切换导致的。

总结:

不太理解这个特性有啥用。。。

–END–

发表评论