oracle内存结构与SQL处理流程


SQL执行过程
第1阶段:client发起SQL
客户端进程(jdbc/sqlplus)发送SQL查询需求,监听器接收到需求信息发送给服务器进程。服务器进程接收信号,在内存中开辟一块内存区给本次会话(PGA)
将客户端信息存储在本次会话的PGA中
第2阶段:PARSE解析阶段
- 服务器进程将PGA存储的信息调入SGA中的shared pool中进行解析
- 语法解析:检查SQL语句是否符合语法规范(检查机制官方文档没有说明)
- 语义解析:通过shared pool的dictionary cache检查SQL语句的对象是否存在、字段是否存在、是否有权限等.(dictionary cache找不到相关字典信息就去磁盘数据文件读取)
- 生成执行计划
- 查询library cache的SHARE SQL AREA(共享SQL区域)是否存在已解析的相同SQL。如果存在,服务器进程直接调用解析树和执行计划到DB BUFFER CACHE执行(软解析)
- 如果在library cache中的SHARE SQL AREA中不存在已解析的相同SQL,则进行执行计划的生成,并在library cache中分配新的内存区域存储此信息(硬解析)
第3阶段:EXEC执行阶段
- 不管是硬解析还是软解析,服务器进程最终会得到执行计划。并将其调入DATABASE BUFFER CACHE(数据库高速缓冲区缓存,也叫块缓冲区缓存)
- 按照执行计划,在database buffer cache里面读取相关数据块信息
- 如果读取了相关块数据,暂时将数据集合存储database buffer cache。 (result cache是存储复杂的数据、不经常改变的数据,默认是关闭的) (这一步简称逻辑读)
- 如果没有读取到,服务器进程去磁盘数据文件读取相关数据块房在database buffer cache中暂时存储下来(这一步简称物理读)
第4阶段:FETCH读取/返回数据
服务器进程将结果集通过监听器返回给客户端进程
- 数据的返回有2个路径,1个通过SDU(SESSION DATA UNIT)返回,第二个路径是如果采用JDBC方式这则直接通过网络传输数据。(资料来源Oracle内核技术揭秘第4.2章节)
DML语句执行过程
第1阶段:client发起SQL
- oracle监听器接收到SQL请求,发送给服务器进程
- 服务端进程分配PGA,存储本次会话信息
第2阶段:PARSE解析阶段
- SGA中的shared pool中进行解析(解析SQL语句的语法、语义)
- 生成SQL执行计划并存入library cache(已经存在的下次就不再进行解析)
第3阶段:EXEC执行阶段
- 解析SQL语句得到执行计划,并将被操作数据从磁盘调入database buffer cache
- database buffer cache(数据库高速缓冲区缓存,也叫块缓冲区缓存) 作用:用来缓存从数据文件中读取的数据;延迟写数据文件,减少与磁盘的交互次数
- 相关数据块信息已经存在,则把数据集合存储在SHARE POOL中的result cache(逻辑读)
- 相关数据块信息不存在,服务器进程(PGA)去磁盘读取相关数据块并在database buffer cache中暂时存储下来,并将缓存中的结果集存储到result cache(物理读)
- 修改database buffer cache数据后,会产生UNDO数据和REDO数据
- DML直接修改的是db buffer cache中的数据块
- UNDO是修改前数据,RODO是修改后的数据
- 客户端提交(COMMIT)以后,触发LGWR进程将redo log buffer的数据刷入磁盘的物理文件REDO LOG FILE,然后直接给客户端响应DML操作结果
- redo log写入磁盘的同时,将DML修改的数据存入REDO LOG BUFFER和UNDO
- LGWR进程将database buffer cache中的脏块(有变更与dbf文件中不一致)写入磁盘
- LGWR进程 触发时机:脏块过多或空间不足够写入新数据块; 淘汰策略:LRU