Oracle服务器进程

Oracle中的各个进程要完成某个特定的任务或一组任务,每个进程都会分配内部内存(PGA内存)来完成它的任务。

Oracle实例主要有3类进程:

A 服务器进程 server process
根据客户的请求来完成工作。专用/共享服务器,就是服务器进程

B 后台进程 background process
随数据库而启动,完成各种维护任务,如将块写至磁盘、维护在线重做日志、清理异常中止的进程等。

C 从属进程 slave process

类似于后台进程,不过它们要代表后台进程或服务器进程完成一些额外的工作。


A服务器进程

代表客户会话完成工作的进程。应用向数据库发送的SQL语句最后就要由这些进程接收并执行。

dedicated server连接
会在服务器上得到针对这个连接的一个专用进程。数据库连接与服务器上的一个进程之间存在一对一的映射。

shared server
多个会话可以共享一个服务器进程池,其中的进程由Oracle实例生成和管理。

你所连接的是一个数据库调度器(dispatcher),而不是特意为连接创建的一个专用服务器进程。


专用or共享 服务器进程的任务是一样的:要处理你提交的所有SQL。当你向数据库提交一个SELECT * FROM EMP查询时,会有一个Oracle专用/共享服务器进程解析这个查询并把它放在共享池中(或者最好能发现这个查询已经在共享池中)。这个进程要提出查询计划,如果必要,还要执行这个查询计划可能在缓冲区缓存中找到必要的数据,或者将数据从磁盘读入缓冲区缓存中。这些服务器进程是干重活的进程。在很多情况下,你都会发现这些进程占用的系统CPU时间最多,因为正是这些进程来执行排序、汇总、联结等等工作,几乎所有工作都是这些进程做的。

------------------------------------------------------------------------专用服务器

客户应用中链接着Oracle库,这些库提供了与数据库通信所需的API。这些API知道如何向数据库提交查询,并处理返回的游标。它们知道如何把你的请求打包为网络调用,专用服务器则知道如何将这些网络调用解开。这部分软件称为Oracle Net,这是一个网络软件/协议,Oracle利用这个软件来支持客户/服务器处理(即使在一个n层体系结构中也会“潜伏”着客户/服务器程序)。不过,即使从技术上讲没有涉及Oracle Net,Oracle也采用了同样的体系结构。也就是说,即使客户和服务器在同一台机器上,也会采用这种两进程(也称为两任务)体系结构。这个体系结构有两个好处:
1.远程执行(remote execution):客户应用可能在另一台机器上执行(而不是数据库所在的机器)
2.地址空间隔离(address space isolation):服务器进程可以读写SGA。如果客户进程和服务器进程物理地链接在一起,客户进程中一个错误的指针就能轻松地破坏SGA中的数据结构。

可以在同一台机器上运行客户和服务器,就能很清楚地看出这种父/子进程的创建

scott@ORCL>select a.spid dedicated_server,
  2  b.process clientpid
  3  from v$process a, v$session b
  4  where a.addr = b.paddr
  5  and b.sid = (select sid from v$mystat where rownum=1)
  6  /

DEDICATED_SERVER         CLIENTPID
------------------------ ------------------------
5748                     1408:3388

查询与专用服务器相关联的进程ID(PID),从V$PROCESS得到的SPID是执行该查询时所用进程的操作系统PID



shared server

共享服务器连接强制要求必须使用Oracle Net,即使客户和服务器都在同一台机器上也不例外。如果不使用Oracle TNS监听器,就无法使用共享服务器。客户应用会连接到Oracle TNS监听器,并重定向或转交给一个调度器。调度器充当客户应用和共享服务器进程之间的“导管”。


在此可以看到,客户应用(其中链接了Oracle库)会与一个调度器进程物理连接。调度器只负责从客户应用接收入站请求,并把它们放入SGA中的一个请求队列第一个可用的共享服务器进程从队列中选择请求,并附加相关会话的UGA共享服务器处理这个请求,把得到的输出放在响应队列中调度器一直监视着响应队列来得到结果,并把结果传回给客户应用。就客户而言,它分不清到底是通过专用 or 共享 服务器连接进行连接,看上去二者都一样,只是在数据库级二者的区别才会明显。


连接与会话

在一条连接上可以建立0个、一个或多个会话各个会话是单独而且独立的,即使它们共享同一条数据库物理连接也是如此。一个会话中的提交不会影响该连接上的任何其他会话。实际上,一条连接上的各个会话可以使用不同的用户身份

在Oracle中,连接只是客户进程和数据库实例之间的一条特殊线路,最常见的就是网络连接。这条连接可能连接到一个专用服务器进程,也可能连接到调度器。如前所述,连接上可以有0个或多个会话,这说明可以有连接而无相应的会话。另外,一个会话可以有连接也可以没有连接。使用高级Oracle Net特性(如连接池)时,客户可以删除一条物理连接,而会话依然保留(但是会话会空闲)。客户在这个会话上执行某个操作时,它会重新建立物理连接。

connection

客户进程Oracle实例一条物理路径(例如,客户与实例之间的一个网络连接)
连接可以在网络上建立,或者通过IPC机制建立。通常会在客户进程与一个专用服务器或一个调度器之间建立连接。


session

会话是实例中存在的一个逻辑实体。这就是你的会话状态(session state),

也就是表示特定会话的一组内存中的数据结构。客户进程要在服务器中的会话上执行SQL、提交事务和运行存储过程。多个独立的会话可以与一个连接相关联,这些会话甚至可以独立于连接存在。


这里使用了AUTOTRACE命令,并发现有两个会话。我们在一条连接上使用一个进程创建了两个会话。以下是其中的第一个会话:

scott@ORCL>select username, sid, serial#, server, paddr, status
  2  from v$session
  3  where username = USER
  4  /

USERNAME                              SID    SERIAL# SERVER    PADDR                STATUS
------------------------------ ---------- ---------- --------- ----------------    --------
SCOTT                                  67        434 DEDICATED 000007FF634DF010    ACTIVE
这说明现在有一个会话:这是一个与单一专用服务器连接的会话。以上PADDR列是这个专用服务器进程的地址


下面,只需打开AUTOTRACE来查看SQL*Plus中所执行语句的统计结果:

scott@ORCL>set autotrace on statistics
scott@ORCL>select username, sid, serial#, server, paddr, status
  2  from v$session
  3  where username = USER
  4  /

USERNAME                              SID    SERIAL# SERVER    PADDR                STATUS
------------------------------ ---------- ---------- --------- ----------------    --------
SCOTT                                  63        535 DEDICATED 000007FF634DF010    INACTIVE
SCOTT                                  67        434 DEDICATED 000007FF634DF010    ACTIVE


统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          0  consistent gets
          0  physical reads
          0  redo size
        992  bytes sent via SQL*Net to client
        519  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed

这样一来,我们就有了两个会话,但是这两个会话都使用同一个专用服务器进程,从它们都有同样的PADDR值就能看出这一点。从操作系统也可以得到确认,因为没有创建新的进程,这两个会话只使用了一个进程(一条连接)。需要注意,其中一个会话(原来的会话)是ACTIVE(活动的),它正在运行查询来显示这个信息。那个INACTIVE(不活动的)会话是 AUTOTRACE 会话,它的任务是“监视”我们的实际会话,并报告它做了什么。

在SQL*Plus 中启用AUTOTRACE时,如果执行DML操作(INSERT、UPDATE、DELETE、SELECT和MERGE),SQL*Plus会完成以下动作:
(1) 如果还不存在辅助会话,它会使用当前连接创建一个新会话。
(2) 要求这个新会话查询V$SESSTAT视图来记住实际会话(即运行DML的会话)的初始统计值。
(3) 在原会话中运行DML操作。

(4) DML语句执行结束后,SQL*Plus会请求另外那个会话(即“监视”会话)再次查询V$SESSTAT,并生成前面所示的报告,显示出原会话(执行DML的会话)的统计结果之差。

如果关闭AUTOTRACE,SQL*Plus会终止这个额外的会话,在V$SESSION中将无法看到这个会话。

SQL*Plus之所以会另外创建一个会话来执行监视,原因:如果使用同一个会话来监视内存使用,那执行监视本身也要使用内存,就会对统计结果造成影响(导致对统计结果的修改)。


到目前为止,我们已经看到一条连接可以有一个或两个会话。现在,我们想使用SQL*Plus来查看一条没有任何会话的连接。在上例所用的同一个SQL*Plus窗口中,只需键入DISCONNECT

scott@ORCL>disconnect
从 Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options 断
开
从技术上讲,这个命令应该叫DESTROY_ALL_SESSIONS更合适,而不是DISCONNECT,因为我们并没有真正物理地断开连接。
在SQL*Plus中要真正地断开连接,应该执行“exit”命令,必须退出才能完全撤销连接。


我们已经关闭了所有会话。如果使用另一个用户账户system打开另一个会话,并查询。可以看到,之前账户scott下没有会话,但是仍有一个进程,相应地有一条物理连接(使用前面的ADDR值):

system@ORCL>select * from v$session where username = 'scott@ORCL';
未选定行

system@ORCL>select username, program
  2  from v$process
  3  where addr = hextoraw('000007FF634DF010');

USERNAME        PROGRAM
--------------- ----------------------------------------------------------------
SYSTEM          ORACLE.EXE (SHAD)

所以,这就有了一条没有相关会话的“连接”。可以使用SQL*Plus的CONNECT命令(这个命令的名字也起得不恰当),在这个现有的进程中创建一个新会话(CONNECT命令叫CREATE_SESSION更合适):

scott@ORCL>conn scott/123456
已连接。
scott@ORCL>select username, sid, serial#, server, paddr, status
  2  from v$session
  3  where username = USER
  4  /

USERNAME                              SID    SERIAL# SERVER    PADDR               STATUS
------------------------------ ---------- ---------- --------- ----------------    -------
SCOTT                                  67        470 DEDICATED 000007FF634DF010    ACTIVE

可以注意到,PADDR还是一样的,所以我们还是在使用同一条物理连接,但是(可能)有一个不同的SID,也许还会分配同样的SID,这取决于在我们注销时是否有别人登录,以及我们原来的SID是否可用。


到此为止,这些测试都是用一条专用服务器连接执行的,所以PADDR正是专用服务器进程的进程地址。

------------------------------------------------------------------------共享服务器

共享服务器模式设置 详见 https://blog.csdn.net/A0001AA/article/details/79915439

下面使用共享服务器登录,并在这个会话中查询:

sys@ORCL>select username, sid, serial#, server, paddr, status from v$session where username = USER ;

USERNAME                    SID    SERIAL# SERVER    PADDR            STATUS
-------------------- ---------- ---------- --------- ---------------- --------
SYS                           9         87 SHARED    000007FF634DDFA0 ACTIVE
一条连接(从客户到数据库实例的一条物理路径)上可以建立0个、1个或多个会话。我们看到了这样一个用例,其中使用了SQL*Plus的AUTOTRACE工具。还有许多其他的工具也利用了这一点。例如,Oracle Forms就使用一条连接上的多个会话来实现其调度功能。Oracle 的n层代理认证特性可用于提供从浏览器到数据库的端到端用户鉴别,这个特性也大量使用了有多个会话的单连接概念,但是每个会话中可能会使用一个不同的用户账户。随着时间的推移,会话可能会使用多个进程,特别是在共享服务器环境中这种情况更常见。另外,如果使用Oracle Net的连接池,会话可能根本不与任何进程关联;连接空闲一段时间后,客户会将其删除,然后再根据检测活动(是否需要连接)透明地重建连接。


连接和会话之间有一种多对多的关系。不过,最常见的是专用服务器与单一会话之间的一对一关系.

------------------------------------------------------------------------------专用 or 共享服务器

1. 什么时候使用专用服务器
客户连接与服务器进程之间存在一种一对一的映射。对于目前所有基于SQL的应用来说,这是应用连接Oracle数据库的最常用的方法。设置专用服务器最简单,而且采用这种方法建立连接也最容易,基本上不需要什么配置。
因为存在一对一的映射,所以不必担心长时间运行的事务会阻塞其他事务。其他事务只通过其自己的专用进程来处理。因此,在非OLTP环境中,也就是可能有长时间运行事务的情况下,应该只考虑使用这种模式。专用服务器是Oracle的推荐配置,它能很好地扩缩。只要服务器有足够的硬件(CPU和RAM)来应对系统所需的专用服务器进程个数,专用服务器甚至可以用于数千条并发连接。

某些操作必须在专用服务器模式下执行,如数据库启动和关闭,所以每个数据库中可能同时有专用服务器和共享服务器,也可能只设置一个专用服务器。


2. 什么时候使用共享服务器

多个客户对应一个共享服务器。使用共享资源时,不要太长时间独占这个资源要确保事务的持续时间尽量短事务可以频繁地执行,但必须在短时间内执行完(这正是OLTP系统的特点)。如果事务持续时间很长,看上去整个系统都会慢下来,因为共享资源被少数进程独占着。使用共享服务器时,可能还会人工死锁(artificial deadlock)。


你有5个共享服务器,并建立了100个用户会话。现在,一个时间点上最多可以有5个用户会话是活动的。假设其中一个用户会话更新了某一行,但没有提交。正当这个用户呆坐在那里对是否修改还有些迟疑时,可能又有另外5个用户会话力图锁住这一行。当然,这5个会话会被阻塞,只能耐心地等待这一行可用。现在,原来的用户会话(它持有这一行的锁)试图提交事务,相应地释放行上的锁。这个用户会话发现所有共享服务器都已经被那5个 等待的会话所垄断。这就出现了一个人工死锁的情况:锁的持有者永远也拿不到共享服务器来完成提交,除非某个等待的会话放弃其共享服务器但是,除非等待的 会话所等待的是一个有超时时间的锁,否则它们绝对不会放弃其共享服务器(除非让管理员通过一个专用服务器“杀死”(撤销)等待的会话来摆脱这种 困境)。

共享服务器只适用于OLTP系统,这种系统 事务短而且频繁。在一个OLTP系统中,事务以毫秒为单位执行,任何事务的执行都会在1秒以内的片刻时间内完成。共享服务器对数据仓库很不适用,因为在数据仓库中,可能会执行耗时1分钟、2分钟、5分钟甚至更长时间的查询。如果你的系统中90%都是OLTP,只有10%“不那么OLTP”,那么可以在同一个实例上适当地混合使用专用服务器和共享服务器。采用这种方式,可以大大减少机器上针对OLTP用户的服务器进程个数,并使得“不那么OLTP”的用户不会独占共享服务器。另外,DBA可以使用内置的资源管理器(Resource Manager)进一步控制资源利用率。

当然,使用共享服务器还有一个很重要的原因,许多高级连接特性都要求使用共享服务器。如果你想使用Oracle Net连接池 或 数据库之间使用数据库链接集合(database link concentration),必须对这些连接使用共享服务器。

共享服务器的潜在好处

1.减少操作系统进程/线程数

2.刻意地限制并发度

3.减少系统所需的内存

猜你喜欢

转载自blog.csdn.net/a0001aa/article/details/79932989