★
19c shared pool 知识点分享
★
不知道各位神探有没有发现,19c其实和11g以及之前的版本发生了很多大的变化,Oracle的内核很多关键的模块都重新改写,比如cache fusion层,解析层,都和以前有了较大的改进。19c在带领大家买入新的架构体系的同时,很多知识点也需要相应的更新。今天由重案组重庆的资深探长李捷为大家带来一篇关于19c解析层的案例分享。
最近重案组李探长在支持一套核心系统数据库迁移,原环境为11.2 on HPIA,新环境采用19c multetent database on Exadata X8M,补丁集安装RU 19.11.0。在使用OTEST进行“高并发事务”场景压测时(主要操作为insert+update),发现事务数压不上去,每实例大约仅2000/s,检查AWR报告时发现异常:
(PS: 王探长在2019年初实施19.5的时候也遇到1个29XXXXX开头的row cache mutex相关bug,也是研发及时发布的补丁,版本更迭期间总是会遇到一些问题,核心生产库更需要注意)

“row cache mutex“等待占到整个数据库db time的35.6%。
Row cache mutex是数据字典缓存(row cache)中的内存锁,当多个进程访问row cache中的同一对象时,需要先获得这个对象上的mutex,才能进行访问(包括修改)。Mutex以串行方式控制进程访问对象,当一个进程hold mutex,其他访问相同mutex的进程则需要等待,直到mutex释放。Mutex作为light-weight内存锁,get和release非常快(纳秒级),但这里出现严重“row cache mutex“等待,则说明进程持有mutex时间过长,造成大量申请相同mutex的进程等待。
Row cache mutex发生过度等待的主要后果,是消耗掉大量的CPU,严重时会造成数据库HANG。这是所有内存锁争用(latch & mutex)的共同特点,

国内重要客户中已出现多起因“row cache mutex”等待造成的重要故障,基本都发生在从11gR2升级到12.2或19c,并且在上线后很快出现。OTEST作为专业的ORACLE数据库压力测试工具,可以针对性的模拟出各类负荷场景,使得在核心系统上线前发现该隐患,
Row cache缓存多种类型的数据对象,包括table、tablespace、segment、user、constraints。。。等等,访问每个对象都需要获取mutex,针对这个case,首先需要定位到争用出现在哪个类别上。观察AWR报告的“Dictionary cache stats“,

可以看到对”dc_users“类对象的请求次数非常高,观察mutex sleep,

Mutex的阻塞点(choke point)位于代码[19] kqrpre。测试环境相对单一,使用单个账号进行长连接测试,对其下数百张表DML操作,dc_users上出现等待大概率为BUG。结合short stack,搜索MOS,初步推断同Bug 31933451 - High row Cache Mutex Waits有关,开SR后ORACLE GCS确定命中该BUG,19.11.0补丁集未修复,48小时后我们获得overlay 19.11.0的补丁(体现了ORACLE DEV的高效率)。
安装补丁后,做相同场景测试,

可以看到row cache mutex等待已消除。

CPU压力显著下降,并发事务数提升到10442/s。

上线前的隐患消除了,客户的核心系统的稳定性得到了保障。
ACS 保护你的核心数据
接下来探究一下row cache mutex的特点。
#Mutex溯源
分析
Mutex和Latch都是ORACLE共享内存锁机制。latch和mutex的区别在于:latch是独立的结构,可以同时保护多个内存对象,
比如大家熟悉的library cache latch:

一个Latch可以保护多个library cache handle,以至多个library cache bucket。因为Latch控制的对象太多,所以高并发场景下很容易产生latch争用。
Mutex不是一个独立结构,它嵌入到一个内存对象中(每个内存对象包含了Mutex结构体),所以mutex是用来保护一个具体的内存对象。从11g开始,逐步用library cache mutex代替library cache latch,:

Mutex结构轻巧(几十字节),数量要远远多于Latch,使得进程对内存锁的请求更加分散,显著降低了争用。
从12.2开始, row cache上共享内存锁机制发生了改变,采用row cache mutex代替了row cache object latch,所以11g上的等待事件latch: row cache objects,19c上对应到row cache mutex。
使用row cache object latch,一个latch保护一类对象,查询可以看到:
使用row cache mutex保护的则是一个具体对象:

和library cache mutex取代library cache latch类似的原理,row cache mutex也实现分散访问请求,显著降低内存锁争用的目的。
Mutex的处理机制比Latch更优越,绝大多数场景下,会带来数据库性能的提升,但新
技术的引入会有一个成熟期。Row cache mutex等待引起的数据库性能问题,多数是由于bug导致,比如文章开头的这个CASE,
“当row cache某个对象被非常频繁地访问时,为了减轻row cache mutex争用,引起了hot clone object机制。根据进程mutex gets失败进入sleep的次数,超过阈值(default 500),则将该对象设置为hot object,会将为其常见多个hot copy,挂载到hot hash chain下。进程尝试获取”hot object“的mutexs时使用nowait,即如果获取失败,即刻尝试获取下一个hot copy的mutex。hot clone object机制有效地减低了高频次访问对象上的mutex争用。这个Bug是因为大量对象被异常识别为hot object,产生了数量异常庞大的hot copies,带来了新的问题。当升级19c RU patch时,建议安装相应的overlay 补丁已发布。”
针对不同的row cache类型(如dc_segments、db_props等),也存在其他的bug,ORACLE基本都能快速发布补丁予修复;个别情况是由于row cache mutex机制引起,目前也有合理的处理措施。
以上就是对”row cache mutex“所做的一些分析,感谢大家关注”西区重案实录“,欢迎在此发表ORACLE各类技术问题。
附录:otest的最新下载链接
https://152.67.211.126:8443/ords/otest/r/113/files/static/v41/otesttool20220630.zip