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写磁盘是批量顺序写,速度快。但数据块很多是更新的,在众多数据块中找到并更新,想想这个时间都比顺序写慢很多。