数据库管理-第八十三期 炒点冷饭(20230620)

第八十三期 抄点冷饭

上周,借着剩余的两天年假,又从300多个小时中拿了3天出来,加上前后两个周末,去泰国完了一圈,整体还是很爽的,这里分享一些照片,具体游记后面详见公众号:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1 ORA-04031

ORA-04031: unable to allocate xx bytes of shared memory(“xxx”,“xxx”,“xxx”,“xxx”),是一个Oracle数据库中比较典型的报错,从报错的字面意思就能很好理解,数据库语句执行无法从SGA的shared pool中获取需要的内存,大多数情况只会偶发出现(毕竟硬件资源是有限的);但是我也遇到过一直触发,语句无法执行的情况,这一般就涉及BUG、配置错误等原因了。

2 Shared Pool

只要是影响语句的报错,我们都应该尽量避免出现,毕竟你不知道那些开发有没有做好失败重试机制,更有甚者一个报错会拖垮整个应用。但从4031这个报错来看,就需要回过头看看Shared Pool到底是用来干什么的:
在这里插入图片描述
首先Shared Pool是SGA中的一个组成部分,无论是基于自动管理还是手动管理,在SGA中都需要考虑与其他组件之间的关系,尤其是与Buffer Cache之间的关系(毕竟更多的数据刷到内存性能相对更好)。
在这里插入图片描述

  • Library Cache
    是一种共享内存结构,用于存放可执行的SQL和PL/SQL代码。简单点来说,SQL执行的时候会尝试使用以前执行过的信息,诸如已解析的SQL、SQL执行计划、解析过和编译过的PL/SQL程序单元等信息就存放在这里。
  • Data Dictionary Cache
    是存放数据库元数据的地方,比如表或视图的结构和用户信息。
  • Server Result Cache
    用于存放SQL执行结果和PL/SQL函数结果缓存。

其他Shared Pool中的组件就不太重要了。在Shared Pool中其实Library Cache往往是占用内存空间最大的地方,那么控制Library Cache大小就是减少出现4031的重要手段。

3 Library Cache

无论是Shared SQL Area还是Private SQL Area,里面存放的都是已解析的SQL、SQL执行计划、解析过和编译过的PL/SQL程序单元等信息。减少Library Cache中记录的SQL信息就可以极大减少内存空间占用,从一般优化建议来看就是使用绑定变量来减少:

SQL1:
select * from daily_sales where shipped_from='WAREHOUSE1';
SQL2:
select * from daily_sales where shipped_from='WAREHOUSE2';

SQL3:
select * from daily_sales where shipped_from=:A;

对于数据库来说,SQL1和SQL2不是一条语句,在Library Cache用会生成两条SQL信息,且不同语句之间无法复用执行计划会产生硬解析,这样不仅增大了内存占用,也增加了内存消耗。如果将shipped_from的匹配内容像SQL3那样传入变量A中,那么在Library Cache中就只会生成一条信息,也可以很方便的复用执行计划。
当然还有一些看似完全一样的操作也会增加占用:

SQL4:
create table x1 (id number,name varchar2(20));

drop table x2 [purge];

SQL5:
create table x1 (id number,name varchar2(20));

SQL4和SQL5语句完全一样,但是因为对应表的object_id产生了变化,在Library Cache中也会生成不同version的信息,增加占用。我这里处理过的一个业务就是因为每天大量的此类操作,导致自动管理的SGA,总计120GB,db cache被shared pool积压到了不足5GB,要不是因为是Exadata,可能早卡崩了。

4 Doc ID 2590172.1

ORA-04031 on Multitenant Database with Excessive Amounts of KGLH0 and / or SQLA Memory and Parameter SHARED_POOL_SIZE or SGA_MIN_SIZE Set at the PDB Level
在这里插入图片描述
在第二十二期的时候我是遇到过这个问题的,莫名其妙报4031,就是因为在PDB内设置了shared_pool_size和sga_min_size,遇到了只能通过下面命令处理:

alter system flush shared_pool;

由于PDB只有2个,后面就通过在CDB层面控制db_cache_size和shared_pool_size处理该问题。

5 Bug 34832725

[SHRD CRSRS] ORA-4031 and / or High Shared Pool Latch Contention During Session Creation in 19.11 and Above
在这里插入图片描述
在这里插入图片描述
这也是一个经常出发4031的一个BUG,之前在一个省的一体机上的19.17触发了并且查了很久,我这里的19.16和19.17上并没有触发,从后台反馈来看主要涉及19.15和19.17两个版本。现在的处理方法要么是flush shared_pool,要么打one-off patch和升级到19.18、19.19的修复版本或19.20。

总结

休假回来整体浑浑噩噩的,这一期实际上还算是炒第二十二期的冷饭。
老规矩,知道写了些啥。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖头鱼的鱼缸(尹海文)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值