近期,某用户在进行SQL优化时,通过sqlplus的set autotrace on命令跟踪SQL执行情况时,发现这条SELECT命令竟然也产生了REDO日志;与我们通常理解的DML/DDL语句才产生REDO日志的认识存在差异~
对ORACLE数据库的特性了解比较清楚的话,特别是数据块、事务处理方面有较深入学习理解,会知道ORACLE数据库的事务、数据块中ITL事务槽的一些原理、结构信息;会知道一个概念叫“延迟块清除”--delayed block cleanout,在约9年前我在学习了解这一块知识时,对相关概念原理进行总结并进行了测试,可以查看当时的BLOG:关于延迟块清除的概念及实验_还不算晕的博客-CSDN博客
简单说就是:
在大事务时可能会操作很多数据块;而BUFFER CACHE中被修改的脏数据写入数据文件中的时机不是COMMIT而是DBWR按规则进行的;所以存在事务相关的数据块先被刷出了 buffer cache,而此时COMMIT还未执行。
当本次事务COMMIT提交后,事务相关的data block ,undo block 上的事务信息,锁信息不会被清除。 当下一次数据块读取到buffer cache(可能是SELECT读取或其它DML), oracle在读取这类数据块时作事务信息、锁信息的清除处理。
Statistics
----------------------------------------------------------
105 recursive calls
0 db block gets
1343685 consistent gets
550158 physical reads
28532 redo size ====>>>> SELECT时产生的REDO
2940 bytes sent via SQL*Net to client
520 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
11 sorts (memory)
0 sorts (disk)
15 rows processed
|