2011-10-06 17 views
33

La nostra applicazione ha fallito alcune volte perché un 'ORA-01536: spazio di spazio superato per tablespace', e vorremmo essere in grado di impedirlo controllando regolarmente lo spazio libero sul tablespace e alzando un avviso quando scende al di sotto di un certo livello.Trova spazio libero sul tablespace

C'è un modo per scoprire quanto spazio libero è rimasto in un tablespace?

Dopo alcune ricerche (io non sono un DBA), ho provato la seguente:

select max_bytes-bytes from user_ts_quotas; 

select sum(nvl(bytes,0)) from user_free_space; 

ma le query restituire risultati completamente diversi.

risposta

68

Io uso questa query

column "Tablespace" format a13 
column "Used MB" format 99,999,999 
column "Free MB" format 99,999,999 
column "Total MB" format 99,999,999 
select 
    fs.tablespace_name       "Tablespace", 
    (df.totalspace - fs.freespace)    "Used MB", 
    fs.freespace        "Free MB", 
    df.totalspace        "Total MB", 
    round(100 * (fs.freespace/df.totalspace)) "Pct. Free" 
from 
    (select 
     tablespace_name, 
     round(sum(bytes)/1048576) TotalSpace 
    from 
     dba_data_files 
    group by 
     tablespace_name 
    ) df, 
    (select 
     tablespace_name, 
     round(sum(bytes)/1048576) FreeSpace 
    from 
     dba_free_space 
    group by 
     tablespace_name 
    ) fs 
where 
    df.tablespace_name = fs.tablespace_name; 
+1

Nizza - questo dà lo stesso numero di responsabile di impresa; eccezionale! Mi fido di questo ora =) –

+0

Ho provato e sembra che la lista non includerà un tablespace completamente completo perché non ci sono voci per esso in dba_free_space. (Sono su 10g) – xtsoler

23

Un molto più accurato SQL DICHIARAZIONE

SELECT a.tablespace_name, 
    ROUND (((c.BYTES - NVL (b.BYTES, 0))/c.BYTES) * 100,2) percentage_used, 
    c.BYTES/1024/1024 space_allocated, 
    ROUND (c.BYTES/1024/1024 - NVL (b.BYTES, 0)/1024/1024,2) space_used, 
    ROUND (NVL (b.BYTES, 0)/1024/1024, 2) space_free, 
    c.DATAFILES 
    FROM dba_tablespaces a, 
     ( SELECT tablespace_name, 
        SUM (BYTES) BYTES 
      FROM dba_free_space 
     GROUP BY tablespace_name 
     ) b, 
     ( SELECT COUNT (1) DATAFILES, 
        SUM (BYTES) BYTES, 
        tablespace_name 
      FROM dba_data_files 
     GROUP BY tablespace_name 
    ) c 
    WHERE b.tablespace_name(+) = a.tablespace_name 
    AND c.tablespace_name(+) = a.tablespace_name 
ORDER BY NVL (((c.BYTES - NVL (b.BYTES, 0))/c.BYTES), 0) DESC; 
+0

questo ha un tablespace TEMP, che non è stato visualizzato quando si utilizza la query dalla risposta – Dennis

+0

personalmente verificare che questo è abbastanza veloce. 6 secondi vs 188 secondi che hanno una query simile che abbiamo usato da qualche tempo fa., Su un database Oracle 12. – Zardoz89

+0

Mi dispiace, ma qual è l'unità di misura di cui stiamo parlando qui ..? –

9

Questa è una delle query più semplice per la stessa che mi sono imbattuto e lo usiamo per il monitoraggio e :

SELECT TABLESPACE_NAME,SUM(BYTES)/1024/1024/1024 "FREE SPACE(GB)" 
FROM DBA_FREE_SPACE GROUP BY TABLESPACE_NAME; 

Un articolo completo su Oracle Tablespace: Tablespace

8

Ci sono molti modi per controllare la dimensione, ma come sviluppatore noi non hanno molto accesso per interrogare le tabelle di meta, trovo questa soluzione molto facile (Nota: 'L'errore ORA-01653 è causato perché è necessario aumentare lo spazio su uno spazio tabella' se hai trovato il messaggio di errore ORA-01653 )

--Size of All Table Space 

--1. Used Space 
SELECT TABLESPACE_NAME,TO_CHAR(SUM(NVL(BYTES,0))/1024/1024/1024, '99,999,990.99') AS "USED SPACE(IN GB)" FROM USER_SEGMENTS GROUP BY TABLESPACE_NAME 
--2. Free Space 
SELECT TABLESPACE_NAME,TO_CHAR(SUM(NVL(BYTES,0))/1024/1024/1024, '99,999,990.99') AS "FREE SPACE(IN GB)" FROM USER_FREE_SPACE GROUP BY TABLESPACE_NAME 

--3. Both Free & Used 
SELECT USED.TABLESPACE_NAME, USED.USED_BYTES AS "USED SPACE(IN GB)", FREE.FREE_BYTES AS "FREE SPACE(IN GB)" 
FROM 
(SELECT TABLESPACE_NAME,TO_CHAR(SUM(NVL(BYTES,0))/1024/1024/1024, '99,999,990.99') AS USED_BYTES FROM USER_SEGMENTS GROUP BY TABLESPACE_NAME) USED 
INNER JOIN 
(SELECT TABLESPACE_NAME,TO_CHAR(SUM(NVL(BYTES,0))/1024/1024/1024, '99,999,990.99') AS FREE_BYTES FROM USER_FREE_SPACE GROUP BY TABLESPACE_NAME) FREE 
ON (USED.TABLESPACE_NAME = FREE.TABLESPACE_NAME); 

Grazie

0

A meno che non mi sbagli, il codice precedente non prende in considerazione lo spazio non allocato, quindi se vuoi davvero sapere quando raggiungerai un limite rigido, dovresti usare maxbytes.

Penso che il codice qui sotto lo faccia. Calcola lo spazio libero come "spazio libero" + spazio non allocato.

select 
    free.tablespace_name, 
    free.bytes, 
    reserv.maxbytes, 
    reserv.bytes, 
    reserv.maxbytes - reserv.bytes + free.bytes "max free bytes", 
    reserv.datafiles 
from 
    (select tablespace_name, count(1) datafiles, sum(maxbytes) maxbytes, sum(bytes) bytes from dba_data_files group by tablespace_name) reserv, 
    (select tablespace_name, sum(bytes) bytes from dba_free_space group by tablespace_name) free 
where free.tablespace_name = reserv.tablespace_name; 
1
column pct_free format 999.99 
select 
    used.tablespace_name, 
    (reserv.maxbytes - used.bytes)*100/reserv.maxbytes pct_free, 
    used.bytes/1024/1024/1024 used_gb, 
    reserv.maxbytes/1024/1024/1024 maxgb, 
    reserv.bytes/1024/1024/1024 gb, 
    (reserv.maxbytes - used.bytes)/1024/1024/1024 "max free bytes", 
    reserv.datafiles 
from 
    (select tablespace_name, count(1) datafiles, sum(greatest(maxbytes,bytes)) maxbytes, sum(bytes) bytes from dba_data_files group by tablespace_name) reserv, 
    (select tablespace_name, sum(bytes) bytes from dba_segments group by tablespace_name) used 
where used.tablespace_name = reserv.tablespace_name 
order by 2 
/
+0

Perché questa affermazione di sql è migliore delle altre? – rene

+2

Benvenuto in Stack Overflow! Le risposte al solo codice non sono molto utili. Modifica la tua risposta per spiegare perché il tuo codice risolve il problema originale. –