前天在Oracle生产环境中,自己的存储过程运行时间超过1小时,怀疑是其他job运行时间过长推迟了自己job运行时间,遂重新跑job,发现同测试环境的确不同,运行了25分钟。

之后准备在测试环境中制造同数量级的数据进行分析,写了大概如下的存储过程,

create or replace PROCEDURE PERFORMANCE_TEST AS 

v_date date;
v_start_date date;
v_end_date date;
v_start_date_str varchar2(10) := '2017-01-31';
v_end_date_str varchar2(10) := '2017-07-31';
v_date_str varchar2(10); BEGIN
v_start_date := to_date(v_start_date_str, 'yyyy-mm-dd');
v_end_date := to_date(v_end_date_str, 'yyyy-mm-dd');
v_date := v_start_date;
while v_date < v_end_date loop
v_date_str := to_char(v_date, 'yyyy-mm-dd');
insert into datacore.df_customer_static_report
(
data_date,
cty_code,
party_id,
party_name,
ho_domicile_cty,
rm_code,
rm_name,
business_division
)(
select
v_date_str,
cty_code,
party_id,
party_name,
ho_domicile_cty,
rm_code,
rm_name,
business_division
from datacore.df_customer_static_report
where data_date = v_end_date_str
);
commit;
end loop; END PERFORMANCE_TEST;

犯了个致命错误,丢了v_date := v_date + 1; 存储过程陷入无限循环!在过了1个多小时后,意识到不对劲,遂查询了数据量,发现2017-01-31的数据量竟然达到了千万级。。。赶紧停止运行找原因,才发现无限循环插入数据。

剩下就是怎么删掉这些数据,毕竟千万级的数据占据存储空间太大了。简单的删除肯定不起作用,遂尝试分批删除,先试着删除1w条,结果运行很长时间后还是没有结束。这个时候,感觉之前那个无限循环应该还没有结束,在后台还在运行。因为其他事情捣乱,没来得及修正这个问题。第二天来,再次查询,发现数据量达到了快5千万条,欲哭无泪啊!赶紧删数据,分批次,1百万条的删,(这次加上累加条件了)

create or replace PROCEDURE DELETE_TEMP AS 

v_number number := 1;
v_number_end number := 50; BEGIN while v_number <= v_number_end loop
delete from datacore.df_customer_static_report nologging
where data_date = '2017-01-31'
and rownum < 1000000;
commit;
v_number := v_number + 1;
dbms_output.put_line(v_number || ' end');
end loop; END DELETE_TEMP;

本想用TRUNCATE把所有数据都删掉,但是我这里只需要删掉表中‘2017-01-31’的数据,而且只是把千万条降低到万条。查了delete语句的优化,发现加上nologging会更快些(数据不做恢复)。

运行了大概1个小时后,感觉差不多了,遂手动终止了delete的运行。再次查询,‘2017-01-31’的数据降到9千多条。窃喜~

不过又想起昨天想到的“是否无限循环还在后台运行”?过了10几分钟后查询,发现数据又多了,欲哭无泪。。

怎么让这个讨厌的无限循环终止呢?因为使用的账号没有dba权限,所以想通过更改表的结构,让包含无限循环的存储过程异常终止。但估计不可行,因为数据库表一直被占用了。抱着试一试的想法,执行以下sql,

alter table datacore.df_customer_static_report
drop column rds_spread_code

报错“资源正忙, 但指定以 NOWAIT 方式获取资源, 或者超时失效;resource busy and acquire with NOWAIT specified”。

搜索后,果真有解决方案 - here,但还是需要dba权限(厚脸皮要吧)。

1. 用dba权限的用户查看数据库都有哪些锁

SELECT T2.USERNAME,T2.SID,T2.SERIAL#,T2.LOGON_TIME
FROM V$LOCKED_OBJECT T1,V$SESSION T2
WHERE T1.SESSION_ID=T2.SID ORDER BY T2.LOGON_TIME;

2. 根据sid查看具体的sql语句,如果sql不重要,可以kill

SELECT SQL_TEXT FROM V$SESSION A,V$SQLTEXT_WITH_NEWLINES B
WHERE DECODE(A.SQL_HASH_VALUE, 0, PREV_HASH_VALUE, SQL_HASH_VALUE)=B.HASH_VALUE
AND A.SID=&SID ORDER BY PIECE;

3. kill该事务

ALTER SYSTEM KILL SESSION '590,20839';

4. 再次查看数据库锁,发现锁消失。再次查询表数据,不再增加。

教训:以后写存储过程中的循环,千万注意条件的累加!

--------------------------------------------------------------------------------------------------------------------------------

-- index(索引)
select * from all_indexes;
select * from user_indexes;

select * from all_ind_columns;
select * from user_ind_columns;

select t.*,i.index_type
from user_ind_columns t,user_indexes i
where t.index_name = i.index_name
and t.table_name = i.table_name and t.table_name = 'DM_RR_GQ_FIN_FEDS';

select t.*,i.index_type
from all_ind_columns t,all_indexes i
where t.index_name = i.index_name
and t.table_name = i.table_name
and owner = 'FISP'
and t.table_name = 'FIS_OUT_FLEXI';

-- tables(表)
select * from user_tab_columns;
select * from all_tab_columns;

select * from user_col_comments;
select * from all_col_comments;

select * from user_tables;
select * from all_tables;

记一次Oracle数据故障排除过程的更多相关文章

  1. 记一次wiki数据爬取过程

    最近有个爬取各国领导人信息的奇怪需求,要求百度和维基两种版本的数据,最要命的还要保持数据的结构不变.正好印象中隐约记得维基有专门的领导人列表页,不考虑爬取下来的格式不变的话应该很好爬的样子. 首先思路 ...

  2. 对NetBackup 问题进行故障排除的步骤

    错误消息通常是指出哪里出现故障的手段.如果在界面上没有看到错误消息,但仍怀疑有问题,请检查报告和日志. NetBackup提供了各种报告和日志记录工具, 这些工具可提供错误消息,直接为您指出解决方案. ...

  3. spark 性能优化 数据倾斜 故障排除

    版本:V2.0 第一章       Spark 性能调优 1.1      常规性能调优 1.1.1   常规性能调优一:最优资源配置 Spark性能调优的第一步,就是为任务分配更多的资源,在一定范围 ...

  4. Atitit.故障排除系列---php 计划网站数据库错误排除过程

    Atitit.故障排除系列---php 计划网站数据库错误排除过程 Php页面报告的错误不能定位到myusql的db配置上...字说是db conn err Mysql 接入错误...大概查看哈能不能 ...

  5. Confluence 6 数据中心的 SAML 单点登录最佳实践和故障排除

    最佳实践 SAML 授权仅仅在有限的时间进行校验.你需要确定运行你的应用的计算机时间与 IdP 的时间是同步的. 如果你应用中的用户和用户组是通过用户目录进行配置的,你通常希望用户来源目录和你的 Id ...

  6. 记一次oracle 11g数据导入

    1.ORACLE数据库数据导入到测试库环境 172.15.1.51 root  kic@test 172.15.1.52 root 一般先将数据导入52的环境(配置比较低),再将数据导入51的环境(本 ...

  7. 理解 OpenStack + Ceph (7): Ceph 的基本操作和常见故障排除方法

    本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...

  8. ORA-4031 错误故障排除与诊断[视频] (Doc ID 2016002.1)

    Copyright (c) 2019, Oracle. All rights reserved. Oracle Confidential.     ORA-4031 错误故障排除与诊断[视频] (Do ...

  9. 学习笔记:CentOS7学习之十八:Linux系统启动原理及故障排除

    目录 学习笔记:CentOS7学习之十八:Linux系统启动原理及故障排除 18.1 centos6系统启动过程及相关配置文件 18.1.1 centos6系统启动过程 18.1.2 centos6启 ...

随机推荐

  1. .net3.5下使用LINQ递归算法实现简洁代码

    原文发布时间为:2011-04-24 -- 来源于本人的百度文章 [由搬家工具导入] http://www.cnblogs.com/wintersun/archive/2009/03/29/14243 ...

  2. hdu 1847 Good Luck in CET-4 Everybody! 组合游戏 找规律

    题目链接 题意 有\(n\)张牌,两人依次摸牌,每次摸的张数只能是\(2\)的幂次,最后没牌可摸的人为负.问先手会赢还是会输? 思路 0 1 2 3 4 5 6 7 8 9 10 11 -- P N ...

  3. VS Code开发技巧集锦【转】

    转自:http://blog.csdn.net/tiantangyouzui/article/details/52163175 入门 自定义 扩展 文件/文件夹管理 编辑技巧 智能感应功能 代码片段 ...

  4. 【剑指offer】数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  5. 2018 L2-027. 名人堂与代金券【结构体排序】

    L2-027. 名人堂与代金券 时间限制 150 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 对于在中国大学MOOC(http://www.i ...

  6. codevs——3372 选学霸(背包)

    题目等级 : 大师 Master  时间限制: 1 s  空间限制: 128000 KB 题解       题目描述 Description 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实 ...

  7. 【转】浅谈多核CPU、多线程、多进程

    浅谈多核CPU.多线程.多进程 1.CPU发展趋势 核心数目依旧会越来越多,依据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的桌面PC有望在2017年末2018年初达到24核心(或者16核3 ...

  8. SecureCRT发送键盘按键对应表(转义字符)

    \r 发送回车(CR) \n 发送换行符(LF) \b 发送退格 \e 发送一个转义 \t 发送一个标签 \\ 发送一个反斜杠字符 \v 将剪贴板的内容粘贴到活动状态会话窗口 \p 暂停一秒钟

  9. 15 THINGS ALL GIRLS SHOULD KNOW ABOUT THEIR VAGINA

    Here are 15 facts that EVERY GIRL should know about her vagina. Don’t be shy! Your vagina is part of ...

  10. 【前端阅读】——《活用PHP、MySQL建构Web世界》摘记之设计技巧

    二.设计技巧 Programming的习惯因人而异,这里只提供一些经验,可以参考. 1.利用Include模块化你的程序代码 Include函数基本上说:就像是把另一个文件(HTML或者PHP程序)读 ...