My web app is acting very sluggish and it looks like its due to the database running out of table space. For the time being I'm using the SYSTEM user to connect my web app to the database which I know is not a good practice, but this is how it is for now. Anyone know how to increase the SYSTEM user tablespace using a Query? Maybe something can be done to clean up some of the SYSTEM tablespace? Turn off Auditing?
Get Tablespace Stats Query:
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;
Query Results:
TABLESPACE_NAME PERCENTAGE_USED SPACE_ALLOCATED SPACE_USED SPACE_FREE DATAFILES
SYSTEM 97.45 380 370.31 9.69 1
SYSAUX 94.48 740 699.19 40.81 1
UNDOTBS1 83.44 40 33.38 6.63 1
USERS 2.56 100 2.56 97.44 1
TEMP 0
SELECT FILE_NAME, TABLESPACE_NAME,BYTES
FROM DBA_DATA_FILES
WHERE TABLESPACE_NAME = 'SYSTEM';
ALTER DATABASE DATAFILE '<FILENAME>' RESIZE 500M;
example:
ALTER DATABASE DATAFILE '/u02/oracle/rbdb1/stuff01.dbf'
RESIZE 100M;
Related
qu = 'SELECT DS.TABLESPACE_NAME AS SCHEMA_NAME,
SEGMENT_NAME AS TABLE_NAME,
ROUND(SUM(DS.BYTES) / (1024 * 1024)) AS MB
FROM DBA_SEGMENTS DS
WHERE SEGMENT_NAME IN (SELECT TABLE_NAME
FROM DBA_TABLES)
GROUP BY DS.TABLESPACE_NAME, SEGMENT_NAME;'
When I'm executing this query in the synapse notebook, it says "missing right parenthesis".
Can anyone help pls?
Seems to be OK, unless you need to remove the terminating semi-colon:
... GROUP BY DS.TABLESPACE_NAME, SEGMENT_NAME;'
^
|
here
Query itself runs OK:
SQL> SELECT ds.tablespace_name AS schema_name,
2 segment_name AS table_name,
3 round(SUM(ds.bytes)/(1024 * 1024)) AS mb
4 FROM dba_segments ds
5 WHERE segment_name IN (SELECT table_name
6 FROM dba_tables
7 )
8 GROUP BY ds.tablespace_name,
9 segment_name;
SCHEMA_NAME TABLE_NAME MB
------------------------------ ---------- ----------
SYSTEM OBJ$ 2
SYSTEM UNDO$ 0
SYSTEM FILE$ 0
<snip>
I have a requirement to come up with a break down of the below
overall DWH SIZE
used space
free space
break down of space per schema (example STAGE,EDW/CORE,MART....) (point 1,2,3 must be covered)
4.1 - I am interested to see specifically all the schemas break down by total table size vs used size
(tables), i have tried the below queries (1 to 5)
upon checking various posts it's bit confusing
some suggests checking the following tables
DATA_SIZE (to check the data files)
TEMP_SIZE (to check the temporaryfiles)
SYS.V_$LOG (to check the redo log files)
V$CONTROLFILE (to check the redo log files) DBA_SEGMENTS
i have tested the below queries
Query 1 - actual size of the database
SELECT SUM (bytes) / 1024 / 1024 / 1024 AS GB FROM dba_data_files;
RESULT - GB
GB
900 - only example
Query 2 - Gives the size occupied by data in this database or Database usage details
SELECT SUM (bytes)/1024/1024/1024 AS GB FROM dba_segments;
RESULT- GB
GB
900 - only example
Query 3 - overall database size in TB
SELECT
( SELECT SUM(BYTES)/1024/1024/1024/1024 DATA_SIZE FROM DBA_DATA_FILES ) +
( SELECT NVL(SUM(BYTES),0)/1024/1024/1024/1024 TEMP_SIZE FROM DBA_TEMP_FILES ) +
( SELECT SUM(BYTES)/1024/1024/1024/1024 REDO_SIZE FROM SYS.V_$LOG ) +
( SELECT SUM(BLOCK_SIZE*FILE_SIZE_BLKS)/1024/1024/1024/1024 CONTROLFILE_SIZE FROM V$CONTROLFILE) "SIZE IN TB"
FROM
DUAL
RESULT- TB
SIZE IN TB
100 - only example
Query 4 - Database Size in TB with use space and free space Oracle DB
select round(sum(used.bytes) / 1024 / 1024 / 1024/1024 ) || 'TB' "Database Size"
, round(sum(used.bytes) / 1024 / 1024 / 1024/1024 ) -
round(free.p / 1024 / 1024 / 1024/1024) || 'TB' "Used space"
, round(free.p / 1024 / 1024 / 1024/1024) || 'TB' "Free space"
from (select bytes
from v$datafile
union all
select bytes
from v$tempfile
union all
select bytes
from v$log) used
, (select sum(bytes) as p
from dba_free_space) free
group by free.p
/
RESULT- TB
Database Size Used space Free space
100 90 10
Query 5 - QUERY TO GET SIZE OF ALL TABLES IN AN ORACLE DATABASE SCHEMA
SELECT * FROM
(
SELECT
OWNER,
OBJECT_NAME,
OBJECT_TYPE,
TABLE_NAME,
--ROUND(BYTES)/1024/1024 AS MB,
ROUND(BYTES) / 1024 / 1024 / 1024 AS GB,
--ROUND(100*RATIO_TO_REPORT(ROUND(BYTES) / 1024 / 1024 / 1024) OVER(),2) AS GB_PERCENT,
ROUND(100*RATIO_TO_REPORT(BYTES) OVER (), 2) PERCENTAGE,
TABLESPACE_NAME,
EXTENTS,
INITIAL_EXTENT,
ROUND(SUM(BYTES/1024/1024/1024) OVER (PARTITION BY TABLE_NAME)) AS TOTAL_TABLE_GB
--ROUND(SUM(BYTES)/1024/1024/1024) OVER (PARTITION BY TABLE_NAME)) AS TOTAL_TABLE_GB
FROM
(
--TABLES
SELECT OWNER, SEGMENT_NAME AS OBJECT_NAME, 'TABLE' AS OBJECT_TYPE,
SEGMENT_NAME AS TABLE_NAME, BYTES,
TABLESPACE_NAME, EXTENTS, INITIAL_EXTENT
FROM DBA_SEGMENTS /*DBA_SEGMENTS*/
WHERE SEGMENT_TYPE IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
UNION ALL
--INDEXES
SELECT I.OWNER, I.INDEX_NAME AS OBJECT_NAME, 'INDEX' AS OBJECT_TYPE,
I.TABLE_NAME, S.BYTES,
S.TABLESPACE_NAME, S.EXTENTS, S.INITIAL_EXTENT
FROM DBA_INDEXES I /*DBA_INDEXES*/
, DBA_SEGMENTS S /*DBA_SEGMENTS*/
WHERE S.SEGMENT_NAME = I.INDEX_NAME
AND S.OWNER = I.OWNER
AND S.SEGMENT_TYPE IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
--LOB SEGMENTS
UNION ALL
SELECT L.OWNER, L.COLUMN_NAME AS OBJECT_NAME, 'LOB_COLUMN' AS OBJECT_TYPE,
L.TABLE_NAME, S.BYTES,
S.TABLESPACE_NAME, S.EXTENTS, S.INITIAL_EXTENT
FROM DBA_LOBS L, /*DBA_LOBS*/
DBA_SEGMENTS S /*DBA_SEGMENTS*/
WHERE S.SEGMENT_NAME = L.SEGMENT_NAME
AND S.OWNER = L.OWNER
AND S.SEGMENT_TYPE = 'LOBSEGMENT'
--LOB INDEXES
UNION ALL
SELECT L.OWNER, L.COLUMN_NAME AS OBJECT_NAME, 'LOB_INDEX' AS OBJECT_TYPE,
L.TABLE_NAME, S.BYTES,
S.TABLESPACE_NAME, S.EXTENTS, S.INITIAL_EXTENT
FROM DBA_LOBS L, /*DBA_LOBS*/
DBA_SEGMENTS S /*DBA_SEGMENTS*/
WHERE S.SEGMENT_NAME = L.INDEX_NAME
AND S.OWNER = L.OWNER
AND S.SEGMENT_TYPE = 'LOBINDEX'
)
WHERE OWNER IN UPPER('&SCHEMA_NAME')
)
--WHERE TOTAL_TABLE_MB > 10
ORDER BY TOTAL_TABLE_GB DESC, GB DESC
/
EXPECTED_RESULTS
OWNER OBJECT_TYPE TOTAL_SPACE_GB TOTAL_SPACE_USED_GB PERCENTAGE_GB
DWH_STAGE TABLE 400 200 50
DWH_EDW TABLE 800 400 50
DWH_MART TABLE 1600 800 50
could you please suggest how to achieve this ?
This shows space within table segments if that is what you want but I think you probably want free space by tablespace instead.
select t.owner,'TABLE' OBJECT_TYPE ,t.TOTAL_SPACE_GB, u.TOTAL_SPACE_USED_GB,(u.TOTAL_SPACE_USED_GB/t.TOTAL_SPACE_GB)*100 PERCENTAGE_USED
from
(select owner,sum(bytes)/(1024*1024*1024) TOTAL_SPACE_GB
from dba_segments
where segment_type like 'TABLE%'
group by owner) t,
(select owner, sum(NUM_ROWS*AVG_ROW_LEN)/(1024*1024*1024) TOTAL_SPACE_USED_GB
from dba_tables
group by owner) u
where
t.owner=u.owner
order by owner;
Bobby
I need a way in Oracle to query the size of the segments as well as the amount of rows for all segment types which are a 'Table'.
Is there a way to combine the statement below (which calculates the size) and the 'count' function?
SELECT s.segment_type, (s.bytes / 1024 / 1024) mb, s.segment_name, l.*, s.*
FROM dba_segments s, dba_lobs l
where s.segment_name = l.segment_name(+)
and s.owner='TEST' order by bytes desc
If you have Oracle 12c (please always provide your database version info), you can use the new inline functions.
with function fRowCount(aOwner in varchar2, aTableName in varchar2) return number
is
lCount number;
begin
execute immediate 'select count(*) from ' || aOwner || '.' || aTableName into lCount;
return lCount;
end;
SELECT case when segment_type = 'TABLE' then fRowCount(s.owner, s.segment_name) else null end rowcount,
s.segment_type, (s.bytes / 1024 / 1024) mb, s.segment_name, l.*, s.*
FROM dba_segments s, dba_lobs l
where s.segment_name = l.segment_name(+)
and s.owner='TEST' order by bytes desc
Please be really really careful with that. execute immediate without the option of proper binding variables and to be executed as a dba is a dangerous combination.
If you have gathered the stats at schema level then information you are seeking for must be present in dba_tables.
You can gather the statistics of the schema using the following:
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('TEST');
After that, you can use the following query to fetch the desired result:
SELECT
S.SEGMENT_TYPE,
( S.BYTES / 1024 / 1024 ) MB,
DT.NUM_ROWS,
S.SEGMENT_NAME,
L.*,
S.*
FROM
DBA_SEGMENTS S
LEFT JOIN DBA_LOBS L ON ( S.SEGMENT_NAME = L.SEGMENT_NAME )
LEFT JOIN DBA_TABLES DT ON ( S.SEGMENT_NAME = DT.TABLE_NAME )
WHERE
S.OWNER = 'TEST'
ORDER BY
BYTES DESC
Note: Always use standard ANSI joins.
Cheers!!
Our oracle Oracle Enterprise manager database version is 12.1.0.2. I am trying to get all the tablespace total size,used_size, free_size in my below query. The query give me an error . With this query I wanna show below
1) target name, tablespacename, total_space,free_space, used_space in GB.
2) I want column alias name without comma
Wrote file afiedt.buf
1 select * from
2 ( select target_name,KEY_VALUE NAME
3 ,decode(column_label,'Tablespace Allocated Space (MB)' ,total_space
4 ,'Tablespace Free Space (MB)',free_space,'Tablespace Us
ed Space (MB)',used_space,column_label) as column_label
5 ,value
6 from sysman.mgmt$metric_current
7 where COLUMN_LABEL IN('Tablespace Allocated Space (MB)','Tablespace Used
Space (MB)','Tablespace Free Space (MB)')
8 and target_type = 'rac_database'
9 )
10 PIVOT(
11 MAX(VALUE)
12* FOR COLUMN_LABEL IN( 'total_space ','used_space','free_space'))
SQL> /
,'Tablespace Free Space (MB)',free_space,'Tablespace Used Sp
ace (MB)',used_space,column_label) as column_label
*
ERROR at line 4:
ORA-00904: "USED_SPACE": invalid identifier
SQL>
I think you want:
select * from
( select target_name,KEY_VALUE NAME
,decode(column_label,'Tablespace Allocated Space (MB)' ,'total_space'
,'Tablespace Free Space (MB)','free_space'
,'Tablespace Used Space (MB)','used_space'
,column_label) as column_label
,value
from sysman.mgmt$metric_current
where COLUMN_LABEL IN('Tablespace Allocated Space (MB)','Tablespace Used Space (MB)','Tablespace Free Space (MB)')
and target_type = 'rac_database'
)
PIVOT(
MAX(VALUE)
FOR COLUMN_LABEL IN( 'total_space','used_space','free_space'))
Although on my database (11g), I don't see the label "Tablespace Free Space (MB)"
Note, if you want free space for tablespaces, you could use dba_free_space:
select tablespace_name, sum(bytes)/1024/1024 as mb_free
from dba_free_space
group by tablespace_name;
I think you can simplify even further than #tbone's answer:
select *
from (
select column_label, key_value as tablespace_name, value
from sysman.mgmt$metric_current
where column_label in ('Tablespace Allocated Space (MB)',
'Tablespace Used Space (MB)', 'Tablespace Free Space (MB)')
and target_type = 'rac_database'
)
pivot (
max(value)
for column_label in ('Tablespace Allocated Space (MB)' as total_space,
'Tablespace Used Space (MB)' as used_space, 'Tablespace Free Space (MB)' as free_space)
)
/
Which (in 11gR2) gets output like:
TABLESPACE_NAME TOTAL_SPACE USED_SPACE FREE_SPACE
------------------------------ -------------------- -------------------- --------------------
SYSAUX 1770 1630.25
SYSTEM 730 727.125
TEMP 2009 0
UNDOTBS1 3469 20.5
USERS 832.25 54.0625
...
In this release the mgmt$metric_current table doesn't have an entry for free space; I can't currently check if that's been added in 12c, but you can calculate it from the other two of course.
if you want the values in GB instead of MD just divide by 1024 in the subquery, perhaps rounding to a sensible number of digits:
select *
from (
select column_label, key_value as tablespace_name,
round(to_number(value)/1024, 2) as value
from sysman.mgmt$metric_current
where column_label in ('Tablespace Allocated Space (MB)',
'Tablespace Used Space (MB)', 'Tablespace Free Space (MB)')
and target_type = 'rac_database'
)
pivot (
max(value)
for column_label in ('Tablespace Allocated Space (MB)' as total_space,
'Tablespace Used Space (MB)' as used_space,
'Tablespace Free Space (MB)' as free_space)
)
/
TABLESPACE_NAME TOTAL_SPACE USED_SPACE FREE_SPACE
------------------------------ -------------------- -------------------- --------------------
UNDOTBS1 3.39 .02
TEMP 1.96 0
SYSAUX 1.73 1.59
USERS .81 .05
SYSTEM .71 .71
...
As #tbone also suggested, there are other views that would give you this information, but on my DB at least this is significantly slower:
select dfs.tablespace_name,
(select round(sum(ddf.bytes)/power(1024, 3), 2) from dba_data_files ddf
where ddf.tablespace_name = dfs.tablespace_name) as total_space,
(select round(sum(ds.bytes)/power(1024, 3), 2) from dba_segments ds
where ds.tablespace_name = dfs.tablespace_name) as used_space,
round(sum(dfs.bytes)/power(1024, 3), 2) as free_space
from dba_free_space dfs
group by dfs.tablespace_name
/
TABLESPACE_NAME TOTAL_SPACE USED_SPACE FREE_SPACE
------------------------------ -------------------- -------------------- --------------------
SYSAUX 1.73 1.59 .13
UNDOTBS1 3.39 .08 3.31
USERS .81 .05 .76
SYSTEM .71 .71 0
...
... and from a comment about sysman owning the table you're looking at, perhaps you can't see the DBA views when you're connected to EM.
You can put the pivot result into an inline view or CTE if you want to do further calculations on the results, like getting the percentage of space used:
with cte as (
select *
from (
select column_label, key_value as tablespace_name,
to_number(value)/1024 as value
from sysman.mgmt$metric_current
where column_label in ('Tablespace Allocated Space (MB)',
'Tablespace Used Space (MB)', 'Tablespace Free Space (MB)')
and target_type = 'rac_database'
)
pivot (
max(value)
for column_label in ('Tablespace Allocated Space (MB)' as total_space,
'Tablespace Used Space (MB)' as used_space,
'Tablespace Free Space (MB)' as free_space)
)
)
select tablespace_name, round(total_space, 2) as total_space,
round(used_space, 2) as used_space, round(free_space, 2) as free_space,
round(100 * used_space / total_space, 2) as pct_used
from cte;
In 11g this also lets you calculate the free space easily, from the total and used space:
with cte as (
select *
from (
select column_label, key_value as tablespace_name,
to_number(value)/1024 as value
from sysman.mgmt$metric_current
where column_label in ('Tablespace Allocated Space (MB)',
'Tablespace Used Space (MB)')
and target_type = 'rac_database'
)
pivot (
max(value)
for column_label in ('Tablespace Allocated Space (MB)' as total_space,
'Tablespace Used Space (MB)' as used_space)
)
)
select tablespace_name, round(total_space, 2) as total_space,
round(used_space, 2) as used_space,
round(total_space - used_space, 2) as free_space,
round(100 * used_space / total_space, 2) as pct_used
from cte;
TABLESPACE_NAME TOTAL_SPACE USED_SPACE FREE_SPACE PCT_USED
------------------------------ -------------------- -------------------- -------------------- ----------
UNDOTBS1 3.39 .02 3.37 .59
TEMP 1.96 0 1.96 0
SYSAUX 1.73 1.59 .14 92.1
USERS .81 .05 .76 6.5
SYSTEM .71 .71 0 99.61
...
I would like to understand why pipelined function is not returning any results
Any ideas what i am doing wrong here.
Giving credit where due to the Original Author
CREATE OR REPLACE PACKAGE MANAGE_SPACE AS
--Author Tanmay
g_tblspce_threshold number := 80;
TYPE tblespaces_record IS RECORD(
tablespace_name VARCHAR2(30),
percentage_used NUMBER
);
TYPE tblespaces_table IS TABLE OF tblespaces_record;
function list_tblspcs_excd_thresld
return tblespaces_table PIPELINED ;
END MANAGE_SPACE;
Package body
CREATE OR REPLACE PACKAGE BODY MANAGE_SPACE
AS
--Author Tanmay
FUNCTION list_tblspcs_excd_thresld
RETURN tblespaces_table PIPELINED
AS
tblspaces tblespaces_record;
BEGIN
for x in (SELECT a.tablespace_name tablespace_name,
ROUND (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES) * 100) percentage_used
into tblspaces
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
AND ROUND (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES) * 100) > g_tblspce_threshold
ORDER BY NVL (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES), 0) DESC)
loop
PIPE ROW (tblspaces);
end loop;
return;
END list_tblspcs_excd_thresld;
END MANAGE_SPACE;
executing this package does not return any rows
SQL> select * from table(MANAGE_SPACE.list_tblspcs_excd_thresld())
2
SQL> /
TABLESPACE_NAME PERCENTAGE_USED
------------------------------ ---------------
What am i doing wrong
You need to populate an array. The easiest way to do this is to use the BULK COLLECT syntax. Then loop round the array and pipe out rows.
Here is my revised version of your package.
CREATE OR REPLACE PACKAGE BODY MANAGE_SPACE
AS
FUNCTION list_tblspcs_excd_thresld
RETURN tblespaces_table PIPELINED
AS
-- collection type not record type
tblspaces tblespaces_table;
BEGIN
select *
-- populate the collection
bulk collect into tblspaces
from
(SELECT a.tablespace_name tablespace_name,
ROUND (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES) * 100) percentage_used
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
AND ROUND (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES) * 100) > g_tblspce_threshold
ORDER BY NVL (((c.BYTES - NVL (b.BYTES, 0)) / c.BYTES), 0) DESC);
-- loop round the collection
for i in 1..tblspaces.count()
loop
PIPE ROW (tblspaces(i));
end loop;
return;
END list_tblspcs_excd_thresld;
END MANAGE_SPACE;
Here is the output:
SQL> select * from table(MANAGE_SPACE.list_tblspcs_excd_thresld())
2 /
TABLESPACE_NAME PERCENTAGE_USED
------------------------------ ---------------
SYSTEM 100
SYSAUX 91
APEX_2614203650434107 90
EXAMPLE 87
USERS 82
SQL>
#a_horse_with_no_name makes a good point regarding memory consumption. Collections are held in the session's memory space, the PGA. In this particular case it is unlikely that a database would have enough tablespaces to blow the PGA limit. But for other queries which might have much larger result sets there is the BULK COLLECT ... LIMIT syntax, which allows us to fetch manageable chunks of the result set into our collection. Find out more.