由SQL语句执行过程触发对Oracle体系结构的思考

 

1.首先打开游标(内存指针),

2.语法检查:来了一条update语句首先你要看这条语句是不是SQL语句也就是先对他进行语法分析,语法分析是在share pool的库缓存去中,并在此存储起来,

3.语义检查:语法没问题后,要检验它所涉及的表、索引、以及权限等数据库对象及相关属性是否正确 ,也就是语义检查,是在share pool 的数据字典缓存区中进行,

4.查harsh值,这个过程是在share pool的库缓存区进行的,如果有相同的执行计划存在,则直接调用即可这样就是软解析,否则还要进行硬解析,也就是新生成执行计划,硬解析很消耗资源。

5,有了执行计划后,就该着执行了。

6.处理结果。

7.关闭游标

看似简单的流程里面  有很多值得思考的地方。

1)如果是select 语句 ,服务器进程首先会在database buffer cache 中查看是否有要查询的数据块,如果有则直接在缓存区中查到结果并返回给用户,如果没有,服务器进程会从底层数据文件中把要查询的数据所在的块复制到数据库高速缓存区缓存中,然后再按上述步骤进行查询并返回结果。

2)还涉及到如果缓存区中没有可用的空间了(数据库缓存区中的数据块有四种状态,1脏快—就是被修改过且与底层数据文件的块不一致,也没有被刷新到数据文件的块,2.干净块—也是被修改过的块,但是已经被刷新到了数据文件中,此块是可以被使用的,再来了直接覆写就可以了,3.free 块 —这是还没有被使用过的,当然可以被使用了4.pin块就是正在被使用的块,上面有锁。不能被使用。),这是你就不能把想要查询的数据块复制到缓存区,只能等待。。这种情况就会触发DBWn进程去写缓存区中的脏块,以便腾出块来用。

3)那么还有什么会触发DBWn进程写呢,主要有这几种1.缓存区中的脏快已经达到极限值(1/4满)2.遇到检查点时,3.设置表空间离线(暂时不受数据库管理控制)这是因为既然你都不让数据库控制了,那你得保证在离线时,缓存区中没有与数据文件不一致的块,有的话你就得刷新出来。3.热备份开始的时候。可以这样理解:备份目的就是以便恢复,那你肯定是想要备份一份一致性的数据,如果缓存区中有不一样的,肯定会刷新出来。

4)那又有问题了,既然1/4满时,就会触发dbwn写进程,那么还提数据库缓存区高速缓存满的情况干什么啊,它还能满? 原因是这样的虽然你在1/4满时已经开始刷新脏快,但是同时也会有新的脏快在产生,写脏快的速度不一定比产生的速度快。。。

5)上面还提到了遇到检查点也会触发DBWn进程,那什么是检查点呢?这就涉及到了另一个后台进程CKPT(检查点进程)它的作用:1.给DBWn进程信号,触发它去刷新脏快,2.看dbwn 写了多少脏快了 并把此信息记录到控制文件,更新数据文件头scn号,更新控制文件的scn 号,发一次检查点,就会使数据库到达一致性状态(就是数据文件头的scn,控制文件中记录数据文件的头的scn,以及控制文件有个总的scn,这三个scn号一样)应该注意的是真正建立检查点的主要是DBWn进程,CKPT只是更新数据文件的文件头,以辅助真正建立检查点的的进程(DBWn)——167编程艺术

5)那么什么是scn—系统变更号   其实你可以把它理解为就是记录数据库变化的一个时钟,它是不断增长不能减少的(就像你不能回到过去一样),而且是不能被命令给修改的(bbed是另一种情况),scn号用于保证数据库的读一致性和检查点,每次commit 都会加1.

6)上面说了select 语句的一些事情,那么update语句呢,首先服务器进程也会看缓存区中有没有要修改的块,然后处理过程和select 类似,假如已经修改了块儿,但是还没有commit,这会面临一些问题,首先,你用修改这个块的用户查它是修改后的值,这时候如果你用另一个用户查询这个块,它返回的是修改之前的数据,例如你把x=10改成了x=100,但是没有提交,你去查询时,它返回x=10,那他是怎么实现的呢,其实是在改之前会把当时的值放在under表空间中(这个过程是服务器进程完成的)——以便于你回滚,因为Oracle会保证一致性读,所以会读取修改前的值,因为有锁,另一个用户是无法使用这个块的,所以他会重新复制块到缓存区。Commit之后无论是谁查都是修改后的值了。(一定注意此时缓存区的脏快不一定被刷新出来了,因为commit 不会触发DBWn进程刷新脏块,这一点好多人误解)

7)既然commit之前与之后差距这么大,那commit  到底做了什么呢?311(摘自编程艺术)

COMMIT是一个非常快的操作,当我们发布commit命令时,真正困难的动作已经完成,在数据库中已经执行了数据更改,所以已经完成了99%的任务。

例如:下列操作已经产生: 

 1. 在SGA(Buffer Cache)中已经生成了undo块;

 2.在SGA(Buffer Cache)中已经生成了产生改变的数据块和索引块;

 3.在REDO LOG BUFFER生成了前面两项的redo信息;

 4.buffer中的数据可能已经有一部分输出到了磁盘;(依赖于前三项产生的数据量大小以及操作需要的时间)   

 5.所有需要的锁已经获得;     

 当执行COMMIT命令时,只执行如下操作:     

 1.为事务生成SCN:SCN是ORACLE数据库的一种计时信息,用以保证事务的顺序性,

同时还用于失败恢复和保证数据库的读一致性和检查点,无论何时何人提交,SCN自动加1;

 2.将事务相关的未写入redo log file中的redo信息从redo log buffer写入到redo log file,这才是真实的COMMIT,这步操作完成,说明我们已经完成COMMIT,事务从V$TRANSACTION中移除;

 3.V$LOCK中记录的SESSION关于该事务锁,这些锁会被释放,其他需要这些锁的事务被唤醒;

 4.执行块清理,——清除存储在数据块的首部的与锁有关的信息,

8)已经知道了commit 所做的事情了,那么考虑一下是频繁提交好还是批量提交好呢?

频繁的COMMIT会引起大量Redo Log的物理I/O,会极大的限制数据库的性能 
因此,为提高数据库性能,尽可能的批量提交,

9)前面提到redo log buffer 中的信息写入到redo log file,那么redo log file 是个什么东西呢?它实际上是记录着对数据库的所有修改,以防止数据的丢失,对数据库来说非常重要,

便于安全的考虑,联机重做日志文件至少分两个组,一个组来记录新的日志文件,另一个组来归档。这样满足写机制,1.循环覆写,2.写满切换日志组,3.也可以手工切换日志组:alter system switch log file; 那么你自然会想到是谁干写了这件事,

这是LGWR进程完成的操作,触发它写的条件有:1.任何用户commit的时候,2.当redo log buffer中的日志有1/3满时,3.有1M的日志时,4.在DBWn写之前,5.每三秒写一次

11)上面说到归档--可以理解为对联机重做日志的复制,有了归档你就能保证数据永远都不会丢失,是ARCn进程完成此操作的, 但重做日志文件切换组的时候(假如有两个日志组),如果另一个还没有完成归档,这样会出问题,数据库夯住。。。

12)pmon (进程检测进程) :当会话异常终止时 清除失败的进程 包括 回滚事务、释放锁,动态注册监听器。

13)Smon (系统检测进程):实例恢复(前滚所有重做日志中的改变、回滚没有提交的事务),释放临时表空间。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29654823/viewspace-1248127/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29654823/viewspace-1248127/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值