一个SQL语句的执行过程
用户A主动连接数据库,首先user process(up)向监听请求连接,监听收到 up 的请求后,根据连接串找到实例所在位置,通知实例有up发起连接,此时实例启动一个 server process(sp),将sp的地址告诉监听,监听将sp地址转发给up,up收到sp的地址后,直接和sp建立连接。
up和sp顺利建立连接后,就可以访问数据库,当us发起一个sql语句时,sp接收到up传过来的sql后,首先对这个sql进行语法检查、语义检查。这两项检查通过之后,开始对sql进行解析。
解析过程:对sql字符串进行hash运行,得到hash值 hashA,对 hashA再进行一次运算,得到sql执行计划所在链编号 chainB,然后sp遍历library cache 中链 chainB上是否存在 hash值为 hashA 的执行计划,如果存在,则拿出该执行计划直接执行,此为软解析。如果不存在,则调用cbo生成一系列执行方案,在众多执行方案中挑选出性能最优的作为执行计划。然后在free中选择出合适大小的buffer,将执行计划放进去之后,把这个buffer连接到library cache 的链 chainB上。也就是发生了硬解析。如果在free中没有找到大小刚好合适的buffer,就会查找比所需buffer大的buffer,然后分割出需要大小的buffer来存放执行计划。如果free中彻底没有所需要的buffer,则会覆盖library cache 中LRU链冷端的buffer,如果从library cache和 free中均找不到可用的块存放执行计划,则会抛出 ora-4031错误。
得到执行计划后,就根据执行计划的指示,执行sql,确定需要的数据所在内存块。sp首先到database buffer cache中查找是否全部所需数据都在buffer cache中,如果不是,则sp从存储在硬盘上的数据文件中读入所需数据行所在block。即发生了物理读,Oracle IO的最小单位是块。在发生物理IO时,首先查找buffer cache中是否有free状态的buffer,如果没有,则查找干净的buffer,如果还是没有,则sp触发ckpt执行增量检查点,将ckpt队列前端的部分脏块写回dbf。如果写入的脏块中有对应redo log未写入日志的,则会在DBWn开始写数据之前,触发LGWR将redo log写入online redo log file。如果online redo log 写满,则只能先切换日志才能继续写日志操作。在得到可以覆盖的buffer后,sp将所需block从dbf读入buffer cache。再从buffer cache返回PGA,即发生了内存读。
sp从buffer cache中读取一个buffer的数据时,会首先检查该buffer头部的事务槽中是否有未释放事务锁,如果有,则发生一致读。如果没有,则sp会进一步确定事务槽中事务对应的undo段段头块的事务表中该事务的的锁是否释放,如果不是,也发生一致读。如果是,则改写buffer头部事务槽信息。然后直接读该buffer,无需构造cr块。在读取的过程中,如果遇到行头中行锁未释放的情形,也会改行锁标记。在此过程中,改锁标记的动作引起了buffer的改变,将会在pga中产生redo log。
构造cr块的过程:如果sp在内存读时,检测到需要构造cr块,则会读取buffer头事务槽信息中的uba,根据uba的指引找到对应的undo块,读出undo块中的信息构造cr块。然后读取该cr块返回pga,如果构造 cr 块需要的信息,已经从undo 中挤出去了,那么构造cr块将会失败,此时抛出 ora-01555异常。
如果用户发出了一个dml语句,首先oracle会找到一个相对空闲的undo段,在undo段的段头块的事务表中插入一条事务信息,然后找到要修改的数据块,假设是 buffA,在数据块头的事务槽中填写该事务信息,并且在undo段中为该事务分配一个undo块。如果需要修改的数据块不在buffer cache中,则产生物理读将数据从dbf读入buffer cache。如果需要修改的数据块事务槽中记录了其它未提交的信息,则会到事务表中进行验证,如果该事务确实没有提交,则会等待该事务提交后,才会加锁。等到加锁完成后,开始修改buffA,首先将 buffA 中修改之前的数据复制到 undo块。然后覆盖修改。每次修改之前,都需要将buffA的数据事先复制到undo块中, 如果一个undo块不够用,将会申请一个新的undo块,新undo块的地址记录在前一个undo块的块头中。如果一个事务用了很多undo块,超过一个undo段大小,就会报错。
当用户结束修改,要提交事务时,在同步提交情况下,oracle会启动LGWR进程将该事务对应的redo log 数据全部写入 online redo log file。日志写入完成,提交完毕。如果是回滚事务,则从undo中从后往前反向修改buffer中数据。此时也产生redo信息。
用户A主动连接数据库,首先user process(up)向监听请求连接,监听收到 up 的请求后,根据连接串找到实例所在位置,通知实例有up发起连接,此时实例启动一个 server process(sp),将sp的地址告诉监听,监听将sp地址转发给up,up收到sp的地址后,直接和sp建立连接。
up和sp顺利建立连接后,就可以访问数据库,当us发起一个sql语句时,sp接收到up传过来的sql后,首先对这个sql进行语法检查、语义检查。这两项检查通过之后,开始对sql进行解析。
解析过程:对sql字符串进行hash运行,得到hash值 hashA,对 hashA再进行一次运算,得到sql执行计划所在链编号 chainB,然后sp遍历library cache 中链 chainB上是否存在 hash值为 hashA 的执行计划,如果存在,则拿出该执行计划直接执行,此为软解析。如果不存在,则调用cbo生成一系列执行方案,在众多执行方案中挑选出性能最优的作为执行计划。然后在free中选择出合适大小的buffer,将执行计划放进去之后,把这个buffer连接到library cache 的链 chainB上。也就是发生了硬解析。如果在free中没有找到大小刚好合适的buffer,就会查找比所需buffer大的buffer,然后分割出需要大小的buffer来存放执行计划。如果free中彻底没有所需要的buffer,则会覆盖library cache 中LRU链冷端的buffer,如果从library cache和 free中均找不到可用的块存放执行计划,则会抛出 ora-4031错误。
得到执行计划后,就根据执行计划的指示,执行sql,确定需要的数据所在内存块。sp首先到database buffer cache中查找是否全部所需数据都在buffer cache中,如果不是,则sp从存储在硬盘上的数据文件中读入所需数据行所在block。即发生了物理读,Oracle IO的最小单位是块。在发生物理IO时,首先查找buffer cache中是否有free状态的buffer,如果没有,则查找干净的buffer,如果还是没有,则sp触发ckpt执行增量检查点,将ckpt队列前端的部分脏块写回dbf。如果写入的脏块中有对应redo log未写入日志的,则会在DBWn开始写数据之前,触发LGWR将redo log写入online redo log file。如果online redo log 写满,则只能先切换日志才能继续写日志操作。在得到可以覆盖的buffer后,sp将所需block从dbf读入buffer cache。再从buffer cache返回PGA,即发生了内存读。
sp从buffer cache中读取一个buffer的数据时,会首先检查该buffer头部的事务槽中是否有未释放事务锁,如果有,则发生一致读。如果没有,则sp会进一步确定事务槽中事务对应的undo段段头块的事务表中该事务的的锁是否释放,如果不是,也发生一致读。如果是,则改写buffer头部事务槽信息。然后直接读该buffer,无需构造cr块。在读取的过程中,如果遇到行头中行锁未释放的情形,也会改行锁标记。在此过程中,改锁标记的动作引起了buffer的改变,将会在pga中产生redo log。
构造cr块的过程:如果sp在内存读时,检测到需要构造cr块,则会读取buffer头事务槽信息中的uba,根据uba的指引找到对应的undo块,读出undo块中的信息构造cr块。然后读取该cr块返回pga,如果构造 cr 块需要的信息,已经从undo 中挤出去了,那么构造cr块将会失败,此时抛出 ora-01555异常。
如果用户发出了一个dml语句,首先oracle会找到一个相对空闲的undo段,在undo段的段头块的事务表中插入一条事务信息,然后找到要修改的数据块,假设是 buffA,在数据块头的事务槽中填写该事务信息,并且在undo段中为该事务分配一个undo块。如果需要修改的数据块不在buffer cache中,则产生物理读将数据从dbf读入buffer cache。如果需要修改的数据块事务槽中记录了其它未提交的信息,则会到事务表中进行验证,如果该事务确实没有提交,则会等待该事务提交后,才会加锁。等到加锁完成后,开始修改buffA,首先将 buffA 中修改之前的数据复制到 undo块。然后覆盖修改。每次修改之前,都需要将buffA的数据事先复制到undo块中, 如果一个undo块不够用,将会申请一个新的undo块,新undo块的地址记录在前一个undo块的块头中。如果一个事务用了很多undo块,超过一个undo段大小,就会报错。
当用户结束修改,要提交事务时,在同步提交情况下,oracle会启动LGWR进程将该事务对应的redo log 数据全部写入 online redo log file。日志写入完成,提交完毕。如果是回滚事务,则从undo中从后往前反向修改buffer中数据。此时也产生redo信息。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/30168575/viewspace-1674560/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30168575/viewspace-1674560/