首页 > 代码库 > oracle 初探内存结构
oracle 初探内存结构
数据库的存储机构 分为 逻辑存储结构 和 物理存储结构
逻辑存储结构: 数据库、表空间、段、区、块
物理存储结构: 数据库、控制文件、数据文件、初始化参数文件、OS块等.
一个区只能在一个数据文件中,一个段中的各个区可以分别在多个数据文件中。组成区的块是连续的。
SGA (SYSTEM Global Area )系统全局区
【buffer cache】数据高速缓存是(由初始化参数DB_CACHE_SIZE指定大小。工作原理和过程是 LRU(最近最少使用 Least Recently Used ))
保持(keep)缓冲池(长期保存在内存中,直到数据库被关闭为止。BUFFER_POOL_KEEP指定大小)
再生(recycle)缓冲池(数据一旦用毕后就被换出内存中。BUFFER_POOL_RECYCLE指定大小)
默认(default)缓冲池 (数据使用LRU调度算法来换出。DB_CACHE_SIZE - BUFFER_POOL_REEP - BUFFER_POOL_RECYCLE 即为该缓冲池的大小)
【redo log buffer】重做日志高速缓存
【large pool】大池
【java pool】JAVA池
【streams pool】流池
【shared pool】共享池
数据字典缓冲区(Dictionary Cache)
其他控制结构区
库缓冲区( Library Cache)
共享SQL区
私有SQL区(当是共享服务器模式时)
排序区(当是共享服务器模式时)
锁与其他控制结构区
PL/SQL过程与包区
PGA 程序全局区
会话区
堆栈区
游标状态区
排序区(当是专用服务器模式时)
私有SQL区(当是专用服务器模式时)
数据高速缓存块由许多大小相等的缓存块组成,这些缓存块的大小和OS块大小相同。 这些缓存块分为 3 大类、
脏缓存块( Dirty buffers ):
脏缓存块中保存的时被修改过的缓存块。即当一条SQL语句对某个缓存块中的数据进行修改后,该缓存块就被标记为藏缓存块。
最后该脏缓存块被DBWn进程写入到硬盘的数据文件中,永久保留起来。
命中缓存块( Pinned buffers ):
命中缓存块中保存的是最近正在被访问的缓存块。它始终被保留中数据高速缓存中,不会被写入数据文件。
空闲缓存块(Free buffers):
该缓存块中没有数据,等待被写入数据。oracle从数据文件中读取数据后,寻找空闲缓存块,以便写入其中。
Oracle 通过 2 个列表(DIRTY、LRU)来管理缓存块
DIRTY 列表中保存已经被修改但还没有被写入到数据文件中的脏缓存块。
LRU 列表中保存所有的缓存块(还没有被移动到DIRTY列表中的脏缓存块、空闲缓存块、命中缓存块)。
当某个缓存块被访问后,该缓存块就被移动到LRU列表的头部,其他缓存块就向LRU列表的尾部移动。
放在最尾部的缓存块就最先被移出LRU列表。
数据高速缓存的工作原理过程是:
A、ORACLE在将数据文件中的数据块复制到数据高速缓存中之前,先在数据高速缓存中找空闲缓存块,以便容纳该数据块。Oracle 将从LRU列表的尾部开始搜索,直到找到所需的空闲缓存块为止。
B、如果先搜索到的是脏缓存块,将将该脏缓存块移动到DIRTY列表中,然后继续搜索。如果搜索到的是空闲缓存块,则将数据块写入,然后将该缓存块移动到DIRTY列表的头部。
C、如果能够搜索到足够的空闲缓存块,就将所有的数据块写入到对应的空闲缓存块中。则搜索写入过程结束。
D、如果没有搜索到足够的空闲缓存块,则ORACLE就先停止搜索,而是激活DBWn进程,开始将DIRTY列表中的脏缓存块写入到数据文件中。
E、已经被写入到数据文件中的脏缓存块将变成空闲缓存块,并被放入到LRU列表中。执行完成这个工作后,再重新开始搜索,直到找到足够的空闲缓存块为止。
重做日志高速缓存 (其大小由初始化参数LOG_BUFFER指定,可以在运行期间修改该参数)
为了加快访问和速度和工作效率,重做记录并不直接写入重做日志文件中,而是首先从数据高速缓存写入重做日志高速缓存。当重做日志高速缓存中的重做记录
达到一定数量或某个时间点时,再由LGWR进程分批写入重做日志文件中(即ORACLE 总是先日志后文件或先内存后磁盘)。由于重做日志文件是循环使用的。
所以当重做日志文件切换时,还会由ARCn(如果启用了归档日志模式)进程将即将要被覆盖的重做日志文件中的数据写入到归档日志文件中,作为备份。
SHOW PARAMETER LOG_BUFFER; ------查询重做日志缓存的大小
SELECT * FROM V$SYSSTAT; ------查询用户进程等待重做日志缓存的次数。
共享池 (由初始化参数SHARED_POOL_SIZE指定,默认80MB,可以在运行期间手动修改该参数)
共享池中保存了最近执行的SQL语句、PL/SQL过程与包、数据字典信息、锁、以及其他控制结构的信息。
共享池是对SQL语句、PL/SQL程序进行语法分析、编译、执行的内存区。
数据字典缓存
用于存储经常使用的数据字典信息。比如(表的定义、用户名、口令、权限、数据库的结构等)。
Oracle运行过程中经常访问该缓存以便解析SQL语句,确定操作的对象是否存在,是否具有权限等。如果不在数据字典缓存中,服务器进程就从保存数据字典信息的据文件中将其读入到数据字典缓存中。数据字典缓存中保存的是一条一条的记录(就像是内存中的数据库),而其他缓存区中保存的是数据块信息。
库缓存 (大小与OPEN_CURSOR初始化参数相关,ORACLE中每条查询语句都需要打开一个游标,OPEN_CURSOR默认值为300)
库缓存的目的就是保存最近解析过的SQL语句、PL/SQL过程和包。这样一来,Oracle在执行一条SQL语句、一段PL/SQL 过程和包之前,首先在“库缓存”中搜索,如果查到们已经解析过了,就利用“库缓存”中解析结果和执行计划来执行,而不必重新对它们进行解析,显著提高执行速度和工作效率。
ORACLE将每一条SQL语句分解为可共享、不可共享的两部分。
共享SQL区
存储的是最近执行的SQL语句、解析后的语法树和优化后的执行计划。这样以后执行相同的SQL语句就直接利用在共享SQL区中的缓存信息,不必重复语法解析了。
Oracle在执行一条新的SQL语句时,会为它在共享SQL区中分配空间,分配的大小取决于SQL语句的复杂度。如果共享SQL区中没有空闲空间,就利用LRU算法,释放占用的空间。
私用SQL区
存储的是在执行SQL语句时与每个会话或用户相关的私有信息。其他会话即使执行相同的SQL语句也不会使用这些信息。比如(绑定变量、环境和会话参数)。
PL/SQL过程和包区
工作原理同共享SQL区。但是嵌套在PL/SQL过程和包中的SQL语句、解析后的语法树和优化后的执行计划被存储中共享SQL区中。
锁与其他控制结构
存储ORACLE例程内部操作所需的信息。比如(各种锁、闩、寄存器值)。
大池 (由初始化参数LARGE_POOL_SIZE确定大小,可以使用ALTER SYSTEM语句来动态改变大池的大小)
大池是可选项的,DBA可以根据实际业务需要来决定是否在SGA区中创建大池。如果没有创建大池,则需要大量内存空间的操作将占用共享池的内存。
ORACLE 需要大力内存的操作有:
A、数据库备份和恢复。
B、具有大量排序操作的SQL语句。
C、并行化的数据库操作。
JAVA池 (由初始化参数JAVA_POOL_SIZE确定大小,控制在30-50MB比较合适)
用户存放JAVA代码、JAVA语句的语法分析表、JAVA语句的执行方案和进行JAVA程序开发。
可以使用 ALTER SYSTEM SET JAVA_POOL_SIZE=0M SCOPE=SPFILE;语句在服务器初始化参数文件中修改该参数。必须重新启动数据库服务器才能使其生效。
PGA (Program Global Area )程序全局区
PGA区是用户进程连接到数据库并创建一个对应的会话时,由ORACLE 为服务器进程分配的专门用于当前用户会话的内存区。该内存区是非共享、不可写的。
只有服务器进程本身才可以访问它本身的PGA区。而PGA是所有服务器进程都可以共享的、可写的内存区。PGA的大小由操作系统决定,其内存取决于专用
服务器还是共享服务器模式。会话结束时,ORACLE会自动释放PGA所占用的内存区。
排序区
用于存放排序操作产生的临时数据,排序区是影响PGA区大小的主要因素。排序区的大小由初始化参数SORT_AREA_SIZE 决定。而SORT_AREA_RETAINED_SIZE
参数是决定排序区操作结束后排序区保留的内存大小。从排序区释放的内存仍然属于服务器进程,并不返回给操作系统。
ORACLE利用内存比磁盘快的事实,将准备排序的数据先临时存储到排序区中,并在排序区中执行排序操作,然后将排序结果返回给用户。
排序原理:如果要排序的数据在排序区中放不下,则ORACLE就将数据分割成较小的块放在排序区中,然后对每一小块进行排序。排序产生的临时数据就先
放到临时表空间的临时段中。当每一小块都排序完成之后,再将这些排序完成的小块合并在一起,产生最终结果。
会话区
存储会话所具有的权限、角色、性能统计信息。
游标状态区
运行SQL语句或使用游标的语句时,ORACLE会在共享池中为该语句分配上下文区,游标实际是指向该上下文区的指针。在PGA区中的游标状态区存储的是会话
中当前使用的各个游标所处的状态。
堆栈区
存储的是会话中的绑定便利、会话变量、SQL语句运行的内存结构等信息。
进程结构
进程是动态创建的,完成任务后就消亡;而程序是静态的实体,程序是可以复制、编辑的。
进程强调的是执行过程,而程序仅仅是指令的有序集合;进程在内存中,程序在外存中。
ORACLE分为用户进程和ORACLE进程
用户进程:当用户执行一个基于ORACLE数据库的应用程序时,客户端就会创建一个ORACLE的用户进程。
用户进程通过连接登录到ORACLE服务器,ORACLE服务器上就产生一个对应的服务器进程;该服务器进程代表运行在客户端的用户进程服务器通信。
ORACLE进程:Oracle进程可以分为 服务器进程和后台进程
服务器进程:
务器进程主要是服务于客户端的用户进程。
务器进程又可以分为 专用服务器进程(只为一个用户进程提供服务)、共享服务器进程(可以为多个用户进程提供服务);
务器进程的任务:
A、解析并执行用户所提交的SQL语句;
B、搜索SGA区的数据库缓存,决定是否读取数据文件。如果数据块不在SGA区的数据库缓存中,就将其从数据文件中读入;
C、将查询执行的结构数据返回给用户;
后台进程(Background Process):
服务器进程是由后台进程提供支持的。
后台进程主要完成的任务是:
A、在内存和外存之间进行I/O操作;
B、监视各个进程的状态;
C、协调各个进程的任务;
D、维和系统的性能;
E、保证系统的可靠性;
SELECT * FROM V$BGPROCESS来检查数据库中启动的后台进程个数及其名称;
常用的后台进程:
SMON(System Monitor) 系统监视进程:
启动条件:
随ORACLE数据库系统启动;运行期间ORACLE可以唤醒SMON进程,以检查是否需要执行它所负责的工作;
如果其他任何进程需要使用SMON进程的功能时,将随时唤醒SMON进程。
作用:
A、在例程启动时负责对数据库进行恢复。如果是非正常关闭数据库,则当下次启动例程时,SMON进程会自动读取重做日志文件,对数据库进行恢复即执行将已提交的事务写入数据文件中、回退未提交的事务等操作;
B、清除已经分配但不再使用的表空间中的临时段。(如果表空间中有大量的盘区,则清除就会花费大量时间,就会影响数据库启动时的性能)
C、 合并基于数据字典管理的各个表空间中位置相邻的空闲盘区,使之更容易分配。
备注说明:
如果某个表空间的存储参数 PCTINCREASE 被设置为 0,则SMON进程就不会对该表空间中的空闲盘区进行合并操作。
PMON(Process Monitor) 进程监视进程;
启动条件:
需要启动、清除中断或失败的用户进程时;(即对ORACLE数据库的连接发生崩溃、挂起或其他非正常终止等)
清除操作还包括非正常中断的用户进程留下的孤儿会话,回退未提交的事务,释放会话所占用的锁、SGA区、PGA区的资源。
运行期间ORACLE可以唤醒PMON进程,以检查是否需要执行它所负责的工作;
如果其他任何进程需要使用PMON进程的功能时,将随时唤醒PMON进程。
PMON是在单独的数据库中启动的,而分布式数据库中是 RECO 恢复进程来完成PMON进程的任务的。
作用:
A、恢复中断或失败的用户进程、服务器进程;
B、清除非正常中断的进程留下的孤儿会话;
C、回退未提交的事务,重置活动事务的状态,从系统活动进程中删除用户进程标识号(ID);
D、释放进程所占用的各种资源,并通过自动回退事务来解决死锁,释放用户所拥有的表和行商的锁;
E、定期检查服务器进程和调度进程,如果它们因失败而被异常挂起,则自动重新启动它们;
DBWn(Database Writer) 数据库写进程;
启动条件:
当DIRTY列表中的脏缓存块达到到一定数量(即初始化参数db_block_write_batch指定值的一半),DBWn进程将脏缓存块写入数据文件(同时ORACLE将对控制文件和数据文件的头部的同步序号SCN进行修改,记录下当前数据库的结构和状态,以保证数据库中物理文件之间的同步);
当在LRU列表中找到一定数量(即初始化参数db_block_max_scan指定的值)的空闲缓存块,但还不够时,为获得更多的空闲缓存块,DBWn进程将脏缓存块写入数据文件;当出现检查点LGWR进程通知DBWn进程进行写操作;
一个表空间被置于备份模式、脱机或只读状态时;DBWn进程出现超时(Time_out)即大约3秒未启动时;
作用:
A、 管理高速缓冲区,保证服务器进程总能找到空闲缓存块,以便保存从数据文件中读取的数据块;
B、将DIRTY列表中的脏缓存块写入到数据文件中,获取更多的空闲缓存块;
C、使用LRU算法将最近正在使用的缓存块即命中块,继续保留在LRU列表中,不必重新读取数据文件;
D、DBRn进程通过延迟写入来优化磁盘I/O操作,而服务器进程只在数据高速缓存区中做修改;
备注说明:
DBWn进程在ORACLE中 最多可以启动20个该进程;但是最好不要超过CPU的个数,因为每个处理器同时只能运行已个DBWn进程;
ORACLE默认启动一个DBWn进程,启动受初始化参数(DB_WRITER_PROCESS)的限制。可以设置初始化参数 DB_BLOCK_CHECKPOINT_BATCH来
设置每当出现检查点时,DBWn进程写入的脏缓存块的最大数量。增大该值,可以延长启动DBWn进程的时间间隔;
LGWR(Log Writer) 日志写进程;
启动条件:
用户进程通过COMMIT语句提交当前事务;重做日志高速缓存被写满1/3时,或含有1MB的重做信息时;
DBWn进程需要为检查点清除脏缓存块,即将脏缓存块写入数据文件时;LGWR进程出现超时,即大约3秒为启动LGWR进程时;
作用:
A、负责管理重做日志高速缓冲区,即将重做日志记录从高速缓存区写入到重做日志文件;
B、如果例程没有启动CKPT检查点进程,则LGWR进程就来完成检查点执行任务;
备注说明:
每个例程只有一个LGWR进程;LGWR进程先于DBWn进程启动;
CKPT (CheckPoint) 检查点进程;
启动条件:
关闭数据库时;一个重做日志文件被写满而产生日志切换时;满足参数 LOG_CHECKPOINT_TIMEOUT(指定检查点之间的时间间隔(以秒为单位));
参数 LOG_CHECKPOINT_INTERVAL(指定当一定数量的操作系统数据块(非ORACLE数据块)被写入重做日志文件时,将触发一个检查点)
作用:
A、触发DBWn进程,使其将自上一个检查点之后的全部已经修改的数据块(脏缓存块)写入数据文件中;
B、保持数据库高速缓冲区与数据文件之间数据同步(用最新的检查点信息更新控制文件和数据库文件的文件头);
C、检查点信息会在恢复数据库期间使用,当SMON进程恢复数据库时,SMON会决定最后在数据文件中的检查点。必须将数据文件的文件头和控制文件中最后记录的检查点之后的联机重做日志文件中的事务编号重新提交到数据文件中。
备注说明:
不要设置不必要的检查点,或迫使不需要的检查点发生;缩短检查点执行的间隔,可以缩短数据库恢复时所需的时间;如果检查点执行的间隔短,
将会产生过多的I/O操作;应该使LOG_CHECKPOINT_INTERVAL 设置的操作系统块数与重做日志文件的大小箱匹配;
ORACLE在不同的时刻执行不同级别的检查点,故 检查点有可分为 4 种:
数据库检查点:
每一次重做日志文件切换时都执行数据库检查点;
使用NORMAL\TRANSACTIONAL\IMMEDIATE选项关闭数据库时,会执行一个检查点;
此时DBWn进程将数据高速缓存区中的所有脏缓存块都写入数据文件中。
表空间检查点:
将一个表空间设置为脱机状态或备注为BACKUP模式,会执行一个表空间检查点;此时DBWn只会将高速缓存区中的与该表空间相关的脏缓存块写入数据文件中。
手动检查点:
使用 ALTER SYSTEM CHECKPOINT 语句来手动设置一个检查点。
时间检查点:
即每隔多久执行一次检查点。可以通过调整(LOG_CHECKPOINT_TIMEOUT和 LOG_CHECKPOINT_INTERVAL)参数来改变检查点实行的间隔。
ARCn(Archiver) 归档进程;
启动条件:
发生重做日志切换时(必须是归档模式下,并且初始化参数 LOG_ARCHIVE_START 为 TRUE ,如果在归档模式下 该参数是FALSE 当重做日志文件全部全满,数据库将会被挂起。);
作用:
避免数据库崩溃无法恢复。
备注说明:
一个例程默认只会启动一个归档进程ARCn,当ARCn正在归档一个重做日志文件时,任何其他进程都不能访问这个重做日志文件。
为了避免LGWR进程使用正在归档中的重做日志文件造成数据库被挂起,LGWR进程会根据需要主动启动更多的归档进程。ORACLE最多可以启用10个ARCn。
初始化参数 LOG_ARCHIVE_DEST 指定了归档日志文件所在的位置;LOG_ARCHIVE_FORMAT指定了归档日志文件的命名格式规则。
RECO(Recoverer) 恢复进程;
启动条件:
在分布式数据库中,RECO恢复进程周期性地启动,以判断是否有服务器进程发生故障,清除失败的事务。
即 分布式数据库中 启动RECO恢复进程,单独数据库中 启动PMON 进程监视进程。
如果将数据库设置成分布式事务处理方式,初始化参数 DISTRIBUTED_TRANSACTIONS 的值设置为大于0 ,则RECO恢复进程将会自动启动,
如果设置为 0 ,则RECO恢复进程就不会启动。
备注说明:
分布式事务处理是指:事务在分布式数据库上(多个数据库)进行数据更新、删除、插入等操作,即为分布式事务处理。
原理:在发起事务的数据库将作为一个协调器,协调器询问其他数据库是否已做好准备进程事务提交。如果所有的数据库都回应做好准备,则协调器就会发送一个消息,让事务的提交在所有数据库上永久生效。否则该事务就会在所有数据库上进行回退。该过程被称为 两阶段提交。
LCKn(Lock) 锁进程;
备注说明:
ORACL上最大可以有10个锁进程。
RVWR(Recovery Writer) 闪回恢复进程;
CTWR(Change Tracking Writer) 闪回变化跟踪写进程;
CJQn(Job Queue Monitor) 作业队列监视进程;
Jnnn(Job Queue) 作业队列进程;
Dnnn(Dispatcher) 调度进程;
备注说明:
调度进程是多线程服务器体系架构(共享服务器模式)。调度进程接收用户进程的请求,并将用户进程放入到请求队列中,然后为请求队列中的用户进程分配以个共享的服务器进程。通过设置初始化参数 MTS_DISPATCHERS 为不同的网络协议指定调度进程的数量。例如:
MTS_DISPATCHERS=‘(PROTOCOL =TCP) (DISPATCHERS=5)‘
Snnn(Shared Server) 共享服务器进程;
SQL 语句的执行标准流程
1、建立一个执行该语句所需的显示或隐式游标;
2、在共享SQL区中查找是否有该SQL语句。
2.1 如果共享SQL区总没有该SQL语句,则ORACLE就解析该SQL语句,再定义输出结果(即将结果输出给变量,定义输出的位置、类型、结果集等);
3、判断是否使用了绑定变量;
3.1、如果使用,则用户进程提供 绑定便利,然后ORACLE进行绑定;
4、ORACLE 执行计划,尽可能的进行并行处理操作;
5、执行SQL语句;
6、如果是SELECT 查询语句就将结果返回给用户进程,如果是 DML(insert、 delete、update 等)就将执行状态返回给用户进程;
7、关闭游标;
转自:http://blog.csdn.net/zhaowenzhong/article/details/7057750