Oracle 数据库体系结构详解
一、SGA 相关概念
SGA,全称为 “System Global Area”(系统全局区),是 Oracle 为实例分配的一组共享缓冲存储区,主要用于存放数据库数据和控制信息,供数据库进程共享(PGA 不可共享),以实现对数据库数据的管理和操作。它包含 Oracle 服务器的数据和控制信息,存储在 Oracle 服务器所在计算机的实际内存中,若实际内存不足,则会写入虚拟内存。当数据库实例启动时,SGA 自动分配;实例关闭时,SGA 内存被回收。作为占用内存最大的区域,SGA 对数据库性能有着至关重要的影响。
(一)SGA 主要组成部分
Shared Pool(共享池)
共享池是 SGA 的重要组成部分,用于缓存此前执行过的 SQL 语句、PL/SQL 代码、数据字典内容等信息,供会话重用,以提高执行效率。其缓存内容以 “行” 为形式,且无法单独控制其中 Library Cache(库缓存)和 Dictionary Cache(数据字典缓存)的内存大小,只能整体控制共享池的大小。这是因为共享池中的可用内存块(chunk)具有动态性,若内存块存储数据字典信息,则属于数据字典缓存;若存储 SQL 文本或执行计划等,则属于库缓存,且内存块的归属可能因内存不足等情况发生切换。
在处理 SQL 语句时,Oracle 会先对提交的 SQL 语句进行哈希算法处理,生成 hash_values,再利用该值在 buffer cache 中查找是否存在相同语句,以实现高效检索。
Buffer Cache(缓冲区缓存)
缓冲区缓存是 Oracle 执行 SQL 的工作区域,以 “块” 为形式缓存内容。为避免频繁磁盘 IO 对系统性能造成毁灭性影响,用户会话不会直接操作磁盘数据,无论是查询还是 DML(insert、update、delete)操作,都需先作用于缓冲区缓存。
以查询语句select ename,salary from emp where name='111';为例,用户提交该语句后,用户进程(如 sql developer)将其发送给服务器,监听程序为其建立对应的服务器进程。服务器进程首先扫描缓冲区缓存,若存在包含 “111” 关键行的数据块(缓存命中),则将相关行传输到 PGA 进一步处理,格式化后展示给用户;若未命中,则先将对应数据块从磁盘复制到缓冲区缓存,再返回给客户端。
DML 操作流程类似,若缓存命中,服务器进程直接在缓冲区缓存中更新数据,导致数据块变为 “脏缓冲区”;若未命中,先将数据块从磁盘复制到缓冲区缓存,再执行更新。
日志缓冲区
日志缓冲区是一块较小的内存区域,用于短期存储将写入磁盘重做日志文件的变更向量,其存在意义在于减少磁盘 IO,缩短用户等待时间。与缓冲区缓存不同,日志缓冲区不能自动管理,修改其配置需重启实例。
(二)相关后台进程
DBWn(数据库写入器)
DBWn 是 Oracle 的后台进程,“n” 表示一个实例可配置多个(最多 20 个,如 DBW0-DBWN9、DBWa-DBWj),核心作用是将缓冲区缓存中的脏缓冲区(存储块与磁盘块不一致的缓冲区)写入磁盘的数据文件。
DBWn 采用 “极懒算法”,仅在以下四种情况执行写入,以减少频繁磁盘 IO 对系统性能的影响:
无可用缓冲区时,不得不写入;
脏缓冲区数量过多;
每 3 秒超时一次;
遇到检查点(checkPoint)事件,如实例有序关闭时,需将所有脏缓冲区写入磁盘,保证数据文件一致性。
需注意,DBWn 的写入与会话更新操作、commit 操作均无直接关联,并非一产生脏缓冲区或执行 commit 就写入磁盘。
LGWR(日志写入器)
与 “懒惰” 的 DBWn 不同,LGWR 十分 “勤快”,核心功能是将日志缓冲区内的内容写入磁盘的重做日志文件,以确保数据安全,它也是 Oracle 体系结构中的主要瓶颈之一,DML 速度无法超过 LGWR 写入变更向量的速度。
LGWR 在以下三种情况执行写入:
执行 commit 操作时,会话会挂起,等待 LGWR 将相关记录写入磁盘重做日志文件后,才通知用户提交完成,确保事务不丢失;
日志缓冲区占用率达到 1/3 时;
DBWn 写入脏缓冲区前,为保证事务回滚,需先由 LGWR 写入针对撤销数据的日志记录。
二、Oracle 数据库主要进程
(一)PMON(Process Monitor Process,进程监控进程)
负责监控进程运行状态,对异常进程进行恢复;
清理 buffer cache,释放客户端进程使用的资源,如重置事务表状态、释放锁、删除进程 ID 等;
将实例信息和调度进程注册到 Oracle Net Service;
定期检查监听程序是否启动,若已启动则传递相关参数给 listener,未启动则定时尝试连接。
(二)SMON(System Monitor Process,系统监控进程)
执行实例恢复,如实例不一致关闭后重启时的恢复操作;
恢复因读文件错误或表空间脱机错误中断的事务;
清空未使用的临时段,管理 tempfile;
合并数据字典管理的表空间中连续的空闲区块。
(三)DBWn(Database Write Process,数据库写进程)
如前文所述,DBWn 负责将 buffer cache 中修改过的脏数据写入磁盘,写入触发条件包括服务器进程无法找到可重用缓冲区、定时写入等,最多可配置 20 个。
(四)LGWR(Log Write Process,日志写进程)
主要功能是将日志缓冲区中连续的日志内容写入在线重做日志文件,触发条件有用户提交事务、日志切换、3 秒超时、日志缓冲区占用达 1/3 或 1Mb、DBWn 写入脏数据前等。
(五)CKPT(Checkpoint Process,检查点进程)
更新控制文件和数据文件头文件的检查点信息,包括检查点位置、SCN、在线重做日志恢复起始点等;
触发 DBWn 将脏数据写入磁盘。需注意,增量检查点仅每 3 秒更新控制文件中的 low cache rba 信息(检查点位置),不更新数据文件头及控制文件中数据库 SCN 和数据文件条目 SCN。
三、SCN(System Change Number,系统改变号)
(一)SCN 的定义与作用
SCN 是 Oracle 根据时间点通过函数运算得到的一串数字,反之也可通过 SCN 反推时间,本质是时间的另一种表示形式。系统使用 SCN 而非直接用时间,是因为 SCN 便于比较对象的新旧关系,操作更简单高效,核心作用是保证 Oracle 数据和文件的一致性。
(二)常见 SCN 类型
Checkpoint Queue(检查点队列)相关 SCN
通过查询语句select CPDRT,CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low RBA",CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF "On disk RBA",CPODS,CPODT,CPHBT from x$kcccp;可查看相关信息。其中,CPDRT 为当前脏 buffer 数量,Low RBA 是检查点队列中最早脏 buffer 的日志地址,On disk RBA 是当前日志文件最后一条日志的地址,CPODS 是 On disk RBA 写入时对应的 SCN。Oracle 每 3 秒触发一次检查点事件,将 Low RBA 保存到控制文件,实例崩溃重启恢复时,以此为起点、On disk RBA 为终点应用日志。
控制文件 SCN
控制文件包含三种重要 SCN:
系统检查点 SCN:全局范围 SCN,CKPT 进程启动时保存到控制文件,文件级别的 SCN 操作(如将表空间置为只读)不更新该 SCN,可通过select CHECKPOINT_CHANGE# from v$database;查询;
数据文件检查点 SCN:CKPT 进程启动(全局或文件级检查点)时更新,保存到控制文件,通过select file#, name, checkpoint_change# from v$datafile;查询;
数据文件结束 SCN:数据文件在线且可读写时为空,否则为具体 SCN 值,代表数据文件停止读写的时间,可通过关联查询 v$datafile、dba_data_files、dba_tablespaces 表查看。
日志文件 SCN
每条 redo log 数据项都对应一个 SCN,日志文件头记录两个关键 SCN:
First SCN:日志文件第一条数据项的 SCN;
Next SCN:日志文件最后一条数据项的 SCN,同时也是下一个日志组的 First SCN,用于体现日志文件的衔接关系,通过select * from v$log;可查询。
根据 SCN 及日志使用情况,日志组文件分为三种状态:
Current:当前正在使用的日志组,新日志写入此处;
Active:非当前日志组,但其日志对应的脏 buffer 未完全写入数据文件,不可覆盖重写;
Inactive:非当前日志组,且日志对应的脏 buffer 已全部写入数据文件,可覆盖重写。生产环境中通常最少建立 5 组重做日志,确保日志正常切换。
四、Oracle 实例恢复
(一)实例恢复的触发场景
当数据库突然崩溃(如断电),buffer cache 中的脏数据块未及时刷新到数据文件,且运行中的事务被中断(处于未提交也未回滚的中间状态),导致数据文件内容无法反映实例崩溃时的状态,数据库关闭不一致,下次启动实例时,SMON 进程会自动触发实例恢复。
(二)实例恢复的过程
检测恢复需求:实例启动时,SMON 进程检查控制文件中在线可读写数据文件的 STOP SCN。正常运行时,该 SCN 为空;正常关闭数据库时,会执行完全检查点,将检查点 SCN 更新为 STOP SCN。若 SMON 发现 STOP SCN 为空,则判定实例上次未正常关闭,启动恢复。
前滚(Roll Forward):SMON 从控制文件中找到每 3 秒触发的增量检查点对应的 RBA 地址(检查点队列第一个脏数据块的日志地址),在联机日志文件中定位该地址,从该位置开始应用所有 redo 条目,直至 ON DISK RBA(检查点队列最后一个 RBA,即联机日志文件最后一条 redo),使 buffer cache 恢复到实例崩溃时的状态,此时 buffer cache 中包含已提交未写入数据文件的脏数据块和未提交的脏数据块。
打开数据库与回滚(Roll Back):前滚完成后,SMON 立即打开数据库,允许用户访问。随后,SMON 在后台对未提交的事务进行回滚,删除未提交事务产生的脏数据块,最终使数据文件仅保留提交的数据。
(三)实例恢复的特点
Oracle Database 10g 及以后版本可自动从实例错误中恢复,DBA 只需正常启动实例。实例启动后,先装载控制文件,尝试打开数据文件;若发现文件关闭时不同步,利用重做日志信息将数据文件前滚到错误发生前的状态,再回退未提交事务(还原表空间已前滚),确保数据一致性。
浙公网安备 33010602011771号