Oracle Database Growth Monitoring – Simplified Guide
This guide provides queries and scripts to monitor database growth at different levels:
1. 📅 Database Growth Per Month
SELECTto_char(creation_time, 'MM-RRRR') AS "Month",round(SUM(bytes) / 1024 / 1024 / 1024, 2) AS "Growth in GB"FROMv$datafileWHEREto_char(creation_time, 'RRRR') = '2023'GROUP BYto_char(creation_time, 'MM-RRRR')ORDER BY1;
2. 📦 Tablespace-Level Growth (Last 7 Days)
SELECTb.tsname AS tablespace_name,MAX(b.used_size_mb) AS cur_used_size_mb,round(AVG(inc_used_size_mb), 2) AS avg_increase_mbFROM(SELECTa.days,a.tsname,a.used_size_mb,a.used_size_mb - LAG(a.used_size_mb, 1)OVER(PARTITION BY a.tsnameORDER BYa.tsname, a.days) AS inc_used_size_mbFROM(SELECTto_char(sp.begin_interval_time, 'MM-DD-YYYY') AS days,ts.tsname,MAX(round(tsu.tablespace_usedsize * dt.block_size / 1024 / 1024, 2)) AS used_size_mbFROMdba_hist_tbspc_space_usage tsu,dba_hist_tablespace_stat ts,dba_hist_snapshot sp,dba_tablespaces dtWHEREtsu.tablespace_id = ts.ts#AND tsu.snap_id = sp.snap_idAND ts.tsname = dt.tablespace_nameAND sp.begin_interval_time > sysdate - 7GROUP BYto_char(sp.begin_interval_time, 'MM-DD-YYYY'),ts.tsname) a) bGROUP BYb.tsnameORDER BYb.tsname;
3. 📋 Database Size, Used/Free Space, Growth Per Day and Per Week
SET LINESIZE 200SET PAGESIZE 200COL "Database Size" FORMAT a13COL "Used Space" FORMAT a11COL "Used in %" FORMAT a11COL "Free in %" FORMAT a11COL "Database Name" FORMAT a13COL "Free Space" FORMAT a12COL "Growth DAY" FORMAT a11COL "Growth WEEK" FORMAT a12COL "Growth DAY in %" FORMAT a16COL "Growth WEEK in %" FORMAT a16SELECT(SELECTMIN(creation_time)FROMv$datafile) "Create Time",(SELECTnameFROMv$database) "Database Name",round((SUM(used.bytes) / 1024 / 1024), 2)|| ' MB' "Database Size",round((SUM(used.bytes) / 1024 / 1024) - round(free.p / 1024 / 1024), 2)|| ' MB' "Used Space",round(((SUM(used.bytes) / 1024 / 1024) -(free.p / 1024 / 1024)) / round(SUM(used.bytes) / 1024 / 1024, 2) * 100, 2)|| '% MB' "Used in %",round((free.p / 1024 / 1024), 2)|| ' MB' "Free Space",round(((SUM(used.bytes) / 1024 / 1024) -((SUM(used.bytes) / 1024 / 1024) - round(free.p / 1024 / 1024))) / round(SUM(used.bytes) /1024 / 1024, 2) * 100, 2)|| '% MB' "Free in %",round(((SUM(used.bytes) / 1024 / 1024) -(free.p / 1024 / 1024)) /(SELECTsysdate - MIN(creation_time)FROMv$datafile), 2)|| ' MB' "Growth DAY",round(((SUM(used.bytes) / 1024 / 1024) -(free.p / 1024 / 1024)) /(SELECTsysdate - MIN(creation_time)FROMv$datafile) / round((SUM(used.bytes) / 1024 / 1024), 2) * 100, 3)|| '% MB' "Growth DAY in %",round(((SUM(used.bytes) / 1024 / 1024) -(free.p / 1024 / 1024)) /(SELECTsysdate - MIN(creation_time)FROMv$datafile) * 7, 2)|| ' MB' "Growth WEEK",round((((SUM(used.bytes) / 1024 / 1024) -(free.p / 1024 / 1024)) /(SELECTsysdate - MIN(creation_time)FROMv$datafile) / round((SUM(used.bytes) / 1024 / 1024), 2) * 100) * 7, 3)|| '% MB' "Growth WEEK in %"FROM(SELECTbytesFROMv$datafileUNION ALLSELECTbytesFROMv$tempfileUNION ALLSELECTbytesFROMv$log) used,(SELECTSUM(bytes) AS pFROMdba_free_space) freeGROUP BYfree.p;
4. 📊 Current Tablespace Size and Average Daily Growth
SELECTb.tsname AS tablespace_name,MAX(b.used_size_mb) AS cur_used_size_mb,round(AVG(inc_used_size_mb), 2) AS avg_increase_mbFROM(SELECTa.days,a.tsname,a.used_size_mb,a.used_size_mb - LAG(a.used_size_mb, 1)OVER(PARTITION BY a.tsnameORDER BYa.tsname, a.days) AS inc_used_size_mbFROM(SELECTto_char(sp.begin_interval_time, 'MM-DD-YYYY') AS days,ts.tsname,MAX(round(tsu.tablespace_usedsize * dt.block_size / 1024 / 1024, 2)) AS used_size_mbFROMdba_hist_tbspc_space_usage tsu,dba_hist_tablespace_stat ts,dba_hist_snapshot sp,dba_tablespaces dtWHEREtsu.tablespace_id = ts.ts#AND tsu.snap_id = sp.snap_idAND ts.tsname = dt.tablespace_nameAND sp.begin_interval_time > sysdate - 7GROUP BYto_char(sp.begin_interval_time, 'MM-DD-YYYY'),ts.tsname) a) bGROUP BYb.tsnameORDER BYb.tsname;
5. 📅 Monthly Database Growth
SELECTto_char(creation_time, 'RRRR') year,to_char(creation_time, 'MM') month,round(SUM(bytes) / 1024 / 1024 / 1024) gbFROMv$datafileGROUP BYto_char(creation_time, 'RRRR'),to_char(creation_time, 'MM')ORDER BY1,2;
6. 🗓️ Simple Database Growth Per Month
COLUMN month FORMAT a20 COLUMN growth FORMAT 999,999,999,999,999 SELECT TO_CHAR(creation_time, 'RRRR-MM') AS "Month", SUM(bytes/1024/1024) AS "Growth (MB)" FROM sys.v_$datafile GROUP BY TO_CHAR(creation_time, 'RRRR-MM') ORDER BY 1;
7. 📈 DB Growth Per Tablespace, Daily and Weekly
SELECTMIN(creation_time) AS "Create Time",ts.name,round(SUM(df.bytes) / 1024 / 1024) AS curr_size_mb,round((SUM(df.bytes) / 1024 / 1024) / round(sysdate - MIN(creation_time)), 1) AS growth_per_day_mb,round(((SUM(df.bytes) / 1024 / 1024) / round(sysdate - MIN(creation_time))) * 7, 1) AS growth_per_week_mbFROMv$datafile df,v$tablespace tsWHEREdf.ts# = ts.ts#GROUP BYdf.ts#,ts.nameORDER BYdf.ts#;
8. 📅 Database Growth History and Forecast (PL/SQL Block)
▶ A script that calculates total growth and expected growth:
set serverout onset verify offset lines 200set pages 2000DECLAREv_ts_id NUMBER;not_in_awr EXCEPTION;v_ts_block_size NUMBER;v_begin_snap_id NUMBER;v_end_snap_id NUMBER;v_begin_snap_date DATE;v_end_snap_date DATE;v_numdays NUMBER;v_count NUMBER;v_ts_begin_size NUMBER;v_ts_end_size NUMBER;v_ts_growth NUMBER;v_ts_begin_allocated_space NUMBER;v_ts_end_allocated_space NUMBER;v_db_begin_size NUMBER := 0;v_db_end_size NUMBER := 0;v_db_begin_allocated_space NUMBER := 0;v_db_end_allocated_space NUMBER := 0;v_db_growth NUMBER := 0;CURSOR v_cur ISSELECTtablespace_nameFROMdba_tablespacesWHEREcontents = 'PERMANENT';BEGINFOR v_rec IN v_cur LOOPBEGINv_ts_begin_allocated_space := 0;v_ts_end_allocated_space := 0;v_ts_begin_size := 0;v_ts_end_size := 0;SELECTts#INTO v_ts_idFROMv$tablespaceWHEREname = v_rec.tablespace_name;SELECTblock_sizeINTO v_ts_block_sizeFROMdba_tablespacesWHEREtablespace_name = v_rec.tablespace_name;SELECTCOUNT(*)INTO v_countFROMdba_hist_tbspc_space_usageWHEREtablespace_id = v_ts_id;IF v_count = 0 THENRAISE not_in_awr;END IF;SELECTMIN(snap_id),MAX(snap_id),MIN(trunc(to_date(rtime, 'MM/DD/YYYY HH24:MI:SS'))),MAX(trunc(to_date(rtime, 'MM/DD/YYYY HH24:MI:SS')))INTOv_begin_snap_id,v_end_snap_id,v_begin_snap_date,v_end_snap_dateFROMdba_hist_tbspc_space_usageWHEREtablespace_id = v_ts_id;IF upper(v_rec.tablespace_name) = 'SYSTEM' THENv_numdays := v_end_snap_date - v_begin_snap_date;END IF;SELECTround(MAX(tablespace_size) * v_ts_block_size / 1024 / 1024, 2)INTO v_ts_begin_allocated_spaceFROMdba_hist_tbspc_space_usageWHEREtablespace_id = v_ts_idAND snap_id = v_begin_snap_id;SELECTround(MAX(tablespace_size) * v_ts_block_size / 1024 / 1024, 2)INTO v_ts_end_allocated_spaceFROMdba_hist_tbspc_space_usageWHEREtablespace_id = v_ts_idAND snap_id = v_end_snap_id;SELECTround(MAX(tablespace_usedsize) * v_ts_block_size / 1024 / 1024, 2)INTO v_ts_begin_sizeFROMdba_hist_tbspc_space_usageWHEREtablespace_id = v_ts_idAND snap_id = v_begin_snap_id;SELECTround(MAX(tablespace_usedsize) * v_ts_block_size / 1024 / 1024, 2)INTO v_ts_end_sizeFROMdba_hist_tbspc_space_usageWHEREtablespace_id = v_ts_idAND snap_id = v_end_snap_id;v_db_begin_allocated_space := v_db_begin_allocated_space + v_ts_begin_allocated_space;v_db_end_allocated_space := v_db_end_allocated_space + v_ts_end_allocated_space;v_db_begin_size := v_db_begin_size + v_ts_begin_size;v_db_end_size := v_db_end_size + v_ts_end_size;v_db_growth := v_db_end_size - v_db_begin_size;END;END LOOP;dbms_output.put_line(chr(10));dbms_output.put_line('Summary');dbms_output.put_line('========');dbms_output.put_line('1) Allocated Space: '|| v_db_end_allocated_space|| ' MB'|| ' ('|| round(v_db_end_allocated_space / 1024, 2)|| ' GB)');dbms_output.put_line('2) Used Space: '|| v_db_end_size|| ' MB'|| ' ('|| round(v_db_end_size / 1024, 2)|| ' GB)');dbms_output.put_line('3) Used Space Percentage: '|| round(v_db_end_size / v_db_end_allocated_space * 100, 2)|| ' %');dbms_output.put_line(chr(10));dbms_output.put_line('History');dbms_output.put_line('========');dbms_output.put_line('1) Allocated Space on '|| v_begin_snap_date|| ': '|| v_db_begin_allocated_space|| ' MB'|| ' ('|| round(v_db_begin_allocated_space / 1024, 2)|| ' GB)');dbms_output.put_line('2) Current Allocated Space on '|| v_end_snap_date|| ': '|| v_db_end_allocated_space|| ' MB'|| ' ('|| round(v_db_end_allocated_space / 1024, 2)|| ' GB)');dbms_output.put_line('3) Used Space on '|| v_begin_snap_date|| ': '|| v_db_begin_size|| ' MB'|| ' ('|| round(v_db_begin_size / 1024, 2)|| ' GB)');dbms_output.put_line('4) Current Used Space on '|| v_end_snap_date|| ': '|| v_db_end_size|| ' MB'|| ' ('|| round(v_db_end_size / 1024, 2)|| ' GB)');dbms_output.put_line('5) Total growth during last '|| v_numdays|| ' days between '|| v_begin_snap_date|| ' and '|| v_end_snap_date|| ': '|| v_db_growth|| ' MB'|| ' ('|| round(v_db_growth / 1024, 2)|| ' GB)');IF ( v_db_growth <= 0 OR v_numdays <= 0 ) THENdbms_output.put_line(chr(10));dbms_output.put_line('No data growth was found for the Database');ELSEdbms_output.put_line('6) Per day growth during last '|| v_numdays|| ' days: '|| round(v_db_growth / v_numdays, 2)|| ' MB'|| ' ('|| round((v_db_growth / v_numdays) / 1024, 2)|| ' GB)');dbms_output.put_line(chr(10));dbms_output.put_line('Expected Growth');dbms_output.put_line('===============');dbms_output.put_line('1) Expected growth for next 30 days: '|| round((v_db_growth / v_numdays) * 30, 2)|| ' MB'|| ' ('|| round(((v_db_growth / v_numdays) * 30) / 1024, 2)|| ' GB)');dbms_output.put_line('2) Expected growth for next 60 days: '|| round((v_db_growth / v_numdays) * 60, 2)|| ' MB'|| ' ('|| round(((v_db_growth / v_numdays) * 60) / 1024, 2)|| ' GB)');dbms_output.put_line('3) Expected growth for next 90 days: '|| round((v_db_growth / v_numdays) * 90, 2)|| ' MB'|| ' ('|| round(((v_db_growth / v_numdays) * 90) / 1024, 2)|| ' GB)');dbms_output.put_line(chr(10));dbms_output.put_line('/\/\/\/\/\/\/\/\/\/\/ END \/\/\/\/\/\/\/\/\/\/\');END IF;EXCEPTIONWHEN not_in_awr THENdbms_output.put_line(chr(10));dbms_output.put_line('====================================================================================================================');dbms_output.put_line('!!! ONE OR MORE TABLESPACES USAGE INFORMATION NOT FOUND IN AWR !!!');dbms_output.put_line('Execute DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT, or wait for next AWR snapshot capture before executing this script');dbms_output.put_line('====================================================================================================================');END;//############################################# #
Post a Comment
Post a Comment