记一次Oracle数据故障排除过程
前天在Oracle生產環(huán)境中,自己的存儲過程運行時間超過1小時,懷疑是其他job運行時間過長推遲了自己job運行時間,遂重新跑job,發(fā)現同測試環(huán)境的確不同,運行了25分鐘。
之后準備在測試環(huán)境中制造同數量級的數據進行分析,寫了大概如下的存儲過程,
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);BEGINv_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 loopv_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_divisionfrom datacore.df_customer_static_reportwhere data_date = v_end_date_str);commit;end loop;END PERFORMANCE_TEST;犯了個致命錯誤,丟了v_date := v_date + 1;?存儲過程陷入無限循環(huán)!在過了1個多小時后,意識到不對勁,遂查詢了數據量,發(fā)現2017-01-31的數據量竟然達到了千萬級。。。趕緊停止運行找原因,才發(fā)現無限循環(huán)插入數據。
剩下就是怎么刪掉這些數據,畢竟千萬級的數據占據存儲空間太大了。簡單的刪除肯定不起作用,遂嘗試分批刪除,先試著刪除1w條,結果運行很長時間后還是沒有結束。這個時候,感覺之前那個無限循環(huán)應該還沒有結束,在后臺還在運行。因為其他事情搗亂,沒來得及修正這個問題。第二天來,再次查詢,發(fā)現數據量達到了快5千萬條,欲哭無淚啊!趕緊刪數據,分批次,1百萬條的刪,(這次加上累加條件了)
create or replace PROCEDURE DELETE_TEMP AS v_number number := 1; v_number_end number := 50;BEGINwhile v_number <= v_number_end loopdelete from datacore.df_customer_static_report nologgingwhere 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語句的優(yōu)化,發(fā)現加上nologging會更快些(數據不做恢復)。
運行了大概1個小時后,感覺差不多了,遂手動終止了delete的運行。再次查詢,‘2017-01-31’的數據降到9千多條。竊喜~
不過又想起昨天想到的“是否無限循環(huán)還在后臺運行”?過了10幾分鐘后查詢,發(fā)現數據又多了,欲哭無淚。。
怎么讓這個討厭的無限循環(huán)終止呢?因為使用的賬號沒有dba權限,所以想通過更改表的結構,讓包含無限循環(huán)的存儲過程異常終止。但估計不可行,因為數據庫表一直被占用了。抱著試一試的想法,執(zhí)行以下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.?再次查看數據庫鎖,發(fā)現鎖消失。再次查詢表數據,不再增加。
教訓:以后寫存儲過程中的循環(huán),千萬注意條件的累加!
?
--------------------------------------------------------------------------------------------------------------------------------
-- 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;
?
轉載于:https://www.cnblogs.com/hello-yz/p/9923057.html
總結
以上是生活随笔為你收集整理的记一次Oracle数据故障排除过程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 配置文件位置整理
- 下一篇: DevOps:软件架构师行动指南(文摘)