很多企业在招聘DBA的时候,首先问的问题就是:请叙述一下Oracle的体系架构。因为这个体系架构是Oracle最基本的组成,如果这个最近都理解不了,想深入Oracle会很难。尤其是深入优化的时候。
因为本人也是个“半吊子”兼职DBA,所有的都是自学,因为自学容易走弯路,哪里不对的地方还希望各位大牛批评指教!
首先放个Oracle体系架构图(版本为11GR2)
Oracle是由一个个实例组成,对外提供数据支持服务。
Oracle数据库启动后,首先在内存中划分一片空间,并启动一些进程,这些内存和进程组成了数据库的实例,然后实例会读取硬盘上的物理文件(数据文件、控制文件、日志文件等),并缓存到高速缓存中,方便进程进行读写。
简单来说实例主要由如下够成:
进程结构、内存结构和物理文件
User Process(用户进程)
每当客户端连接Oracle或者发送1个SQL语句时会形成User Process,同时也会形成一个Session;
Server Process(服务进程)
收到Session后,Oracle会在服务器创建一个Server Process用来处理这条Session,有几个Session就会对应有几个Server Process(一对一)或者一对多(MTS共享模式下)
2.1 Program Globa Area(程序全局区,简称PGA)
Oracle会在服务器内存中对每一条Server Process划分一定的内存空间,这个内存空间叫做Program Globa Area,程序全局区,简称PGA;
PGA是一个进程专用内存(私有进程),在系统中其他进程绝对不允许访问的。
PGA主要由是Stack Space(堆栈区)和User Globa Area(UGA 用户全局区)组成
UGA主要作用是保存用户会话信息,游标开启状态和排序区组成,其中排序区需要DBA关注一下,合理的排序优化能提高语句执行速度;
UGA在专用服务模式下服务进程和用户进程为一对一,即每一个会话对应一个UGA,存在PGA中
UGA在共享服务模式下进程为一对多,即多个会话对应一个UGA,存在SGA中;
2.12 System Globa area(系统全局区,SGA)
Oracle在实例启动时,会划分一定的共享内存组成SGA。一个SGA只服务于一个实例,当一台服务器运行多个实例时,虽然它们都来自己于OS的共享内存,但实例之间不能互相访问对方的SGA
SGA主要由Shared Pool(共享池)、Database Buffer Cache(数据高速缓冲区)、Redo Buffer cache(重做日志缓冲区)、Large Pool(大池)、JAVA Pool(JAVA池)、Stream Pool(流池)、Sort Extent(排序扩展池)、Flash Buffer Cache(闪存缓冲区)组成。
1)、 Shared Pool(共享池)
Shared Pool(共享池)由是库缓存(Library Cahce)、数据字典缓存(Data Dictionary Cache)和Result Cache (结果集缓存)组成。
https://blog.csdn.net/hongkaihua1987/article/details/51686030
Shared作用是将用户提交来的SQL语句或者结果都缓存Shared Pool在中,每当有一条新的SQL语句需要执行时,都需要在Shared Pool(共享池)中查看是否有执行过的SQL语句,如果有则拿来返回给用户,这样可以减少解析,节省服务器资源(软解析)。如果没有找到相同的SQL语句,则必须重新生产执行计划,这样比较占用服务器过多的资源(硬解析)。
库缓存(Library Cahce)在共享缓存里最为重要。它包含了最近解析过的PS/SQL语句、游标和JAVA类程序,通常库缓存命中率需要保持在99%以上,如果过多的未命中容易造成硬解析造成服务器资源占用过多;
数据字典缓存(Data Dictionary Cache)用于存储经常使用的数据字典信息。比如(表的定义、用户名、口令、权限、数据库的结构等)。Oracle运行过程中经常访问该缓存以便解析SQL语句,确定操作的对象是否存在,是否具有权限等。
结果高速缓存包含 SQL 查询结果高速缓存和 PL/SQL 函数结果高速缓存。此高速缓存用于存储 SQL 查询或 PL/SQL 函数的结果,以加快其将来的执行速度。
2)、DataBase Buffer Cache (数据高速缓存区)
内容摘自如下博客,非常详细!
https://blog.csdn.net/hongkaihua1987/article/details/51686030
数据高速缓冲区(Database Buffer Cache):用于存放从数据文件读取的数据块,大小从2K、4K和8K组成(在创建库时自己划分,一般默认为8K参数为DB_BLOCK_SIZE)。它的作用是把硬盘上的数据文件缓存到内存中,方便快速读取,以免减少磁盘I/O。
数据高速缓存块由许多大小相等的缓存块组成,这些缓存块的大小和OS块大小相同。 这些缓存块分为3大类:
脏缓存块( Dirty buffers ):脏缓存块中保存的时被修改过的缓存块。即当一条SQL语句对某个缓存块中的数据进行修改后,该缓存块就被标记为脏缓存块。最后该脏缓存块达到一定条件后会被DBWn进程写入到硬盘的数据文件中,永久保留起来。
命中缓存块( Pinned buffers ):命中缓存块中保存的是最近正在被访问的缓存块。它始终被保留中数据高速缓存中,不会被写入数据文件。
空闲缓存块(Free buffers):该缓存块中没有数据,等待被写入数据。oracle从数据文件中读取数据后,寻找空闲缓存块,以便写入其中。
Oracle 通过 2 个列表(DIRTY、LRU,Least Recently Used,最近最少使用 )来管理缓存块
1、DIRTY 列表中保存已经被修改但还没有被写入到数据文件中的脏缓存块。
2、LRU列表中保存所有的缓存块(还没有被移动到DIRTY列表中的脏缓存块、空闲缓存块、命中缓存块)。当某个缓存块(经常用到的数据块)被访问后,该缓存块就被移动到LRU列表的头部,其他缓存块(不经常被用到的数据块)就向LRU列表的尾部移动。放在最尾部的缓存块就最先被移出LRU列表。
数据高速缓存的工作原理过程是:
A、ORACLE在将数据文件中的数据块复制到数据高速缓存中之前,先在数据高速缓存中找空闲缓存块,以便容纳该数据块。Oracle 将从LRU列表的尾部开始搜索,直到找到所需的空闲缓存块为止。
B、如果先搜索到的是脏缓存块,将该脏缓存块移动到DIRTY列表中,然后继续搜索。如果搜索到的是空闲缓存块,则将数据块写入,然后将该缓存块移动到DIRTY列表的头部。
C、如果能够搜索到足够的空闲缓存块,就将所有的数据块写入到对应的空闲缓存块中。则搜索写入过程结束。
D、如果没有搜索到足够的空闲缓存块,则ORACLE就先停止搜索,而是激活DBWn进程,开始将DIRTY列表中的脏缓存块写入到数据文件中。
E、已经被写入到数据文件中的脏缓存块将变成空闲缓存块,并被放入到LRU列表中。执行完成这个工作后,再重新开始搜索,直到找到足够的空闲缓存块为止。
这里可以看出,如果你的高速缓冲区很小的话,就会不停的写入数据,造成很大I/O开销。
块缓冲区可以配置1、2或3个缓冲池,默认只有一个
默认池(Default pool):所有数据默认都在这里缓存,除非你在建表的时候指定 Store(buffer_pool keep) or Store(buffer_pool recycle)。使用LRU算法管理。
保持池(Keep pool):缓存需要多次重用的数据,长期保存内存中,缺省值为0。
回收池(Recycle pool):用来缓存很少重用的数据,用完就释放,缺省值为0。
原来只有一个默认池,所有数据都在这里缓存。这样会产生一个问题:大量很少重用的数据会把需重用的数据“挤出”缓冲区,造成磁盘I/O增加,运行速度下降。后来分出了保持池和回收池根据是否经常重用来分别缓存数据。这三部分内存池需要手动确定大小,并且之间没有共享。例如:保持池中已经满了,而回收池中还有大量空闲内存,这时回收池的内存不会分配给保持池,这些池一般被视为一种非常精细的低级调优设备,只有所有其他调优手段大多用过之后才应考虑使用。
在9i之前,数据缓冲区的大小是由DB_BLOCK_BUFFER确定,之后的版本中,是由参数DB_CACHE_SIZE及DB_nK_CACHE_SIZE确定。不同的表空间可以使用不同的块大小,在创建表空间中加入参数BLOCKSIZE指定该表空间数据块的大小,如果指定的是2k,则对应的缓冲区大小为DB_2K_CACHE_SIZE参数的值,如果指定的是4k,则对应的缓冲区大小为DB_4K_CACHE_SIZE参数的值,以此类推。如果不指定BLOCKSIZE,则默认为参数DB_BLOCK_SIZE的值,对应的缓冲区大小是DB_CACHE_SIZE的值
3)、Redo Loger Buffer Cache (重做日志缓冲区)
记录数据更改并形成日志条目。当这块区域用光时,后台进程LGWR把日志条目写到磁盘上的联机日志文件中。它由初始化参数log_buffer决定大小。同样的道理下,日志缓冲区应该稍微大点,特别是有长时间运行的事务的时候,可以大量减少I/O。
数据写到重做日志文件之前在这里缓存,在以下情况中触发:
4、)Large Pool(大池)
大池由初始化参数LARGE_POOL_SIZE确定大小,可以使用ALTER SYSTEM语句来动态改变大池的大小,是可选项,DBA可以根据实际业务需要来决定是否在SGA区中创建大池。如果没有创建大池,则需要大量内存空间的操作将占用共享池的内存, 将对SHARED POOL造成一定的性能影响,而LARGE POOL是起着这种功能隔离作用的一块区域。
ORACLE 需要大量内存的操作有:
A、数据库备份和恢复,如RMAN某些情况下用于磁盘IO缓冲区
B、具有大量排序操作的SQL语句
C、并行化的数据库操作,存放进程间的消息缓冲区
D、共享服务器模式下UGA在大池中分配(如果设置了大池)
5)、JAVA Pool
用于支持在数据库中运行java代码,一般由java_pool_size控制
6)、Stream Pool (流池)
加强对流的支持,一般由stream_pool_size控制。流池(或者如果没有配置流池,则是共享池中至多10%的空间)会用于缓存流进程在数据库间移动/复制数据时使用的队列消息
放个自己画的逻辑图,缺少了五大进程,画布满了,智能画这么多了