SQL语句的结果如何反映在SGA与磁盘中

上面插入语句的执行过程如下:
1、在library buffer中找到该语句则直接调用
否则:
a)检查语法
b)检查权限
c)生成查询计划
d)存于library buffer,下次直接从中获取

2、写入数据到redo buffer、data buffer内存块中

3、此时数据都还只是存于内存,跟磁盘还没关系

下列情况会直接触发LGWR进程将redo buffer中的脏块写入redo log

1、commit;
2、每隔3秒
3、redo buffer内容超其容量的1/3
4、redo buffer内容大于M

下列情况会触发检查点,会由ckpt通知LGWR与DBWR将对应的buffer写入磁盘,

4、手动归档
5、数据库正常关闭
6、日志切换时的自动归档


oracle在将数据写入磁盘前,先写redo与uodo,data是在最后才写入 redo buffer -> redo log - >uodo log -> data block
因为redo与data由不同进程写,导致redo、data、控制文件记录的信息会不同步,检查点作为一个数据库事件,负责同步以上内容的一致性

先大概整理一下redo buffer与redo log,data buffer与data file的交互过程

redo log --重做日志
先确定一点,只有commit;才能体现用户想把数据保存的意图,以commit为分割点可能更好理解点

commit会直接触发LGDR将redo buffer
中的脏块写入到redo log

但按oracle的机制,除了用户显式commit,还有下列情况会写到redo log
1: 每3秒
2: 内容超容量1/3
3: 内容超过1M
4: 其他检查点的发生

也就是说所有数据的更改,无论commit与否都会被写到redo log中。

data file--数据文件
由data buffer写入data file的原理与redolog一样,无论commit与否都有可能会被写到data file中。但在写到data file之前
会将原data blocks放到undo file中。

oracle会保证写到data file之前必先写到redo file,也能保证写到data file之前会将原数据放到undo file中
redo log file -> uodo file -> data file

如oralce非正常关闭,再打开数据库时会根据控制文件的信息:
1、将redo log file中已经commit但未写入到data file的重演一遍(前滚)
2、将redo log file中未commit但已经写入到data file的撤消(后滚),即将uodo file中的旧块还原至data中对应的内容
3、这样前滚+后滚就保证了数据是非正常关闭前一刻的最新数据

redo意义
redo存在的意义就在于出现意外时,能让未写入磁盘的操作重现,以保持数据一致性,如果数据库永远都不会
出问题,那redo其实是没有意义的,但这没人可以保证

那既然redo也会很快写入到磁盘,不何为直接将数据写入磁盘?
个人认为可能是因为从redo buffer写磁盘是批量顺序写,速度快。但数据块很多是更新的,在众多数据块中找到并更新,想想这个时间都比顺序写慢很多。

原文地址:https://www.cnblogs.com/doclaim/p/3145277.html