从内存存储、填充加载谈谈Oracle 12C IN-MEMORY的新特性(二)

周光晖
原创 1067       2018-03-01  
【RAC下的跨实例加载机制】
在12c的RAC环境下,Oracle默认将对象的列式存储信息分布式地条带地加载到所有节点的IMCU中。每个节点的数据不重复。通过横向扩展的方式充分利用所有节点的CPU和内存资源结合12C的并行发挥最大的性能提升。

对于数据是否应该在in memory area中保存冗余,如果是普通的RAC数据库,那么数据并不会在in memory area中保存冗余;而对于Exadata一体机,in memory area中的数据是可以设置冗余的。之所以选择这样做的原因在于,Oracle认为Exadata一体机的心跳性能能够得到保障。


另外,由于目前硬件层面的高可用技术已经非常成熟,一个数据库实例或者节点down掉的事故大部分都是在短时间内能恢复的。所以Oracle在发现某一个实例或者节点fail之后并不会马上触发数据的重新分布,而是会等待一段时间以便让问题节点或实例能够重新启动并加载自己的数据。

只有当等待时间超时之后,其他节点才会触发数据重新分布的过程,将失败节点的in memory area中的数据重新分布到正常节点。基于这种设计模式,建议在使用RAC系统上的in memory选项时应该为每个节点的in memory area预留出一部分空间,以便确保数据重新分配时仍然有足够的空间。如果空间不足以加载其他节点的数据到内存,那么分配到之前故障节点的数据则从健康节点的buffer cache来地读取,这会对性能产生一些影响。

在RAC环境下的,每个节点都不会包含表当中的所有数据。所以在RAC环境下,需要启用oracle的自动并行查询(AutoDOP)才能够使用in memory的方式访问加载到in memory area中的表。另外还要说明的是在多实例的并发查询中实例之间传输的并不是IMCU,而是每个节点都会对本节点的数据运行相同的sql语句,之后把自己的结果集发送给发起sql语句的实例,组成最终的结果返回给用户。所以这里不必过分担心并行查询带来太多的GC问题。需要注意在12.2 RAC中禁用跨实例并行实质上无法真正实现In-Memory。所以请保持PARALLEL_FORCE_LOCAL为默认值。且自动并行查询参数PARALLEL_DEGREE_POLICY修改为AUTO。




【INMEMORY下我们该如何处理索引】
索引在OLTP下的重要性不要再叙述了,很多应用都过合理地设计索引将性能提升了百倍是很常见的事情。但是在IM下索引并不能被使用。内存列式存储扫描的速度足够快,我们还需要索引吗?答案是肯定的。我们不然删除掉所有的索引,至少我们还需要主外键/唯一约束来保证数据的完整性。同时在OLTP中需要访问buffer cache对象时索引还是很重要的。如果每一笔事物都对表做全扫描,那么我们系统将会慢的无法想象。


对于索引的存在需要具体分析,报表对象上的索引可以做适当地删除。只保留必要的索引,多余的索引可以尝试删除掉观察性能。而且在索引量降低的情况下,我们可以提升对表的DML效率。



【使用12C INMEMORY特性优化案例】
业务特点分析
某客户的日志查询单次执行都要45s到60s不等的时间。从SQL的逻辑上来看就是对两张大表做全部扫描分别来自当前和历史的两张表。谓词条件中使用了大量的函数导致SQL的执行计划就是对两张表的全表扫描然后做JOIN。


执行耗时分析
执行耗时45s,耗时在CPU/IO wait/Cluster waits上的分别大概为2:1:1。由于11g的RAC数据是从buffer cache中获取的,所以GC争用显得有些严重。


将两张表加载到INMEMORY中
执行时间降低到1s出结果。虽然从两个节点的IMCU中获取数据,但是cache fusion并不明显。彻底消灭了物理IO瓶颈。

恒生技术之眼原创文章,未经授权禁止转载。详情见转载须知

联系我们

恒 生 技 术 之 眼