如何理解redo的内部过程与lgwr

网友投稿 212 2023-12-28

如何理解redo的内部过程与lgwr

如何理解redo的内部过程与lgwr,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

如何理解redo的内部过程与lgwr

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

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:jq设置多个class?
下一篇:前端面试遇到的项目难点(前端面试项目中遇到的难点)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~