love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

Phone:18180207355 提供专业Oracle/MySQL/PostgreSQL数据恢复、性能优化、迁移升级、紧急救援等服务

关于lgwr 进程的一点思考

本站文章除注明转载外,均为本站原创: 转载自love wife love life —Roger的Oracle/MySQL/PostgreSQL数据恢复博客

本文链接地址: 关于lgwr 进程的一点思考

今天参加ACOUG活动,eygle大师分享了一个案例,其中讲到进程的strace时,问我某个字符是神马意思?
当时一时想不起了,他简单的进行了一下描述,猛然大悟,但是还不是特别清楚其中的细节,很多东西
确实是不用就会忘记的,晚上回来,准备研究eygle在活动上所提的lgwr 在写redo 时需要获得哪些latch?
具体这些latch的持有和释放的顺序是怎么样的? 做了一会儿实验,没有搞明白,突然trace lgwr进程,发现
了另外一点内容,彻底颠覆了我以前的认知。

我们来简单分析下上面的trace内容,首先pread64 这样的,是一个参数,可以看到时一些读的操作。
这个操作后面跟的第一个数字是表示文件描述符,你可以进行系统的/proc/fd下面去查看所有的的文件描述符信息,如下:

从上面我们可以看到,18~20 是我们的redo log,15~17 是controlfile。

下面是关于pread和pwrite 函数的描述:

从上面的strace信息我们可以得出如下的结论:

最后我们再回到问题上来,lgwr在写redo的过程中对latch的持有和释放顺序是怎么样的呢 ?
我们来看看10g中 redo 相关的latch有哪些,如下(10g不同版本有一些差异,主要是latch#有所
变化,redo相关latch都是一样的):
—for oracle 10205

我们可以看到,只有redo copy和redo redo allocation 这2个latch是存在子latch的,其中redo copy存在
2个child latch,redo allocation 存在19个child latch。
在jonathan lewis大师的oracle core一书中第137页,有提到,据他的描述是这样的一个顺序:

下面还有一段:

另外在Steve Adams 的http://www.ixora.com.au/tips/tuning/redo_latches.htm 也提到了,如下:

Steve Adams的描述其实跟jonathan lewis大师的描述差不多,这里就不多说了。最后一段Steve Adams大师还提到:一旦进程获得了
redo copy和redo allocation patch以后,也就意味着其对应的log buffer中的空间已经分配出来了,此时redo allocation latch
会被释放,与此同时change vectors会从PGA 的temporary buffers中copy到log buffer中。当然,最后再由lgwr进程将redo buffer
的redo record写入到redo logfile中去。

到这里自然有一个疑问产生了,是什么进程从pga 中去copy change vectors到log buffer中的? 难得是lgwr进程? 显示不是。

这其实还跟你的数据库是shared 还是专用模式有关系,显然我这里是通过sqlplus killdb/killdb 本地操作,那么就是专用模式了。

[ora10g@killdb udump]$ ps -ef|grep 32511
ora10g 32511 32510 0 00:09 ? 00:00:00 oracleroger (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
ora10g 2988 32177 0 01:41 pts/3 00:00:00 grep 32511

如果是专用模式的话,就是我们的user 进程来完成从pga temporary buffer 拷贝change vectors到log buffer的过程的。
上面 Steve Adams大师的这段话也说明了。

说明:如果你是shard 模式,那么说完成change vectors copy的工作是用Snnn进程来完成的。

关于latch,可以通过oradebug 来进行相关的测试,下面是我的一个基于10.2.0.2的测试:

—-for 10.2.0.2

下面用oradebug 离开手工持有redo copy 进行验证。

此时数据库实例可能会crash掉,oracle这里是不允许你即获得redo copy 父latch,同时又获得子latch的,
反过来也是一样的,同时该子latch也不能同时获得2个,那样是不允许的。但是这个时候实例不会crash。
只是会抛出相关错误,数据库仍然可以正常工作。错误如下:

所以,关于redo copy latch可以简单的总结如下几点:
1. redo copy 父latch和子latch 不能同时持有;
2. 在获得父latch后再去申请获得子latch或获得子latch后再去获得父latch都是不允许的;
3. 2个子latch也是不能同时持有的。

最后关于redo allocation 的子latch为什么那么多,我想是出于并发考虑。

备注:其中有部分关于其他进程的trace我去掉了,内容太多了,还有关于latch的持有和释放,可以通过
event 10005去观察,如下:
ora10g@killdb ~]$ oerr ora 10005
10005, 00000, “trace latch operations for debugging”
// *Document: NO
// *Cause:
// *Action: Enable tracing for various latch operations
// *Comment:
// level 1 – trace latch gets and frees
// level 4 – trace multiple posts by processes when latch is freed

We can set events 10005 (trace latch gets and frees) and 10073 (have PMON
dump info before latch cleanup). Level does not matter for these events.
We can also set event=”600 trace name LATCHES level 1″ to dump latch info
when PMON hits the error (I’m not so sure this one is going to work).

event = “600 trace name latches level 10”
event = “10005 trace name context forever, level 1”

10005 event has been removed above 9i , try dump KSTDUMPCURPROC 1

SQL> oradebug setmypid;
SQL> oradebug unlimit;
SQL> oradebug dump KSTDUMPCURPROC 1
SQL> oradebug tracefile_name;

One Response to “关于lgwr 进程的一点思考”

  1. 756714542 Says:

    勉强看懂一点点。。。。。。。。。

Leave a Reply

You must be logged in to post a comment.