1. 概述
Oracle数据库系统由Oracle数据库和Oracle实例组成,分别对应着数据库的存储结构和软件结构。
- Oracle数据库:是固定的,基于磁盘的数据文件、控制文件、日志文件、参数文件、归档日志文件等
- Oracle实例:是管理数据库的后台进程和内存结构的集合。
之前的文章介绍了存储结构(Oracle数据库的体系结构(上)——存储结构),这一篇继续介绍软件结构,即Oracle实例部分。
2. 内存结构
用户操作数据库实际上是与数据库实例建立连接,然后通过实例来操作数据库的过程。用户的所有操作都在内存中进行,最后由数据库后台进程将操作结果写入各种物理文件中永久性保存。
内存结构是Oracle数据库体系结构中最为重要的部分之一,内存也是影响数据库性能的主要因素。在Oracle数据库中,服务器内存的大小将直接影响数据库的运行速度,特别是多个用户连接数据库时,服务器必须有足够的内存支持,否则有的用户可能连接不到服务器,或查询速度明显下降。
内存结构类型:
- 系统全局区(System Global Area,SGA)
- 程序全局区(Program Global Area,PGA)
当服务器进程启动时分配程序全局区。
2.1 系统全局区(SGA)
- SGA是由Oracle分配的共享内存结构,包含一个数据库实例的数据和控制信息。
- SGA数据供所有的服务器进程和后台进程共享,所以SGA又称为共享全局区(Shared Global Area)。
- SGA随数据库实例的创建而分配,随实例的终止而释放。
- SGA构成:
- 数据高速缓冲区(Database Buffer Cache)
- 共享池(Shared Pool)
- 重做日志缓冲区(Redo Log Cache)
- 大型池(Large Pool)
- Java池(Java Pool)
- 流池(Streams Pool)
- 其它结构(如固定SGA、锁管理等)
2.1.1 数据高速缓冲区
- 存储从数据文件中检索出来的数据拷贝。应用程序要访问的数据必须从磁盘的数据文件读到数据缓冲区中 处理。
- 在数据缓冲区中被修改后的数据由数据写入进程DBWR写到硬盘的数据文件中永久保存。
- 目的是提高获取和更新数据的性能。
- 缓冲块的类型
- 脏缓存块(Dirty Buffers):脏缓存块中保存的是已经被修改过的数据。
- 空闲缓存块(Free Buffers):空闲缓存块中不包含任何数据,它们等待后台进程或服务器进程向其中写入数据。
- 命中缓存块(Pinned Buffers):命中缓存块是那些正被使用的数据块,同时还有很多会话等待修改或访问的数据块。
- 干净缓存块(Clean Buffers):干净缓存块是指那些当前没有被使用,即将被换出内存的缓存块。
- 缓存块的管理
- LRU列表(Least Recently Used):包含所有的空闲缓存块、命中缓存块和那些还没有来得及移入到脏缓存块列表中的脏缓存块。在该列表中,最近被访问的缓存块被移动到列表的头部,而其他缓存块向列表尾部移动,最近最少被访问的缓存块最先被移出LRU列表(淘汰队尾的),从而保证最频繁使用的缓存块始终保存在内存中。
- 数据高速缓冲区大小
- 数据高速缓冲区越大,用户需要的数据在内存中的可能性就越大,即缓存命中率越高,从而减少了Oracle访问硬盘数据的次数,提高了数据库系统执行的效率。然而,如果数据高速缓冲区的值太大,Oracle就不得不在内存中寻找更多的块来定位所需要的数据,反而降低了系统性能。显然需要确定一个合理的数据高速缓冲区大小。(太大资源也有限)
- 决定其大小的参数:DB_CACHE_SIZE(标准块)、DB_nK_CACHE_SIZE(非标准块)。
2.1.2 共享池
- 共享池用于缓存最近执行过的SQL语句、PL/SQL程序和数据字典信息,是对SQL语句、PL/SQL程序进行语法分析、编译、执行的区域。
- 组成:
- 库缓存:存用于缓存已经解释并执行过的SQL语句和PL/SQL程序代码,以提高SQL或PL/SQL程序的执行效率。包括SQL工作区和PL/SQL工作区。
- 数据字典缓存区:保存最常用的数据字典信息,可从中获得对象是否存在、用户是否有操作权限等信息,大大提高执行效率。
- 共享池大小
- 合适的共享池大小,可使编译过的程序代码长驻内存,大大降低重复执行相同的SQL语句、PL/SQL程序的系统开销,从而提高数据库的性能。
- 决定其大小的参数:SHARED_POOL_SIZE。
2.1.3 重做日志缓冲区
- 用于缓存用户对数据库进行修改操作时生成的重做记录。
- 为了提高工作效率,重做记录并不是直接写入重做日志文件中,而是首先被服务器进程写入重做日志缓冲区中,在一定条件下,再由日志写入进程(LGWR)把重做日志缓冲区的内容写入重做日志文件中做永久性保存。
- 在归档模式下,当重做日志切换时,由归档进程(ARCH)将重做日志文件的内容写入归档文件中。
- 重做日志缓冲区的大小
- 较大的重做日志缓冲区,可以减少对重做日志文件写的次数,适合长时间运行的、产生大量重做记录的事务。
- 决定其大小的参数:LOG_BUFFER。
2.2 程序全局区(PGA)
- PGA是一个私有的内存区,不能共享,每个服务器进程只能访问自己的PGA,因此PGA又称为私有全局区(Private Global Area)。
- 系统同时为每个后台进程分配私有的PGA区。所有服务器进程PGA与所有后台进程PGA大小的和,即为实例的PGA的大小。
- PGA随着服务器进程与后台进程的启动而分配,随着服务器进程和后台进程的终止而被释放。
- PGA构成:
- 排序区(Sort Area):存放排序操作所产生的临时数据。
- 游标信息区(Cursor Information):存放执行游标操作时所产生的数据。
- 会话信息区(Session Information):保存用户会话所具有的权限、角 色、性能统计信息。
- 堆栈区(Stack Space):用于保存会话过程中的绑定变量、会话变量等信息。
3. 后台进程
- 进程是操作系统中一个独立的可以调度的活动,用于完成指定的任务。
- 进程的类型:用户进程 、服务器进程、后台进程。
- 用户进程:当用户运行一个应用程序时,就建立一个用户进程。
- 服务器进程:处理用户进程的请求(包括分析SQL命令并生成执行方案; 从数据缓冲存储区中读取数据;将操作信息写入重做日志缓冲区;将执行结果返回给用户。)
- 后台进程:为所有数据库用户异步完成各种任务 。主要的后台进程有:
- DBWR 数据库写进程
- Dnnn 调度进程
- LCKn 封锁进程
- RECO 恢复进程
- ARCH 归档进程
- PMON 进程监控进程
- SMON 系统监控进程
- CKPT 检查点写进程
- LGWR 日志写进程
3.1 DBWR(数据库写入进程)
- 把数据高速缓冲区中已经被修改过的数据(脏缓存块)成 批写入数据文件中永久保存,同时使数据高速缓冲区有更多的空闲缓存块,保证服务器进程将所需要的数据从数据文件中读取到数据高速缓冲区中,提高缓存命中率。
- ❗启动DBWR进程:
- 执行INSERT、UPDATE等操作时 ,没有足够的空闲块;
- 当检查点发生时,将启动DBWR进程;
- 当数据缓存的LRU列表的长度达到初始化参数 DB_BLOCK_WRITE_BATCH指定值的一半时;
- 若发生超时(大约3秒未被启动)。
- 注:DBWR进程的启动时间与用户提交事务的时间完全无关。
- DBWn是因为有多个进程。
DBWR功能小结:管理数据缓冲区,将最近使用过的块保留在内存中。将修改后的缓冲区数据写入数据文件中。
3.2 LGWR(日志写入进程)
- 日志写入进程负责把重做日志缓冲区的重做记录写入重做日志文件中永久保存。
- ❗启动LGWR进程:
- 用户通过COMMIT语句提交当前事务;
- 重做日志缓存被写满三分之一;
- DBWR进程开始将脏缓存块写入数据文件;
- 每隔3秒,即发生一次超时,将启动LGWR。
LGWR功能小结:负责将日志缓冲区中的日志数据写入日志文件。系统有多个日志文件,该进程以循环的方式将数据写入文件。
3.3 CKPT(检查点进程)
- 检查点是一个事件,当该事件发生时(每隔一段时间发生),DBWR进程把数据高速缓冲区中脏缓存块写入数据文件中,同时Oracle将对数据库控制文件和数据文件的头部的同步序号进行更新,以记录下当前的数据库结构和状态,保证数据的同步。
- CKPT进程的作用:
- 更新控制文件与数据文件的头部,使其同步。
- 触发DBWR进程,将脏缓存块写入数据文件。
3.4 SMON(系统监控进程)
- 功能:
- 自动进行实例恢复:
- 执行前滚(ROLL FORWARD),将重做日志信息已经写入到重做日志文件中但还数据还没有写入到数据文件中的已提交的数据写入 到数据文件。(前滚-已提交但没有写入数据库的)
- 在前滚完成后立即打开数据库。此时用户可以连接数据库,但此时数据文件中可能存在一些没有提交的数据需要回滚。(回滚-已写入数据库但没有提交的)
- 回滚没有提交的事务。
- 回收不再使用的临时空间。
- 将各个表空间的空闲碎片合并(表空间的存储参数PCTINCREASE不为0时)。
- 自动进行实例恢复:
- 定期被唤醒/随时被唤醒。
SMON功能小结:在实例失败之后,重新打开数据库时自动恢复实例。整理数据文件的自由空间,将相邻区域结合起来。释放不再使用的临时段。
3.5 PMON(进程监控进程)
- 主要功能:
- 负责恢复失败的用户进程或服务器进程,并且释放进程所占用的资源。
- 清除非正常中断的用户进程留下的孤儿会话,回退未提交的事务,释放会话所占用的锁、SGA、PGA等资源。
- 监控调度进程和服务器进程的状态,如果它们失败,则尝试重新启动它们,并释放它们所占用的各种资源。
- 定期被唤醒/随时被唤醒。
PMON功能小结:清理出现故障的进程。释放所有当前挂起的锁定。释放故障进程使用的资源。
3.6 ARCH(归档进程)
- 归档进程负责在日志切换后将已经写满的重做日志文件复制到归档目标中,防止写满的重做日志文件被覆盖。
- 只有当数据库运行在归档模式,且LOG_ARCHIVE_STATE=TRUE,才能启动ARCH。否则,当重做日志文件全部写满,数据库将被挂起,等待DBA进行手工归档。
3.7 RECO(恢复进程)
- RECO进程负责在分布式数据库环境中自动解决分布式事务的故障。一个节点的RECO自动解决所有的悬而未决的事务。当一个数据库服务器的RECO后台进程试图建立同一远程服务器的通信,如果该远程服务器不可用或者网络连接不能建立时,RECO自动地在一个时间间隔之后再次连接。
3.8 LCKn(锁进程)
- LCKn进程用于Oracle并行服务器环境中。在数据库中最多可以启动10 个LCKn进程,主要用于实例间的封锁。
3.9 Dnnn(调度进程)
- Dnnn进程是多线程服务器(Multithreaded Server,MTS)的组成部 分,以后台进程的形式运行。调度进程接受用户进程请求,将它们放入请求队列中,然后为请求队列中的用户进程分配一个服务器进程。最后,从响应队列返回数据给用户进程。