Oracle 网络
配置Oracle Net服务
Oracle Net和客户端-服务器范例
用户和数据库之间存在许多层。在Oracle环境中,用户不能直接访问数据库,其运行的进程也不能直接访问数据库。客户端-服务器体系结构保证了对数据的所有访问都受服务器控制。
用户与用户进程交互,而用户进程是用户在其本地终端上运行的软件。用户进程的目的都是提示用户输入能够被该进程用于生成SQL语句的信息,并将其发送到服务器进程。
服务器进程在数据库服务器上运行,并且执行从用户进程接收到的SQL语句。
Oracle Net提供了帮助启动服务器进程并代表用户进程执行代码的机制。遮也被称为建立一个会话。随后,Oracle Net负责维护这个会话:将SQL语句从用户进程传送至服务器进程,并将结果从服务器进程取回至用户进程。
建立会话
- 连接到本地实例:即使是连接本地计算机运行的实例,也会使用Oracle Net。所有Oracle会话都使用了网络协议来实现用户代码与服务器代码的分离,不过本地连接所使用的网络协议为IPC。这是唯一不需要数据库侦听器的连接类型。事实上,本地连接不必进程任何配置。此时,用户进程需要知道的信息仅仅是希望连接的实例。在本地计算机上可以运行若干实例。
- 名称解析:通过网络进行连接时,第一个阶段是发现实际希望连接的实例。这个阶段就是名称解析过程。如果连接语句包含连接字符串“@orcl112c”,那么Oracle Net必须理解“orcl112c”的含义。这个连接字符串的含义必须解析为下列几部分信息:希望使用的协议(假定为TCP)、运行数据库侦听器的IP地址、侦听器监视传入连接请求的端口以及希望连接的实例的名称(这个名称不需要与连接字符串相同)。还有一种情况:连接字符串没有包含IP地址,而是包含了一个主机名,这个主机名被DNS服务器进一步解析为IP地址。
- 启动服务器进程:在服务器上运行的数据库侦听器使用一种或多种协议在若干网络接口卡上的若干端口监视传入连接请求。接收到一个连接请求时,侦听器必须首先验证这个实例请求是否真的有效。如果这个连接请求有效,那么侦听器会启动一个为用户进程提供服务的新服务器进程。如果有1000个用户同时登陆指定的实例,那么会启动1000个服务器进程。在TCP环境中,一个侦听器所启动的每个专用服务器进程都会获得一个唯一的TCP端口号。操作系统的端口映射算法会在进程启动阶段指派端口号。侦听器将这个端口号传回用户进程(在某些操作系统中,为侦听器打开的套接字会被移至新的端口号),用户进程随后就可以与其服务器进程进行直接通信。此时,侦听器完成当前的工作,同时等待下一次连接请求。
创建数据库侦听器
侦听器在listener.ora文件中定义,这个文件的默认存储位置为ORACLE_HOME/network/admin目录。listener.ora文件至少必须声明一个侦听器的名称及其使用的协议与侦听地址。可以在一个文件中配置多个侦听器,不过这些侦听器必须具有不同的名称与地址。如果侦听器没有继续运行,那么不能启动任何新的服务器进程,但这不会影响已经建立的任何会话。
动态服务注册
为了针对实例启动会话,侦听器需要知道哪些实例当前运行在服务器上。每个数据库都提供了一个或多个服务。服务是一个逻辑名称,其会话可以通过实例来访问。数据库中的不同服务可以有不同的性质(例如容错性)。总是由一个以数据库命名的默认服务,其名称常常与实例相同,还常常与tnsnames.ora文件中定义的、在连接字符串中使用的Net服务别名相同。实例启动时,默认会使用端口1521在机器主机名解析的地址上查找一个侦听器。如果的确在改地址:端口上运行着一个侦听器,数据库就用该侦听器注册其服务名,这样侦听器就可以连接用户。数据库关闭时,就从侦听器中注销。这就是动态注册的过程。侦听器注册(LREG)后台进程用侦听器注册服务。在实例的生命周期中,LREG进程反复用侦听器重新注册。因此,如果实例停止后重启,下次LREG尝试注册时,数据库就会知道。
共享服务器
专用服务器体系结构的局限性:在专用服务器环境中,如果操作系统管理大量并行进程存在某些问题,并且这些问题在服务器内存不足时更加严重,那么性能可能退化。需要注意的是,这种情况与会话是否执行操作无关,即使会话空闲,操作系统仍然必须根据其时间分片算法在CPU中中断和载入这些会话,并且还可能从交换文件中将适当的PGA调页至主内存。无论借助于何种硬件升级方式,由于操作系统低效的上下文切换与分页管理,总是会存在一个性能开始退化的界点。Oracle提供了使用共享服务器体系结构的选项。共享服务器体系结构允许通过相对较少的共享服务器进程为大量的用户进程提供服务,从而显著减少了服务器的操作系统必须管理的进程数。一个额外的好处是,所使用的内存也会减少。
共享服务器体系结构:共享服务器完全在服务器段实现,用户进程和应用软件无法得知发生了任何变化。用户进程会发出一个连接字符串,该连接字符串必须解析为某个侦听器的地址以及某个服务(或实例)的名称。作为回应,用户进程会接收到某个服务器端进程的地址,并且认定这个服务器端进程为共享服务器。随后,用户进程继续发送SQL语句并接受返回的结果集。就用户进程而言,什么都没有发生变化。但服务器端的情况大不相同。共享服务器咋服务器段配置,而通过在TNS连接字符串中指定SERVER=DEDICATED或SERVER=SHARED,客户端可以要求使用共享服务器或专用服务器。 共享服务器由作为指定实例一部分的其他进程实现。这些进程是在实例启动阶段启动的后台进程。此时存在两种新的进程类型:调度进程与共享服务器进程。SGA内还存在一些特殊队列存储结构,数据库侦听器为共享服务器更改其行为。在启动某个用于共享服务器的实例时,除了启动常见的后台进程之外,还会启动一个或多个调度进程。与其他TCP进程一样,这些调度进程在操作系统的端口映射程序所分配的一个单一TCP端口上运行,并与侦听器相联系并向其进行注册。此时还会启动一个或多个共享服务器进程。这些进程会接收、分析和执行SQL语句以及产生结果集,但他们并不是直接从一个用户进程接收SQL语句,而是从一个队列中读取这些语句,这个队列填充了来自任意数目用户进程的SQL语句。同样地,共享服务器并不直接将结果集取回至一个用户进程,而是将结果集排入一个响应队列。某个用户进程联系侦听器时,侦听器的动作是传回某个调度程序的地址,而不是启动一个服务器进程并将其与这个用户进程连接在一起。如果只存在一个调度进程,那么侦听器会连接这个调度进程与所有用户进程。如果存在多个调度进程,那么侦听器会在这些调度进程之间实现对引入连接请求的负载均衡,不过最终的结果是许多用户进程分别连接每个调度进程。每个用户进程都认为自己连接了一个专用服务器进程,然而事实并非如此,此进程与其他很多用户进程共享了一个调度进程。在网络层上,许多用户进程会通过这个调度进程所使用的一个端口多路复用连接。会话与调度进程的连接在会话期间持久存在,而与侦听器的连接时短暂的。用户进程生成一条SQL语句时,会将这条语句发送至调度进程。调度进程将其接受到的所有语句放入一个队列。因为所有调度进程共享这个队列,所以该队列称为“公共”队列。无论用户进程连接哪一个调度进程 ,所有语句最终都会放入这个公共队列。所有共享服务器进程都监视公共队列。在一条语句到达公共队列时,第一个可用的共享服务器就会获得这条语句。随后的语句执行过程会经过通常的分析-绑定-执行周期,不过在进入取出阶段时,因为用户进程与这个共享服务器之间不存在连接,所以共享服务器无法将结果集取回至用户进程。此时,共享服务器只能将结果集放入最初接收到指定作业的调度进程专用的响应队列。每个调度进程都会监视自己的响应队列,一旦在响应队列中放入了结果集,相应的调度进程就会获得结果集并将其返回至先前发出SQL语句的用户进程。所有调度进程共享一个公共的输入队列,但是每个调度进程都具有自己的响应队列。在普通的专用服务器连接中,因为PGA(PGA与一个管理会话的服务器进程相联系)存储与会话状态相关的信息,所以专用服务器知道需要COMMIT的数据以及需要释放的锁定,因此不存在维护会话状态的问题。用于某个专用服务器会话的PGA存储了这个会话的会话数据、游标状态、排序空间以及堆栈空间。但是,在共享服务器环境中,这几条语句可能在公共队列中被不同的共享服务器进程所获取,而这些共享服务器进程并不清楚当前事务的状态。为了解决这个问题,共享服务器会话在SGA中(而不是在PGA中)存储大量的会话数据。只要某个共享服务器从公共队列中获取一个作业,那么就会进入SGA并连接适当的内存块,从而找出会话的状态。SGA中用于每个共享服务器会话的内存称为用户全局区(UGA)除了会话的堆栈空间之外,UGA还包含了PGA中的所有存储结构,由此节省了内存。在于众多不同的PGA中管理内存相比,Oracle能够在共享池中更有效地管理内存。
实现共享服务器时,下面的会话内存结构存储在SGA中:
- 排序区域
- 散列区域
- 位图创建区域
- 位图合并区域
- 游标状态
- 用户会话数据
下面的会话内存结构在SGA的外部,这些可以看作调用过程中的运行时信息;
- 堆栈空间
- 局部变量
用于存储UGA的SGA部分是大池。可以使用large_pool_size参数手动配置,也可以执行自动管理。无法使用共享服务器会话来启动或关闭实例。这是因为需要支持共享服务器的进程(调度程序和共享服务器进程)本身都是实例的一部分。