美文网首页
记一次Oracle大表添加带默认值列带来的灾难性性能故障

记一次Oracle大表添加带默认值列带来的灾难性性能故障

作者: judeshawn | 来源:发表于2019-08-05 19:37 被阅读0次

故障排查


业务人员反映数据库无法使用,故障现象及排查过程如下:

  • 登陆进数据库服务器执行uptime发现负载高达400
  • select * from v$session_longops where sofar<>totalwork;无记录,排除大表全表扫描或hash关联和RMAN备份等原因
  • select * from v$lock where type like 'TX';发现数据库大量会话锁定时间长达4000s
  • 分析AWR报告
    TOP等待事件
    顶级等待事件为cursor:pin S wait on Xlibrary cache lock,library cache是共享池(shared pool)中主要负责缓存SQL语句及其被解析生成的执行计划,解析分硬解析和软解析,硬解析是新生成执行计划然后存入library cache,软解析是library cache中已缓存该SQL执行计划(SQL文本相同,已经解析过,缓存未被清空)。
实例效率百分比统计

SQL解析大多数在等待,实际解析时间仅5%,SQL解析出现严重等待的原因往往和DDL语句有关,DDL语句在更改某个对象(通常是表)的结构的过程中,这个对象是无法使用的,如果是表,则无法查询,实际上就是无法解析SQL。

TOP SQL 异常SQL定位
最终发现是一条来自于PLSQL的alter table MR_ORDERS add execute_count NUMBER default 0;添加表同时赋默认值。

检查表大小发现表大约14G

select bytes/1024/1024,segment_name from dba_segments 
where segment_name like 'MR_ORDERS' and owner like 'BV';
BYTES/1024/1024 SEGMENT_NAME                                                                     
--------------- ---------------------------------------------------------------------------------
          14372 MR_ORDERS                                                                        

稍微有经验的DBA都知道,加列的同时给表列赋默认值实际上就是一个全表的UPDATE,只不过会给表加DDL锁(SQL解析需等待锁释放,从而无法查询)。对于大表来说,加列的同时赋默认值,相当于给一个庞大的DML事务加了个DDL锁,对业务繁忙的生产系统来说,无疑是毁灭性的性能灾难。

解决方案:

先杀掉DDL语句
select 'alter system kill session '''||sid||','||serial#||'''; ' from v$session where sql_id like 'fqhxcjtkbhvrn';

再杀掉其他大量等待的SQL(这里方便起见,按照SQL数据量进行了排序,先批量删最多的)
select count(*),sql_id from v$session group by sql_id order by 1 desc;
select 'alter system kill session '''||sid||','||serial#||'''; ' from v$session where sql_id like 'XXX';

温馨提示:
删之前最好检查一下SQL,以免误删
select * from v$sql where sql_id like 'XXX';

相关文章

  • 记一次Oracle大表添加带默认值列带来的灾难性性能故障

    故障排查 业务人员反映数据库无法使用,故障现象及排查过程如下: 登陆进数据库服务器执行uptime发现负载高达40...

  • insert

    插入多行数据 oracle 如果在创建表的时候设定了列的默认值,那么可以在insert时使用默认值进行插入数据 两...

  • 汽车爆胎前有什么征兆?90%的人都不知道

    车辆行驶过程中如果轮胎出现故障,带来的后果将是灾难性的。而当你清楚地了解自己的车轮胎是否变形、性能是否下降的状况,...

  • oracle数据库表信息查询操作

    随机获取oracle数据库数据量 查看oracle数据库的所有表 查看某个表的字段和类型,默认值,字段注释 查看某...

  • Oracle常见表操作

    Oracle表常见操作如下。 列规范创建表 要创建标准的表,可以使用下面的语法: ...

  • Oracle数据类型及表管理

    Oracle 数据类型 创建表时,必须为各个列指定数据类型 以下是 Oracle 数据类型的类别: Oracle主...

  • Oracle实现自增方式:序列+触发器

    Oracle不能像MySQL那样设置主键自增,Oracle用 <序列+触发器>的方式使数据表的一列或多列实现自增 ...

  • 7天玩转oracle笔记2-表的管理

    7.oracle表的管理 1.表和列的命名规范 必须字母开头 长度小于30字符 不能用oracle保留字 只能使用...

  • SQL的约束_DEFAULT

    1 使用场景在创建数据表时,给某一列赋予一个默认值。当有 DEFAULT 约束的列,插入数据为空时,将使用该默认值...

  • 千万级数据更新

    ORACLE千万级单表数据更新 更新场景是,千万级的单表数据,以列2更新列1 方法一:写最简单的update语句 ...

网友评论

      本文标题:记一次Oracle大表添加带默认值列带来的灾难性性能故障

      本文链接:https://www.haomeiwen.com/subject/xpcvdctx.html