前言:
前幾天,我在對數(shù)據(jù)庫做日常巡檢時發(fā)現(xiàn),有一臺平時沒多少業(yè)務量的數(shù)據(jù)庫(通過歸檔頻率、內存占用、會話量等判斷),其表空間仍然是以700MB/天的速度在增長,這不合常理。于是我通過以下手段進行了分析,找出了"幕后黑手"。
一、查看表空間增長情況

二、找出具體在增長的表空間

三、找出對應表空間中是哪些表導致的空間異常增長
本來想從 dba_hist_seg_stat 視圖中去獲取有用信息,結果搞了半天發(fā)現(xiàn)里面的信息并不全,并且得到的數(shù)據(jù)也不準確,最終我也沒有通過這個視圖找到有用的線索。
所謂“條條大路通北京”,上面的路不通,我就換一條稍微繞點的路來獲取想要的信息吧。既然已經(jīng)知道是哪個表空間在異常增長,那么我只需要編寫一個存儲過程,定時記錄這個表空間中所有表的數(shù)據(jù)變化情況即可。
--先創(chuàng)建用來記錄數(shù)據(jù)的表
create table TB_USAGE_RECORD
(
ctime DATE,
segment_name VARCHAR2(200),
partition_name VARCHAR2(200)
segment_type VARCHAR2(30),
header_file NUMBER,
header_block NUMBER,
size_gb NUMBER
)
create table TB_USAGE_RECORD_TOTAL
(
ctime DATE,
total_gb NUMBER
);
--創(chuàng)建存儲過程(本文中的敏感信息已經(jīng)進行了改寫和處理)
create or replace procedure gather_tb_size_increase authid current_user
is
begin
insert into TB_USAGE_RECORD select sysdate ctime,segment_name,partition_name,segment_type,header_file,header_block,round(bytes/1024/1024/1024,3) size_gb
from dba_segments where tablespace_name='THE_EXCEPTION_TBS';
insert into TB_USAGE_RECORD_TOTAL select sysdate ctime,round(sum(bytes)/1024/1024/1024,3) total_gb from dba_segments where tablespace_name='THE_EXCEPTION_TBS';
commit;
end;
ok,現(xiàn)在我可以馬上執(zhí)行一次存儲過程,然后設置一個定時job,讓其在明天的這個時候再執(zhí)行一次。等明天的數(shù)據(jù)獲取到后,即可分析出問題所在!
四、找出問題根源
等第二天的結果出來后,我編寫了以下sql并執(zhí)行,找出數(shù)據(jù)變化的表:

查看表中有多少數(shù)據(jù):

發(fā)現(xiàn)只有102行數(shù)據(jù),查看表結構發(fā)現(xiàn)也沒有大字段,不應該占用100多M的空間??!接著分析:
--收集統(tǒng)計信息:
analyze table LIST_20220415 compute statistics;
--查看實際占用空間大?。?/span>
select segment_name,partition_name,round(bytes/1024/1024,2) size_mb from dba_segments where segment_name='LIST_20220415'
SEGMENT_NAME PARTITION_NAME SIZE_MB
1 LIST_20220415 152
--查看實際占用多少塊,是否有空塊:
select table_name,num_rows,blocks,empty_blocks from dba_tables where table_name='LIST_20220415'
TABLE_NAME NUM_ROWS BLOCKS EMPTY_BLOCKS
1 LIST_20220415 102 222 19234
實際上數(shù)據(jù)只使用了222個塊,高水位線以下還有19234個空塊,所以才導致102行數(shù)據(jù)占用了(222+19234)*8/1024=152 MB,與dba_segments中查出來的值相同。
所以,應該是業(yè)務端向這張表中寫入了大量數(shù)據(jù),然后又執(zhí)行了delete操作,刪除了大量數(shù)據(jù),導致高水位線的產(chǎn)生。
五、問題的處理
根據(jù)之前找出的導致數(shù)據(jù)增長的幾張表,我發(fā)現(xiàn)它們都是以具體日期命名的。并且我也在數(shù)據(jù)庫的相關存儲過程中也找到了創(chuàng)建這幾張歷史表的sql。至于每天歷史表的創(chuàng)建,則是由應用端直接調用存儲過程發(fā)起。期間應用對歷史表執(zhí)行了一系列操作,從而產(chǎn)生了高水位。為了節(jié)約存儲空間,一方面是和業(yè)務溝通后,要對歷史表進行及時地備份和清理,另一方面是要每天對這幾張歷史表進行高水位線的清理(編寫為存儲過程,創(chuàng)建job每天定時執(zhí)行即可)。
以下是清理高水位線后,表的空間占用情況:
SEGMENT_NAME PARTITION_NAME SIZE_MB 1 LIST_20220415 0.31
可見效果還是很顯著的,空間占用直接由152MB降低到0.31MB。
經(jīng)過幾天的觀察,發(fā)現(xiàn)表空間異常增長的現(xiàn)象已經(jīng)消失:

(本文完)




