和開發同學討論的一個技術問題

jeanron100發表於2016-04-18
   今天下午的時候,有一位開發同事找我,說有一個技術問題想請教一下。
   當然正如他所說,這個問題比較奇怪,而且已經影響了他的測試流程,他說有一個表檢視對應的表空間但是顯示為空,所以插入不了資料。我們之前做過一次資料遷移,他想讓我幫忙看看,能不能修改一下表空間的設定。
   好了,問題到這裡,看起來已經比較明顯了,一個表對應的表空間是必須有的屬性,所以應該不會存在為空的情況,而插入不了資料,應該和這個表空間設定沒有關係,另有其他的原因,而且他說這個表裡面有700多萬的資料,現在只剩下90萬左右,資料是怎麼被清理了?
  到了這個時候,聽起來有了一些頭緒,當然我在19樓,他在3樓,我是不大願意來來回回跑動,如果一兩句話能解決的事情,或者遠端簡單支援就能搞定,就不用那麼麻煩了,所以簡單聊了下,就開啟了遠端協助,他給我復現了問題,當然是透過plsqldev來複現的,我看到他在表物件右鍵屬性,彈出的視窗裡確實顯示錶空間為空,當然到了這裡,我就明白了問題的原因,這肯定是個分割槽表。
當然我是執行了一條sql,select * from user_tab_partitions where table_name='CLIENT_LOG';
可以看到確實存在大量的分割槽資訊,淡然表空間都清一色指向了同一個表空間,所以由此可以看出表空間也算是一個誤導,當然從圖形工具來看,也可以理解,因為分割槽表中含有多個分割槽,每個分割槽的表空間都可以不同,那麼這個表屬於哪個表空間,確實也不好說。
  那麼第二個問題,他說插入不了資料,原來表裡的資料有幾百萬,現在只剩下了幾十萬,這個怎麼來解釋。如果沒有頭緒我可以先從系統級別入手。使用top可以看到系統的CPU使用率極高,基本idle都是個位數,從top的命令可以看出確實存在大量的程式是CPU 100%的節奏,所以在做一些簡單的查詢時,也會有卡頓的情況。
   我檢視了v$session的情況,發現active session有100多個,而且有90%的session都卡在了同一個語句上,這個語句是delete from client_log_real這樣的sql語句,一看到這個語句。就感覺很奇怪,怎麼會出現如此多的active session,而且每個session都在嘗試做delete操作。如果細想,這種情況的可能性也很明顯,那就是這個表太大了或者執行計劃出現了偏差,導致效率低下,第一次的沒有執行完成,然後第二次的又開始執行,如此反覆,卡住了上百個session,當然和開發同事確認,他們有個程式是透過crontab來觸發的delete操作。而且這個表的資料也確實很多,目前是沒5分鐘觸發一次,按照這種情況,5分鐘之內還刪除不了資料,而且這還是一個全表資料刪除,可見資料量應該不小,當然我在稍後進行查詢,結果也嚇我一跳。
SQL> select count(*)from client.CLIENT_LOG_REAL;
  COUNT(*)
----------
 177377492
裡面竟然有多大1億多條資料,如此看來,5分鐘難怪刪除不了了。
所以對於這種問題,當務之急是釋放這些嚴重消耗資源的程式,簡單做了確認,就使用awk生成了動態的刪除指令碼,可以看到系統的負載馬上是降了下來,但是稍後還是會繼續存在這些卡住的程式。因為這種操作方式還是存在一些不嚴謹的地方,每次都是delete from的操作,那麼每次都需要清空資料,為何不用truncate呢,就算每次清理了資料,反覆delete,高水位線的影響也會越來越大。所以可以建議他們使用delete from xxx where 帶有條件的刪除,或者直接使用truncatew刪除。
  然後是他們所說的最後一個問題,就是為什麼原來裡面有幾百萬的資料,現在只有幾十萬的資料,這個如果按照一般的思路還真不好判別,檢視dba_tab_modifications是一種方式,還有中方式就是檢視user_tables,user_objects的資訊,當然我看到這個表的建立時間created的值是今天,也就意味著這個表在今天被重建了。這也可以作為部分資料和預期有差距的一個原因。明白了這一點後,開發同學的這幾個疑問也算是解決了,當然後續還有一些問題,也算是好好鍛鍊了一把最佳化的技巧。也基本都做了分析和定位,爭取儘快得以解決。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23718752/viewspace-2083749/,如需轉載,請註明出處,否則將追究法律責任。

相關文章