Oracle中的各个进程要完成某个特定的任务或一组任务,每个进程都会分配内部内存(PGA内存)来完成它的任务。
Oracle实例主要有3类进程:
类似于后台进程,不过它们要代表后台进程或服务器进程完成一些额外的工作。
代表客户会话完成工作的进程。应用向数据库发送的SQL语句最后就要由这些进程接收并执行。
dedicated server连接
会在服务器上得到针对这个连接的一个专用进程。数据库连接与服务器上的一个进程之间存在一对一的映射。
shared server
多个会话可以共享一个服务器进程池,其中的进程由Oracle实例生成和管理。
你所连接的是一个数据库调度器(dispatcher),而不是特意为连接创建的一个专用服务器进程。
专用or共享 服务器进程的任务是一样的:要处理你提交的所有SQL。当你向数据库提交一个SELECT * FROM EMP查询时,会有一个Oracle专用/共享服务器进程解析这个查询,并把它放在共享池中(或者最好能发现这个查询已经在共享池中)。这个进程要提出查询计划,如果必要,还要执行这个查询计划,可能在缓冲区缓存中找到必要的数据,或者将数据从磁盘读入缓冲区缓存中。这些服务器进程是干重活的进程。在很多情况下,你都会发现这些进程占用的系统CPU时间最多,因为正是这些进程来执行排序、汇总、联结等等工作,几乎所有工作都是这些进程做的。
------------------------------------------------------------------------专用服务器
可以在同一台机器上运行客户和服务器,就能很清楚地看出这种父/子进程的创建
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
共享服务器连接强制要求必须使用Oracle Net,即使客户和服务器都在同一台机器上也不例外。如果不使用Oracle TNS监听器,就无法使用共享服务器。客户应用会连接到Oracle TNS监听器,并重定向或转交给一个调度器。调度器充当客户应用和共享服务器进程之间的“导管”。
在此可以看到,客户应用(其中链接了Oracle库)会与一个调度器进程物理连接。调度器只负责从客户应用接收入站请求,并把它们放入SGA中的一个请求队列。第一个可用的共享服务器进程从队列中选择请求,并附加相关会话的UGA。共享服务器处理这个请求,把得到的输出放在响应队列中。调度器一直监视着响应队列来得到结果,并把结果传回给客户应用。就客户而言,它分不清到底是通过专用 or 共享 服务器连接进行连接,看上去二者都一样,只是在数据库级二者的区别才会明显。
在一条连接上可以建立0个、一个或多个会话。各个会话是单独而且独立的,即使它们共享同一条数据库物理连接也是如此。一个会话中的提交不会影响该连接上的任何其他会话。实际上,一条连接上的各个会话可以使用不同的用户身份!
在Oracle中,连接只是客户进程和数据库实例之间的一条特殊线路,最常见的就是网络连接。这条连接可能连接到一个专用服务器进程,也可能连接到调度器。如前所述,连接上可以有0个或多个会话,这说明可以有连接而无相应的会话。另外,一个会话可以有连接也可以没有连接。使用高级Oracle Net特性(如连接池)时,客户可以删除一条物理连接,而会话依然保留(但是会话会空闲)。客户在这个会话上执行某个操作时,它会重新建立物理连接。
connection
从客户进程到Oracle实例的一条物理路径(例如,客户与实例之间的一个网络连接)
连接可以在网络上建立,或者通过IPC机制建立。通常会在客户进程与一个专用服务器或一个调度器之间建立连接。
会话是实例中存在的一个逻辑实体。这就是你的会话状态(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会完成以下动作:(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,因为我们并没有真正物理地断开连接。我们已经关闭了所有会话。如果使用另一个用户账户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.减少系统所需的内存