加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 安全 > 正文

Oracle高并发系列1:DML引起的常见问题及优化思路

发布时间:2021-01-08 06:18:21 所属栏目:安全 来源:网络整理
导读:副标题#e# 《Oracle高并发系列1:DML引起的常见问题及优化思路》要点: 本文介绍了Oracle高并发系列1:DML引起的常见问题及优化思路,希望对您有用。如果有疑问,可以联系我们。 作者介绍 王鹏冲,平安科技数据库技术专家,浸淫数据库行业十多年,对Oracle数据
副标题[/!--empirenews.page--]

《Oracle高并发系列1:DML引起的常见问题及优化思路》要点:
本文介绍了Oracle高并发系列1:DML引起的常见问题及优化思路,希望对您有用。如果有疑问,可以联系我们。

作者介绍

王鹏冲,平安科技数据库技术专家,浸淫数据库行业十多年,对Oracle数据库有浓厚兴趣,也对MySQL、MongoDB、Redis等数据库有一定架构和运维经验,目前正沉迷在PostgreSQL数据库与Oracle数据库的PK之中,重点在关系型数据库的分布式架构研究.
引言

Oracle数据库是设计为一个高度共享的数据库,这里所说的“共享”,可以从数据库共享内存、后台进程、cursor、执行计划、latch等方面去理解.Oracle如此设计的目的是以最小的系统开销、最大化地支持更多的并发会话.也是基于这个设计思想,所以Oracle单个实例的垂直扩展能力一直是DB领域内的佼佼者.

之前曾经看到PG大牛的文章分析关于Oracle的CursorPin S为什么不会在PostgreSQL里面出现,其主要原因是PostgreSQL的执行计划不是全局共享的,而Oracle里面同样的Cursor在不同session间一般情况下都是可以共享的(Oracle在某些条件下会也触发重新硬解析).这样的设计客观来讲其实各有优劣,虽然PG的plan cache是不同会话不共享的,避免了高并发时不同会话对同一个cursor产生争用,但是也意味着同样的并发会话数的情况下,PG的会话所需求的cache会更多,而且每个会话都至少要parse一次;或者反过来说同样的资源限制的前提下,Oracle支持的并发数更高.

引用一位Oracle 7的OCP,资深Oracle老司机的一段话:“早期Oracle就是使用session私有内存,但当负载并发增加时,内存消耗成了问题,而且执行计划无法共享,增加率parse时间,对于OLTP系统parse时间的增加对于整体执行时间影响较大.因此Oracle基于这一点进行了优化,包括session cached cursor和shared pool等,减少了SQL执行过程中的parsing time和planning time.但没有免费的午餐,肯定会有其它消耗,类似内存结构的并发保护上的成本.总之:

  1. session级SQL解析是Oracle最开始采用过的技术.
  2. 任何应用都要针对其所采用的数据库的特点进行好的设计.

这里不探讨哪个数据库更NB,每种数据库技术的发展会受多种因素的影响,包括商业战略、市场需求、软硬件技术成熟度等.我们采用Oracle多年,对于Oracle数据库有深厚的感情,但是目前也同时义无反顾地投入开源数据库和NoSQL的怀抱,技术无好坏,最适合应用场景的就是最好的.这里只重点探讨,当Oracle数据库的这些“共享”资源,遭遇高并发时的问题发生的原因和应对措施.

这里谈的是思路,不是具体的命令.

这里的处理方法,是基于过往发生过的实际案例总结而来.

高并发的DML引发的问题

Oracle的表是堆表,索引是B树,当对表做DML时,Oracle会对table的block进行操作,同时也对索引树的block进行维护,那么当同一时间有大量会话都需要对索引(或表)的同一个block做维护时,就会产生索引(或表)上面的争用.当出现争用时,v$session_wait显示了当前的会话正在等待的event name.

1、enq: TX – allocate ITL entry

这个等待事件表明,当前的会话正在等待一个block上面的事务槽的分配,可能是table block或index block.

可能的原因有:

  • Initial trans设置过小.
  • 并发DML太高,ITL slot被其它会话占用还未释放、且该block上也无空闲空间可以增加新的ITL slot,故当暂无free的ITLslot可供使用,后续的会话只能等待.
  • 设置合理,并发也不是非常高,但是正在运行的语句效率发生了变化,导致hold ITL的时间变长,进而引发了后续的拥堵.

解决思路:

  • 已有的索引,进行Rebuild,重建时增加initrans,比如从16->32->64(重建索引时若加大pct free,只是刚重建完毕为每个block预留了更多空闲空间,但是随着后续索引的维护这些空闲空间有可能还会被占用).
  • 新建的索引,修改数据库开发规范,新建索引时默认initrans为16;
  • Table block一般很少出现上述问题,但是生产过程中我们的一个非常高频update的table也遇到过此问题,所以最后也修改了规范新建表时默认指定initrans为6.
  • 如果确认是sql语句效率下降导致hold ITL时间变长,那么分析sql效率下降的原因并优化.

小知识点:

在v$lock中若看到某个会话正request一个lmode为4的锁,其原因之一就可能是ITL等待造成的,其它原因可能是并发操作主键、位图索引、分布式事务等.

2、enq: TX – index contention

这个问题一般发生在表在高并发insert操作时,等待在字段类型是日期、自增序列的索引block上.因为应用始终插入的都是最新(high key)的值,导致这些索引一般都是右倾斜增长的,也就是说最近最频繁的操作都发生在索引最右边的那个叶子块上,叶子块的free空间很快被填满,然后叶子块要分裂,分裂过程总要去找free block,index spliter的进程会持有一个enq:TX锁,其它并发insert的进程一般也正是需往最右边的这个index leaf block去insert数据,所以都要等待这个spliter进程完成并释放这个锁.(竞争更加激烈时,甚至会在branch block的split时产生)

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读