如何理解redo的内部过程与lgwr,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
创新互联从2013年成立,是专业互联网技术服务公司,拥有项目网站建设、成都网站制作网站策划,项目实施与项目整合能力。我们以让每一个梦想脱颖而出为使命,1280元包头做网站,已为上家服务,为包头各地企业和个人服务,联系电话:13518219792
Oracle采用混合日志记录模式,以数据块为单位,即dba + sql,即避免记录整个块,又可快速恢复
the granularity is at the block level (like physical logging), so one operation is stored for each individual block change
一个大事务可由多个mini-transaction即redo record组成,而每个record又可由多个change vector组成;commit/rollback单独对应1个redo record;
每个redo record包含1个原子操作,1个change vector仅对应1个数据块,change vector在实际修改块之前生成;
事务提交时,将生成的redo+undo和commit record写入重做日志文件,同时更新rollback segment header的事务表;
注:临时表只记录undo
Redo有3种latch
1 Copy,可通过_LOG_SIMULTANEOUS_COPIES设置多个
2 Allocation 只有1个
3 Write 只有1个
REDO的生成
Redo先在PGA中生成,依次获取copy latch--allocation latch,将redo写入log buffer后再修改块,Lgwr在刷新redo buffer时获取write latch,避免同时多次刷新;
具体步骤如下
1 以排他模式pin住buffer block
2 在PGA中构建change vector并组合成redo record,由kconew()/kcoadd()完成
3 调用kcrfwr()将record写入log buffer:
计算record占用的空间大小;
分配SCN;
获取copy latch,验证SCN;
获取allocation latch,检验log buffer/file是否有足够空间,有则释放allocation latch将redo写入log buffer,否则同时释放allocation/copy latch并通知LGWR进行log flush/switch;
注:为防止多个进程同时通知LGWR刷新redo或切换日志文件,引入write latch(只有1个),只有获取此latch后才能进行下一步操作;
4 将redo record写至log buffer而后释放copy latch,检查是否达到触发LGWR阈值;
5 更改buffer block
nologging
此模式下仍记录redo record,其下的change vector类型均为INVALID;每个record可对应多个数据块,应用该redo时相应数据块将被标识为soft-corrupt;
LGWR触发阈值
1 由前台进程触发:log buffer空间不足;事务提交
2 log buffer满1/3
3 redo超过1M
4 3秒超时
5 日志切换
6 redo线程关闭
LGWR触发过程
1 获取write/allocation latch,前者防止LGWR被多次请求,后者防止为前台进程继续分配redo空间
2 确定待写的log buffer范围(从起始处至待刷新的buffer),分配新SCN(避免两次flush使用同一个SCN)
3 释放allocation latch
4 计算所需redo write次数,因为log buffer为环形,故至多写两次(分布于头尾)
5计算target RBA,依据log_checkpoint_interval增进增量检查点
6 释放write latch
7 确保待写的log buffer都复制完毕,即等待所有copy latch释放
8 LGWR更新redo block header的SCN和checksum(可选)
9 执行磁盘写,可修改_lgwr_async_io启用异步IO
组提交
Lgwr在c1处接到请求,开始刷新log buffer时新增了c2/g1/c3,此时需等待c3写完(释放redo copy latch)后,连同c3一起刷新,
常见的redo等待事件
log file parallel write-由lgwr触发,将redo record写入当前log文件,其并行度由物理磁盘数决定
log file sync-由前台进程等待,从commit/rollback直到lgwr将日志写入磁盘并通知请求进程为止
log buffer space- log buffer中没有足够空间存放新生成的redo,说明lgwr写出速度较redo生成慢
log file switch-分为checkpoint incomplete和archiving needed
Log file sync流程
lgwr会post哪些前台进程?
当lgwr刷新完日志后,会post相应的前台进程(wakeup)继续工作,那么lgwr怎么判断应该wakeup哪些前台进程呢?
log file sync等待的p1参数的含义为:P1 = buffer# in log buffer that needs to be flushed
当lgwr刷新完buffer后,会扫描活跃会话列表,查看哪些会话在等待log file sync,而且会话的buffer#小于等于它所刷新的log buffer的最大值,这些会话会被wakeup。
Lgwr file sync与buffer busy wait
事务commit的stack call如下
为ktcCommitTxn=> ktucmt => kcbchg => kcbchg1_main => kcrfw_redo_gen => kcrf_commit_force
kcbchg==> block change ,为什么要发生block change呢? 因为commit需要对在Buffer Cache里的block做immediate block cleanout,期间需要排他模式pin;
若此时其他会话访问该块则会等待buffer busy wait
http://www.askmaclean.com/archives/why-slow-redo-write-cause-buffer-busy-wait.html
归档日志流程
1 ARCH读取控制文件以决定待归档的日志文件
2 分配归档内存_LOG_ARCHIVE_BUFFERS * _LOG_ARCHIVE_BUFFER_SIZE;
3 以只读方式打开待归档日志组的所有成员(以轮循方式依次读取log buffer),并验证log file header;如果db_block_checksum=true每个log block还将验证checksum
4 创建并打开归档日志文件
5 以循环方式将日志从online log复制到archive log,对每个buffer都执行sanity check
执行完毕后关闭online log和archive log
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。