How to check Total, free space inside tablespace & datafiles in RAC Environment

Hi Mates,

Firstly I wish you a Happy New year.  Last year I was very happy as I started writing my blog. Even though I started this long time back I didn't start blogging as I felt that I need more experience.

This Year you will see me writing few contents related to oracle as I started learning it. Being SQL Server DBA I will maximum try to compare with it so that it can be handy.

As I am beginner most of the content shared will be copied from few sources.

I wanted my blog to be useful for daily Level 1 tasks. As the days grow by I will for sure dig deeper in to Oracle & will share interesting things possibly.

At the beginning when people asked me to work on space issues I was puzzled from where I should start as most of our environment are related to RAC.

 In RAC the storage will be managed by ASM so whenever we encounter space issues just like SQL Server we need to check whether there is space at OS level so to check that we can below query

SELECT name, free_mb/1024 FREE_GB, total_mb/1024 TOTAL_GB, free_mb/total_mb*100 as percentage FROM v$asm_diskgroup;

select name,
to_char(round(free_mb/1024, 2), 'FM99999.00') FREE_GB,
to_char(round(total_mb/1024, 2), 'FM99999.00') TOTAL_GB,
to_char(round(free_mb/total_mb*100, 2), 'FM99999.00') Percentage
FROM v$asm_diskgroup;

Once you know that there is enough space on the disk we can add a new data file to the table space.
Also you can check the consumption of all the table spaces usage using below query

set colsep |
set linesize 100 pages 100 trimspool on numwidth 14
col name format a25
col owner format a15
col "Used (GB)" format a15
col "Free (GB)" format a15
col "(Used) %" format a15
col "Size (M)" format a15
SELECT d.status "Status", d.tablespace_name "Name",
 TO_CHAR(NVL(a.bytes / 1024 / 1024 /1024, 0),'99,999,990.90') "Size (GB)",
 TO_CHAR(NVL(a.bytes - NVL(f.bytes, 0), 0)/1024/1024 /1024,'99999999.99') "Used (GB)",
 TO_CHAR(NVL(f.bytes / 1024 / 1024 /1024, 0),'99,999,990.90') "Free (GB)",
 TO_CHAR(NVL((a.bytes - NVL(f.bytes, 0)) / a.bytes * 100, 0), '990.00') "(Used) %"
 FROM sys.dba_tablespaces d,
 (select tablespace_name, sum(bytes) bytes from dba_data_files group by tablespace_name) a,
 (select tablespace_name, sum(bytes) bytes from dba_free_space group by tablespace_name) f WHERE
 d.tablespace_name = a.tablespace_name(+) AND d.tablespace_name = f.tablespace_name(+) AND NOT
 (d.extent_management like 'LOCAL' AND d.contents like 'TEMPORARY')
SELECT d.status
 "Status", d.tablespace_name "Name",
 TO_CHAR(NVL(a.bytes / 1024 / 1024 /1024, 0),'99,999,990.90') "Size (GB)",
 TO_CHAR(NVL(t.bytes,0)/1024/1024 /1024,'99999999.99') "Used (GB)",
 TO_CHAR(NVL((a.bytes -NVL(t.bytes, 0)) / 1024 / 1024 /1024, 0),'99,999,990.90') "Free (GB)",
 TO_CHAR(NVL(t.bytes / a.bytes * 100, 0), '990.00') "(Used) %"
 FROM sys.dba_tablespaces d,
 (select tablespace_name, sum(bytes) bytes from dba_temp_files group by tablespace_name) a,
 (select tablespace_name, sum(bytes_cached) bytes from v$temp_extent_pool group by tablespace_name) t
 WHERE d.tablespace_name = a.tablespace_name(+) AND d.tablespace_name = t.tablespace_name(+) AND
 d.extent_management like 'LOCAL' AND d.contents like 'TEMPORARY';

However if you want to know how many files are there inside each table space & how much has been filled up you can use below query

SELECT  Substr(df.tablespace_name,1,20) "Tablespace Name",
        Substr(df.file_name,1,80) "File Name",
        Round(df.bytes/1024/1024/1024,0) "Size (G)",
        decode(e.used_bytes,NULL,0,Round(e.used_bytes/1024/1024/1024,0)) "Used (G)",
        decode(f.free_bytes,NULL,0,Round(f.free_bytes/1024/1024/1024,0)) "Free (G)",
        decode(e.used_bytes,NULL,0,Round((e.used_bytes/df.bytes)*100,0)) "% Used"
       (SELECT file_id,
               sum(bytes) used_bytes
        FROM dba_extents
        GROUP by file_id) E,
       (SELECT sum(bytes) free_bytes,
        FROM dba_free_space
        GROUP BY file_id) f
WHERE    e.file_id (+) = df.file_id
AND      df.file_id  = f.file_id (+)
ORDER BY df.tablespace_name,

Finally you can add a new file by using the below command

ALTER tablespace USERS add datafile size 10g autoextend on maxsize 30g;

Even though we are using autoextend feature as we are specifying maxsize it wouldn't be any problem. In above case we are adding 10 GB file and and allowing to extend only up to 30 GB.

Note: if you want even temp tablespace files usage you can use the below query.

COMPUTE SUM OF a_byt t_byt f_byt ON REPORT
BREAK ON REPORT ON tablespace_name ON pf
COL tablespace_name FOR A17 TRU HEAD 'Tablespace|Name'
COL file_name FOR A40 TRU HEAD 'Filename'
COL a_byt FOR 9,990.999 HEAD 'Allocated|GB'
COL t_byt FOR 9,990.999 HEAD 'Current|Used GB'
COL f_byt FOR 9,990.999 HEAD 'Current|Free GB'
COL pct_free FOR 990.0 HEAD 'File %|Free'
COL pf FOR 990.0 HEAD 'Tbsp %|Free'
DEFINE b_div=1073741824
SELECT 1 seq, b.tablespace_name, nvl(x.fs,0)/y.ap*100 pf, b.file_name file_name,
b.bytes/&&b_div a_byt, NVL((b.bytes-SUM(f.bytes))/&&b_div,b.bytes/&&b_div) t_byt,
NVL(SUM(f.bytes)/&&b_div,0) f_byt, NVL(SUM(f.bytes)/b.bytes*100,0) pct_free
FROM dba_free_space f, dba_data_files b
,(SELECT y.tablespace_name, SUM(y.bytes) fs
FROM dba_free_space y GROUP BY y.tablespace_name) x
,(SELECT x.tablespace_name, SUM(x.bytes) ap
FROM dba_data_files x GROUP BY x.tablespace_name) y
WHERE f.file_id(+) = b.file_id
AND x.tablespace_name(+) = y.tablespace_name
and y.tablespace_name = b.tablespace_name
AND f.tablespace_name(+) = b.tablespace_name
GROUP BY b.tablespace_name, nvl(x.fs,0)/y.ap*100, b.file_name, b.bytes
SELECT 2 seq, tablespace_name,*100 pf, file_name, b.bytes/&&b_div a_byt,
a.bytes_used/&&b_div t_byt, a.bytes_free/&&b_div f_byt,
a.bytes_free/b.bytes*100 pct_free
FROM v$temp_space_header a, v$tempfile b
,(SELECT SUM(bytes_free) bf FROM v$temp_space_header) j
,(SELECT SUM(bytes) bb FROM v$tempfile) k
WHERE a.file_id = b.file#
ORDER BY 1,2,4,3;

As I am beginner there might be chance for errors so please feel free to me to correct.