一、Oracle物理体系结构


Oracle的体系结构 如图
1、Oracle由实例和数据库组成,用两个虚框标记出来,上半部的直角方框为实例instance,下半部的圆角方框为数据库Database 。
2、实例是由一个开辟的共享内在区SGA(SystemGlobal Area)和一系列后台进程组成的,其中SGA最主要被划分为共享池(Shared Pool)、数据缓冲区(DB Cache)和日志缓冲区(Log Buffer)三类。后台进程如图所示的PMON、SMON、LCKn、RECO、CKPT、DBWR、LGWR、ARCH等系列进程。
3、数据库是由数据文件、参数文件、日志文件、归档日志文件等系列文件组成的,其中归档日志最终可能会被转移到新的存储介质中,用于备份恢复使用。
4、图中圆形虚线标记部分中,PGA(Program Global Area)区,这也是一块开辟出来的内在区,和SGA最明显的差别在于,PGA不是共享内存,是私有不共享的,S理解为共享的首字母。用户对数据库发起的无论查询还是更新的任何操作,都是在PGA先预处理,然后才进入实例区域,由SGA和系列后台进程共同完成用户发起的请求。
PGA起到的具体作用,也就是前面说的预处理,主要有三点:
第一,保存用户的连接信息,如会话属性、绑定变量等;
第二,保存用户权限等重要信息,当用户进程与数据库建立会话时,系统会将这个用户的相关权限查询出来,然后保存在这个会话区内;
第三,当发起的指令需要排序的时候,PGA(Program Global Area)正是这个排序区,如果在内在中可以放下排序的尺寸,就在内在PGA区内完成,如果放不下,超出的部分就在临时表空间中完成排序,也就是在磁盘中完成排序。
5、在图中标识了三块区域(注意看虚线框的左下角标注),分别是1区圆形虚线框,2区直角方形虚线框,3区圆角方形虚线框。用户的请求发起经历的顺序一般如下:
1区-->2区-->3区 或 1区-->2区。
物理读:查询计划生成好以后,如果缓存缺少所需要的数据,让缓存再次去读硬盘。如果内存里没有缓存数据或执行计划(SQL指令改变执行计划不能重用,需要重新计算执行计划),那么SQL指令就要去硬盘读取这些数据,这时候就是物理读,硬盘速度跟内存速度不在一个数量级别,所以物理读是比较慢的。
逻辑读:SQLSERVER去内存里面的缓存取数据或执行计划(执行计划可以重用),所以逻辑读是比较快的。
二、SQL查询指令多次执行的时间差异:
1、用户首次执行SQL指令时,该指令从磁盘中获取用户转接信息和相关权限,并保存在PGA内存里。当用户再次执行该指令时,由于SESSION之前末被断开重连,转接信息和相关权限信息就可以在PGA内存中直接获取,避免了物理读。
2、首次执行该SQL指令结束后,SGA内存的共享池里已经保存了该SQL唯一指令HASH值,并保留了语法语意检查及执行计划等相关解析动作的劳动成果,当再次执行该SQL时,由于该SQL指令的HASH值和共享池里保存的相匹配了,所以之前的硬解析动作就无须再做,不仅跳过了相关语法语意检查,对于该选取哪种执行计划也无须考虑,直接拿来使用就行。
3、首次执行该SQL指令时,数据一般不丰SGA的数据缓存区里(除非被别的SQL读入内存了),只能从磁盘中获取,不可避免产生了物理读,但是由于获取后会保存在数据缓冲区时,再次执行就直接从数据缓冲区里获取了,完全避免了物理读,效率当然高得多。
三、SQL更新指令
更新指令除了执行查询指令的三个步骤外,还会启用DBWR进程,完成更新的数据从内在中刷入到磁盘,将磁盘中的值更新为新值。因为磁盘才是真正存储数据的地方,否则一断电,数据在内在中,那就灰飞烟灭了。DBWR进程写入------如下图

日志缓冲区保存了数据库相关操作的日志,记录了这个动作,然后由LGWR后台进程将其从日志缓冲区这个内在区写进磁盘的日志文件里。目的简单,为了便于将来出现异常情况时,可以根据日志文件中记录的动作,再继续执行一遍,从而保护数据的安全。如下图

实例中的一个重要后台进程:CKPT。什么时候将数据缓存区数据写到磁盘的动作正是进程CKPT来触发的,CKPT触发DBWR写出。可以通过设置某参数调整来控制CKPT的触发时间,比如万一出现数据库崩溃,希望Oracle的SMON最多用多长时间来做Instance Recovery,该参数就是FAST START MTTR TARGET,通过调整该参数,Oracle会调配CKPT在适当的时候去调用DBWR...... 当然,这个参数也并非越小越好,太小的数值会导致Oracle性能降低。