误删一张80亿数据表的索引是怎样的体验

当然是吓瘸了

Friday目前就职于一家外企IT公司,总部是在美国,Friday在中国。得益于时差的关系,东西两边的工作能进行24小时相对无缝的切换协作。Friday每天的日常就是早上到公司,先回复下对面美国同事的相关邮件,然后开始一天的开发任务,下班前将当天的进度和问题发回总部确认,如果有必要的话,下班后等美国的同事上班发起一轮电话会议。

今天,本又是个平平无奇的一天,Friday来到公司开始一天的日常。打开邮件,美国同事要求Friday帮忙删除一张表的某条索引,因为在此时中国的时间是业务每天的低峰时刻,几乎没有什么流量。“常规操作”,Friday心道。很快他便写好了删除的命令,打开sqldeveloper进行了一波操作,“唔...为什么删了这么久”,索引删除了,但是Friday感觉有点不对,这本是一张不大的表,理论上秒秒钟就可以操作完成了,仔细一看后,Friday心凉了半截 -- 他删错索引了!再仔细检查后,他意识到自己麻烦大了-- 这个误删的索引的表有近80亿条数据(难怪删除花了不少时间,按照一般的方式,重建肯定要花很久的时间。好在此时是业务低谷,否则肯定各种疯狂告警和被投诉了。

Friday决定先死马当活马医,立刻进行索引重建,但是情况并不乐观。通常情况下对oracle的表建立索引的时候并不需要考虑效率问题,这个通常情况指的是相应的表数据在百万级以下。一旦数据量大到千万级,亿级甚至更大的时候,就不能不考虑新建索引的效率问题,因为当表在建立索引的时候,会产生锁阻塞新数据的更新,如果索引不能很快地建立完毕,会对生产环境造成影响。而Friday现在面临的问题是,重建的速度太慢以致于从进度上看预计需要几十个小时才能完成,而再过8个小时就是美国那边的上班时间,业务的流量高峰也会相应到来,想到这里Friday感觉自己有点窒息了。“一定有办法的”,Friday定了定神开始想对策。

“1. 正在执行的重建索引继续让它执行,如果所有办法失效,这就是最后的保障。”
“2. 调查一下索引删除的影响范围,应该不至于整个系统不可用。” Friday迅速过了一下代码,果然这张表只在一个统计类的功能里用到了,不属于核心功能范围,即使暂时一段时间不可用应该也影响不大。(真的吗? 下文分析)
“3. 马上找优化重建索引效率的办法,争取在4小时内重建完成”
“4. 要不要报告下领导...算了先瞒着...不行了再说” (呵呵...)

计算机的世界是一套严密的逻辑体系,凡事都是有迹可循,因果关系贯穿始终。一旦掌握原理,就可以扮演上帝进行法则的干预。想要优化建索引的效率,首先看创建索引到底做了些什么操作。

  1. 把索引key的数据读到内存

如果数据没在db_cache 中,这时候很容易有大量的db file scatter read wait

  1. 对索引key的数据作排序

sort_area_size 或者pga_aggregate_target 不够大的情况下,需要做 disk sort, 会有大量的driect path read/write , 另外,消耗大量CPU Time

  1. 创建新的index segment ,把排过序的索引数据写到所创建的index segment 里面.

如果index 很大,有时会有redo log 相关等待

那么,只要对这几个方向进行相应的优化,就有可能加速整体的效率。经过一番研究,Friday得出结论: 增大pga,增大temp tablepace, 并且用nologging或并行选项。

救火方案有了,看着依旧在龟速重建的进度,Friday决定直接用新的方案进行尝试,毕竟不会更差了,而且也没有环境和时间进行模拟。还好这次幸运女神站在了Friday这边,优化后只用了20分钟就将索引重建完毕,一切又回到了正轨。

Friday这一天过得惊心动魄,他事后进行复盘觉得自己实在是犯了一个非常低级的错误,以致于差点就长跪不起,今后一定要仔细检查,避免再犯。

然而我们更深入地进行思考,事情其实并没有这么简单。

  1. Friday 作为一个开发人员,为何对数据库有如此高的权限,以至于DBA都没有什么存在感

  2. 一个“危险”的DDL操作完全没有被审核的操作,DML那就更不用说了。

  3. 故障发生后,Friday并没有第一时间上报,而是主观凭自己的经验进行了评估,并企图自己修复掩盖失误,虽然最后的结果是成功了,但并不足取。原因有几:

    • 由于经验、技术能力和视野所限,开发并不一定能正确评估风险。比如:Friday认为这个故障只是影响了部分小众功能,问题不大,但是实际上,只要有足够的流量,没有索引的慢查询是足以拖死整个系统的,因为慢查询会占用数据库的连接,不能及时释放,当连接数用完后,其他正常的功能就无法连接数据库,导致整体不可用。其二,Friday的视野只是局限在自己的代码上,也许上报leader后他会发现,这个表还被其他工程甚至其他团队共用,而这其中的风险并没有评估到
    • 能独立解决问题是能力强的表现,但是面对线上故障,群策群力更有助于问题的解决。如果有专业DBA的帮助,可能会更快,更低风险地解决故障。而如果因为对自己能力的估计过于乐观进行冒失操作,可能会引起更大的风险和故障。

故障的发生有时候不是一人或是一事的得失,这是一个系统性的问题。一个良好的系统应该是可以规避风险,甚至自愈的。Friday 可能是个救火能手,但是对于系统上层建筑的机制完善此刻还没有足够的意识。


附 oracle大表加速索引建立的实操手册

1. PGA设置

hash_area_size: 这个参数控制每个会话的hash内存空间有多大。它也可以在会话级和实例级被修改。默认值是sort area空间大小的两倍 sort_area_size: 因为排序通常是在PGA中进行的,需要防止因空间或内存不足导致需要disk排序。

alter session set workarea_size_policy=manual;
alter session set hash_area_size=100000;
alter session set sort_area_size=2000000000; -- 在系统可用内存足够的情况下,最大可以到2G

question

  1. 什么是PGA
  2. 什么是SGA

2. 增加temp表空间

因为大表的数据量比较大,导致建索引时需要的temp表空间也比较大,一般来说接近索引的大小,没把握的情况下可以估算一下索引的大小先:

另外在建索引的过程中也可以随时监控表空间的使用情况,一旦发现temp表空间不够,可以随时加大

set serveroutput on
declare  
 v_ddl varchar(1024);  
 v_used_bytes number;  
 v_alloc_bytes number;  
 begin  
 dbms_space.create_index_cost(  
 ddl =>' create index ids_t on user(userid)',used_bytes=>v_used_bytes,alloc_bytes =>v_alloc_bytes);  
 dbms_output.put_line('used_bytes='||v_used_bytes||' bytes'||' alloc_bytes='|| v_alloc_bytes || ' bytes');  
 end;
 /

3. 使用并行参数

关于利用并行度创建索引,前提是多个CPU,单CPU下用并行度创建索引,可能会造成资源的争用。理论上来说8个CPU, 可以用parallel 6 ,最多占用6个CPU,另外留下两个CPU供其他进程使用。 查看CPU核数的方法有很多, 最简单地就是用下面这个sql直接查

SELECT * FROM v$osstat where stat_name='NUM_CPUS';

4. 使用nologging

nologging, 绝对应该使用,能减少大量redo log,使速度大幅上升。

于是一个比较标准的并行nologging建索引语句就出炉了。对于生产环境,保险的办法是再加上online参数,避免建索引时的锁对dml产生阻塞。

CREATE INDEX  table_idx ON table (col )  NOLOGGING PARALLEL 6;

Note

对于一个比较大的操作,oracle可能会有等待事件发生 首先可以通过sql developer查看等待时间的信息,得到等待时间的p1,p2,p3。然后通过下面的sql转换p1,p2得到具体等待的object。

select owner,segment_name,segment_typefrom dba_extentswhere file_id = &P1 and &P2 between block_id and block_id + blocks -1;

监控oracle 大事务的执行进度

set linesize 400;
set pagesize 400;
set long 4000;
col sql_fulltext format a100;
col opname format a15;
SELECT se.sid,
         opname,
         TRUNC (sofar / totalwork * 100, 2) pct_work,
         elapsed_seconds elapsed,
         ROUND (elapsed_seconds * (totalwork - sofar) / sofar) remain_time,
         sql_fulltext
    FROM v$session_longops sl, v$sqlarea sa, v$session se
   WHERE sl.sql_hash_value = sa.hash_value
         AND sl.sid = se.sid
         AND sofar != totalwork
ORDER BY start_time;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352

推荐阅读更多精彩内容

  • ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。 O...
    我想起个好名字阅读 5,292评论 0 9
  • 特别说明: 1、本文只是面对数据库应用开发的程序员,不适合专业DBA,DBA在数据库性能优化方面需要了解更多的知识...
    安易学车阅读 1,807评论 0 40
  • 常用语句: sql/plus sqlplus 'amdocs/Amdocs.Jx.China.110#@ysdb1...
    好好学习的蜗牛阅读 2,994评论 0 0
  • 索引 数据库中的查询操作非常普遍,索引就是提升查找速度的一种手段 索引的类型 从数据结构角度分 1.B+索引:传统...
    一凡呀阅读 2,901评论 0 8
  • 转载自:https://www.cnblogs.com/easypass/archive/2010/12/08/1...
    SkTj阅读 537评论 0 1