1.3 Oracle的进程组织方案
在用户通过客户端访问数据的过程中,读取数据的载体是进程。Oracle中的进程可分为用户进程、服务器进程及后台进程这三类。还有一种特殊类别的进程是监听进程(相关知识将在9.2节介绍)。
这里需要注意的一点是,用户进程或应用程序所连接的应用服务器进程不能直接存取Oracle数据库中的数据,必须借助Oracle服务器进程才能访问并处理数据。根据用户进程、服务器进程及后台进程这三者的关系,Oracle数据库中的进程组织方案包含如下3种:2N方案、N+M方案和多线程方案。下面先介绍前两种进程组织方案。
1.3.1 2N方案:一个数据库服务器进程对应一个用户进程
每个用户进程均有一个数据库服务器进程为之服务,这个进程称为服务器进程。在该方案中,如果有N个用户进程需要连接数据库,就要启动N个服务器进程,也就是说,一共有2N个进程,因此这种方案称为2N方案,它对应于Oracle的专用服务器模式。在进行数据库性能优化时,这种模式的效率通常很高,相当于一对一专人服务,但同时会消耗更多的操作系统内存及CPU资源。2N方案(Oracle专用服务器模式)如图1-9所示。
图1-9 2N方案
在这种情况下,Oracle的各个服务器进程都是独立运行的。因此,用户进程与服务器进程之间以及各服务器进程之间都要通信。在这种方案中,Oracle数据库服务器的主要负载表现在空间和时间两个方面。在空间上,虽然各个服务器进程的代码段可以共享,但数据段和栈段的空间还是各自独立的,再加上操作系统要为多出来的N个服务器进程分配进程控制块等诸多内部空间,因此2N 结构对内存的需求量很大。如果物理内存远远小于各个进程所需空间之和,那么该模式就会出现各进程被操作系统频繁换入换出的问题,系统可能出现颠簸(即性能抖动)。在时间上,由于2N方案中进程数目过多(活动进程大于CPU逻辑核数),因此大量CPU时间会白白浪费在进程切换这种会消耗大量资源的工作上。
在这个方案中,增加一个用户的资源开销会很大。在Oracle服务器内存配置规划阶段,不仅要为SGA和PGA保留足够多的空间,还必须为进程控制块保留足够多的空间。一般一个用户的内存量按3~5MB配置较为合适。比如,系统需要1000个用户(对应于参数文件中的server process参数)链接,那么我们需要为操作至少保留3~5GB的空闲内存空间。
除了每个用户进程需要一个服务器进程之外,Oracle数据库在全局上还要维护若干个后台服务进程。这些后台进程通过SGA完成监控、写数据、写日志、死锁检测和解除等诸多全局工作。频繁的进程通信意味着频繁的进程切换。少数几个后台进程有可能会成为整个系统的瓶颈。此外,数据不在内存中的情况也有可能会造成性能问题和临界资源(lock和latch)问题,相关内容将在后续章节中进一步讨论。
把多个服务器进程合并为一个进程,也许可以有效解决以上问题。因此,针对大量用户需要访问且内存有限的OLTP(On-Line Transaction Processing,联机事务处理)场景,Oracle提供了N+M方案。N+M方案最主要的优势是节省内存。
1.3.2 N+M方案:M个数据库服务器进程对应N个用户进程
在N+M方案中,Oracle采用M个服务器进程为N个用户进程提供服务(M< N),这个方案称为共享服务器模式。通过DBCA创建数据库时,在创建页面上会有共享服务器模式和专用服务器模式这两种选项,默认为专用服务器模式,一般也选用此模式。Oracle N+M方案(共享服务器模式)如图1-10所示。
图1-10 N+M方案
在该方案中,服务器进程不再负责多任务调度,同时每个用户进程也不再固定地对应于某个服务器进程。用户的数据库请求将会被动态地分配给某个调度器进程。调度器进程的分派由分派程序完成。分派程序还会监测整个数据库的运行状况并根据用户请求队列的情况动态增减共享服务器进程的个数。
如果用户进程增加,则共享服务器进程的个数也会增多,但后者一般小于前者(即M <N)。这样,我们就不必为10000个数据库连接创建10000个专用服务器进程了,只需要建立很少的一部分进程即可。可想而知,这些进程将由所有用户进程共享,这样Oracle就能让更多的用户与数据库连接。
假设让数据库服务器管理10000个进程,如果一个用户进程按5MB的进程控制块开销来算,服务器除了SGA和PGA外还需要为进程管理预留50GB的内存空间,这样的内存需求和进程管理负载所带来的压力可想而知,但按共享服务器模式管理500个或者1000个进程还是可以的。采用共享服务器模式,通过客户端连接配置也能实现专用服务器模式来连接数据库,两者可以并存,如图1-11所示。
图1-11 共享服务器模式下采用专用服务器模式进行连接
N+M方案是2N方案的一种改进方案,提高了内存资源的利用率,但没有克服2N方案的本质弱点。此外,分派程序对系统增加了额外的开销并可能成为瓶颈,而且共享服务器进程动态增减的开销也很大。
从Oracle 12c开始,Oracle开始采用多线程方案(参见11.4节)。