记一次Oracle数据故障排除过程
前天在Oracle生產(chǎn)環(huán)境中,自己的存儲(chǔ)過(guò)程運(yùn)行時(shí)間超過(guò)1小時(shí),懷疑是其他job運(yùn)行時(shí)間過(guò)長(zhǎng)推遲了自己job運(yùn)行時(shí)間,遂重新跑job,發(fā)現(xiàn)同測(cè)試環(huán)境的確不同,運(yùn)行了25分鐘。
之后準(zhǔn)備在測(cè)試環(huán)境中制造同數(shù)量級(jí)的數(shù)據(jù)進(jìn)行分析,寫了大概如下的存儲(chǔ)過(guò)程,
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;犯了個(gè)致命錯(cuò)誤,丟了v_date := v_date + 1;?存儲(chǔ)過(guò)程陷入無(wú)限循環(huán)!在過(guò)了1個(gè)多小時(shí)后,意識(shí)到不對(duì)勁,遂查詢了數(shù)據(jù)量,發(fā)現(xiàn)2017-01-31的數(shù)據(jù)量竟然達(dá)到了千萬(wàn)級(jí)。。。趕緊停止運(yùn)行找原因,才發(fā)現(xiàn)無(wú)限循環(huán)插入數(shù)據(jù)。
剩下就是怎么刪掉這些數(shù)據(jù),畢竟千萬(wàn)級(jí)的數(shù)據(jù)占據(jù)存儲(chǔ)空間太大了。簡(jiǎn)單的刪除肯定不起作用,遂嘗試分批刪除,先試著刪除1w條,結(jié)果運(yùn)行很長(zhǎng)時(shí)間后還是沒(méi)有結(jié)束。這個(gè)時(shí)候,感覺(jué)之前那個(gè)無(wú)限循環(huán)應(yīng)該還沒(méi)有結(jié)束,在后臺(tái)還在運(yùn)行。因?yàn)槠渌虑閾v亂,沒(méi)來(lái)得及修正這個(gè)問(wèn)題。第二天來(lái),再次查詢,發(fā)現(xiàn)數(shù)據(jù)量達(dá)到了快5千萬(wàn)條,欲哭無(wú)淚啊!趕緊刪數(shù)據(jù),分批次,1百萬(wàn)條的刪,(這次加上累加條件了)
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把所有數(shù)據(jù)都刪掉,但是我這里只需要?jiǎng)h掉表中‘2017-01-31’的數(shù)據(jù),而且只是把千萬(wàn)條降低到萬(wàn)條。查了delete語(yǔ)句的優(yōu)化,發(fā)現(xiàn)加上nologging會(huì)更快些(數(shù)據(jù)不做恢復(fù))。
運(yùn)行了大概1個(gè)小時(shí)后,感覺(jué)差不多了,遂手動(dòng)終止了delete的運(yùn)行。再次查詢,‘2017-01-31’的數(shù)據(jù)降到9千多條。竊喜~
不過(guò)又想起昨天想到的“是否無(wú)限循環(huán)還在后臺(tái)運(yùn)行”?過(guò)了10幾分鐘后查詢,發(fā)現(xiàn)數(shù)據(jù)又多了,欲哭無(wú)淚。。
怎么讓這個(gè)討厭的無(wú)限循環(huán)終止呢?因?yàn)槭褂玫馁~號(hào)沒(méi)有dba權(quán)限,所以想通過(guò)更改表的結(jié)構(gòu),讓包含無(wú)限循環(huán)的存儲(chǔ)過(guò)程異常終止。但估計(jì)不可行,因?yàn)閿?shù)據(jù)庫(kù)表一直被占用了。抱著試一試的想法,執(zhí)行以下sql,
alter table datacore.df_customer_static_report drop column rds_spread_code報(bào)錯(cuò)“資源正忙, 但指定以 NOWAIT 方式獲取資源, 或者超時(shí)失效;resource busy and acquire with NOWAIT specified”。
搜索后,果真有解決方案 -?here,但還是需要dba權(quán)限(厚臉皮要吧)。
1.?用dba權(quán)限的用戶查看數(shù)據(jù)庫(kù)都有哪些鎖
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.?根據(jù)sid查看具體的sql語(yǔ)句,如果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該事務(wù)
ALTER SYSTEM KILL SESSION '590,20839';4.?再次查看數(shù)據(jù)庫(kù)鎖,發(fā)現(xiàn)鎖消失。再次查詢表數(shù)據(jù),不再增加。
教訓(xùn):以后寫存儲(chǔ)過(guò)程中的循環(huán),千萬(wà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;
?
轉(zhuǎn)載于:https://www.cnblogs.com/hello-yz/p/9923057.html
總結(jié)
以上是生活随笔為你收集整理的记一次Oracle数据故障排除过程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 配置文件位置整理
- 下一篇: DevOps:软件架构师行动指南(文摘)