5.1 用于与Oracle 数据库服务器建立连接
数据库连接方式: 专用连接(Dedicated)和共享连接(Shared Server , MTS)
专用连接: 用户在客户端启动一个ap,于是在客户端本地启动了一个用户进程。 与Oracle服务器成功建立连接
以后,就会在数据库服务器端生成一个对应的服务器进程, 该服务器进程作为用户进程的代理进程,也叫影子进程,代
替客户端用户进程去执行各种命令并将结果返回。 用户进程是不能直接访问数据库的。 这种模式下,用户进程和服务器
进程是一一对应的, 用户进程终止,对应的服务器进程也随之终止。
共享连接: 在这种模式下,DBA可以定义服务器进程的个数。 在启动数据库时, Oracle会预先在实例中建立指定个数
的服务器进程, 这时用户进程不再与服务器产生一对一的关系, 而是一对多的关系, 一个用户进程可以对应多个服务器
进程, 多个服务器进程都可以处理同一个用户发出的不同命令。 比较少用 。
当用户成功建立连接后, 会在服务器端生成对应的服务器进程, 同时创建一个session, 所谓session(会话),就是
一段内存空间, 这个空间记录了用户采用什么应用程序连接到数据库,客户端机器名称,以及哪个用户名登录 等信息。
容易混淆的概念: connection & session
连接: 物理概念,是客户端到服务器端的通信通道,有本机,C/S,B/S三种结构。
5.2 深入shared pool
用户端发出SQL请求,解析SQL语句,执行SQL语句
解析SQL语句: 检查数据对象存在性,用户操作权限, 产生Oracle内部的执行计划,指导SQL的执行过程, 解析是一个非常
消耗内存的过程,如果每次新的SQL都需要从头到尾解析一遍的话,效率会非常低 。
Oracle将SQL语句提炼成两个部分, 一部分是SQL中的关键词,表名及列名等 ; 另一个部分是SQL语句的动态部分,字面值value部分。
在处理的SQL语句中, 静态部分可以认为是有限的, 但是动态部分由于字面值的变化而变得无限。 动态部分对解析的影响相对于静态部分对
解析的影响是微乎其微, 对于相同静态部分的SQL语句来说, 不同的动态部分所产生的解析结果(执行计划)基本都是一样的(除非表里的数据
分布极其不均匀)
0racle将用户发出的SQL语句缓存在内存中,每次处理新的一条SQL时,都会先在内存中查看是否有相同的SQL语句,如果相同则减少最重要的
解析工作(也就是生成执行计划),可以节省大量的CPU资源,反之如果没有找到,必须从头到尾进行完整的解析,这部分存放SQL语句的内存部分
就叫做共享池(shared pool).
共享池中存放的还有: SQL,PL/SQL代码,执行计划,PL/SQL程序的机器码,管理shared pool的内存结构,控制信息等 。
绑定变量(bind variable): 也就是用一个变量来代替SQL中的字面值,那么Oracle在shared pool中查找到相同的SQL语句的
概率就很大 。 eg: select * from t1 from c1=:v1 ; v1是变量,具体执行SQL时,才将字面值传入。 因为静态部分是有限
的, 同样静态部分的SQL因为绑定变量的使用变成了有限的一条SQL语句, 动态部分也变成有限(1条),从而很容易缓存在内存中。 不使用
绑定变量导致SQL因为动态部分(字面值)的变化而变成无限,很难被缓存到内存中。 只有使用了bind variable 才真正遵循了Oracle
引入shared pool 的根本思路,才能更有效的利用shared pool .
10g以前由于参数shared_pool_size决定共享池大小,10g或以后设置sga_target 来自动决定shared pool的大小。
Shared pool结构: 库缓存(library cache)和数据字典缓存(dictionary cache) .
Library Cache: 存放最近执行的SQL语句,存储过程,函数,解析树以及执行计划 等
Dictionary Cache : 存放SQL需要使用的数据字典信息,包括表,列,权限等,以数据行形式存在,而不是数据块,也叫做row cache.
对于数据字典信息,Oracle倾向于一直存在在shared pool里面,不会将他们交换出内存。可以不用特别关注。
Library Cache是shared pool最重要的部分, 也是进进出出最活跃的部分 。
5.2.1 shared pool的内存结构
物理层面: shared pool由许多内存块组成,这些内存块通常称为chunk, 是shared pool中内存分配的最小单位,一个chunk中
所有的内存都是连续的 。
chunk可用的时候,它既不属于library cache, 也不属于dictionary cache,如果该chunk被用于存放SQL相关的数据时, 就
属于library cache, 同样如果该chunk被用于存放数据字典信息时,该chunk属于dictionary cache .
这些Chunk的分类: free/recr/freeabl/perm
free: 这种chunk不包含有效对象,可以不受限制的被分配。
recr: recreatable , 这种类型的chunk中包含的对象可以在需要的时候被临时移走,并且在需要的时候重新创建,比如对于很多共享
SQL语句的chunk就是recreatable的。
freeabl: 这种chunk包含的对象都是曾经被session使用过的,并且随后会被完全或部分释放,这种类型的chunk不能临时从内存移走,
因为他们是在处理过程中间产生的,如果移走的话就无法被重建。
perm : permanent, 这种类型的chunk包含永久的对象,大型的permanent类型的chunk也可能含有可用空间,这部分可用空间可以
在需要的时候释放回shared pool里 。
在shared pool里,可用的chunk(free类型)会被串起来成为可用链表(free list),或者也可以叫做bucket.
小结:
连续的内存(Mem) --> 组成chunk --> 可用(free)的chunk --> 串联起来 --> 成为可用链表(free list),或称为bucket
当某个进程需要shared pool中的一个chunk时,该进程首先到符合所需空间大小的bucket上去扫描,以找到一个尺寸最合适的chunk,扫描
持续到bucket的最末端, 直到找到完全符合尺寸的chunk为止。 如果找到的尺寸比需要的尺寸要大, 这该chunk会被拆分成两个chunk,一个
chunk被用来存放数据, 而另外一个则成为free类型的chunk, 并被挂到当前的该bucket上 。
如果该bucket 上不含有任何需要大小的尺寸的chunk, 那么就从下一个非空的bucket上获得一个最小的chunk, 如果在剩下的所有bucket
上都找不到合适可用的chunk, 则需要扫描已经使用的 recreatable 类型的chunk链表(free list), 从该链表上释放一部分的chunk,
注意, 只有recreatable类型的 chunk 才是可以被临时移出内存的。
当某个chunk正在被使用时,该chunk不能被移出内存, 比如某个SQL正在执行,这个SQL语句所使用的chunk是不能被移出内存的,该SQL所使用的
表,索引等对象所占用的chunk也是不能被移出内存的。
当shared pool中无法找到足够大小的连续内存(注: 连续内存才能组成chunk),就会报出ora-04031的错误信息,可能是内存碎片 。
事实上,在Oracle报出ora-04031之前, 已经释放了不少recreatable类型的chunk了,会产生不少可用内存,但没有一个chunk能够以连续
的物理内存提供所需的内存空间。
也就是说, 当我们在共享池中试图分配大片的连续内存失败的时候,Oracle首先清除池中当前没使用的所有对象,使空闲内存块合并。如果仍然没有足够
大单个的大块内存满足请求,就会产生ORA-04031 错误。
Shared pool latch :
latch就是轻量级的锁,底层对象,用来保护对某个内存块的并发访问。 每个进程向内存块中写数据之前必须获得latch,
写完以后释放latch, latch的获取是串行话的, 一次只能一个进程能获得latch, 获取和释放都很快 。
从逻辑层面来看,shared pool由 library cache和dictionary cache组成 。
组件关系: 当SQL语句进入library cache时, Oracle会先到dictionary cache中去找与SQL中表有关的数据字典信息,比如表名,表的列,用户权限等信息,如果dictionary cache中没有这些信息,则会将system表空间里的数据字典信息调入buffer cache内存中,读取内存数据块里的数据字典内容, 然后将这些读取出来的数据字典内容按照行的形式放入dictionary cache里,从而在dictionary cache中构造出dc_tables,dc_segments,dc_columns 之类的对象。 然后再从dictionary cache的行数据中取出有关的列信息放入library cache中。
对于非常大的对象,可以让Oracle为他们单独从保留区域里分配空间,而不是从chunk链表中来分配空间,通过shared_pool_reserved_size
设置,一般是shared_pool_size大小的 5%, 保留区域的可用chunk不会挂在bucket上 。
5.2.2 Library cache
library cache用于存放用户发出的SQL语句,解析树,执行计划,PL/SQL程序块,以及他们转换后能被Oracle执行的代码 等。
为了对这些内存结构进行管理, library cache还存放了很多控制结构,包括lock,pin,dependency table 等。 library
cache 也存放了很多数据库对象的信息,包括表,索引等, 都是从数据字典缓存中取得的, 如果用户对对象信息进行了修改,比如加了一个字段,那么这些修改会返回到dictionary cache中 。
在Library cache中存放的所有信息单元都叫做对象,分为两类: 存储对象和过渡对象。 存储对象包括表,视图,索引,包等; 过渡对象即用户发出的sql语句或pl/sql匿名程序块 。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-663460/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/35489/viewspace-663460/
本文详细介绍了Oracle数据库的连接方式,包括专用连接和共享连接,并深入探讨了SharedPool的工作原理及其内部结构,如Library Cache和Data Dictionary Cache,帮助读者理解如何优化Oracle数据库性能。
252

被折叠的 条评论
为什么被折叠?



