Finding extents of Oracle BIN$ segments
Question
I am looking for information on recyclebin extents.
When dropping a table its segments are renamed to 'BIN$...' system generated names and the extents are hidden.
Will those extents still stop me from shrinking a data file (or tablespace)? If so I would like to account for them in the script.
Currently I am using a query inspired by AskTom's maxshrink.sql:
select tbs.TABLESPACE_NAME, df.FILE_NAME,
round(MAX(e.BLOCKS+e.BLOCK_ID+1)*tbs.BLOCK_SIZE/1024/1024,2) "MinMB",
round(MAX(df.BYTES)/1024/1024,2) "FileMB"
from DBA_TABLESPACES tbs
LEFT JOIN DBA_DATA_FILES df on tbs.TABLESPACE_NAME = df.TABLESPACE_NAME
LEFT JOIN DBA_EXTENTS e on df.FILE_ID = e.FILE_ID AND df.RELATIVE_FNO = e.RELATIVE_FNO
-- WHERE
-- tbs.TABLESPACE_NAME like 'MY%'
GROUP BY df.FILE_ID, df.RELATIVE_FNO, tbs.TABLESPACE_NAME, tbs.BLOCK_SIZE, df.FILE_NAME
ORDER BY 1,2;
Update: Initially my question also asked why I no longer see the 'BIN$' segments created by Flashback Drop Table anymore in 12.2 anymore. However that was an error on my side, my test tables had simply no segments to begin with.
Solution
create table bp.t1 as select * from dba_users;
drop table bp.t1;
select owner, object_name, original_name from dba_recyclebin where owner = 'BP';
OWNER OBJECT_NAME ORIGINAL_NAME
----- ------------------------------- -------------
BP BIN$XY0E/EKVFyXgU0cBqMCr3Q==$0 T1
select * from dba_extents where owner = 'BP';
no rows selected
Removing (commenting out) the filter from the relevant part of the definition of DBA_EXTENTS
that filters dropped objects:
select
ds.owner, ds.segment_name, ds.partition_name, ds.segment_type,
ds.tablespace_name,
e.ktfbueextno, f.file#, e.ktfbuebno,
e.ktfbueblks * ds.blocksize, e.ktfbueblks, e.ktfbuefno
from
sys.sys_dba_segs ds, sys.x$ktfbue e, sys.file$ f
where
e.ktfbuesegfno = ds.relative_fno
and e.ktfbuesegbno = ds.header_block
and e.ktfbuesegtsn = ds.tablespace_id
and ds.tablespace_id = f.ts#
and e.ktfbuefno = f.relfile#
and bitand(NVL(ds.segment_flags, 0), 1) = 1
--and bitand(NVL(ds.segment_flags,0), 65536) = 0
and ds.owner = 'BP';
OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME KTFBUEEXTNO FILE# KTFBUEBNO E.KTFBUEBLKS*DS.BLOCKSIZE KTFBUEBLKS KTFBUEFNO
----- ------------------------------ -------------- ------------------ --------------- ----------- ---------- ---------- ------------------------- ---------- ----------
BP BIN$XY0E/EKVFyXgU0cBqMCr3Q==$0 TABLE USERS 0 4 128 65536 8 4
OTHER TIPS
Do you know since when those segments are hidden(?), and is there a way to actually find their extents?
You can find their details from *_SEGMENTS
views/synonyms.
SQL> select bytes from user_segments where segment_name='BIN$XYbYSYopQFTgUzIUqMA4vA==$0';
BYTES
----------
65536
Will those extents still stop me from shrinking a data file (or tablespace)?
Yes, they may stop you to shrink the data files. Dropped tables and any associated objects such as indexes, constraints, nested tables, and other dependent objects are not moved, they are simply renamed with a prefix of BIN$
.
Consider the following(it's just for demonstration purpose only) example.
SQL> conn sys@orclpdb as sysdba
Enter password:
Connected.
SQL> create tablespace tbs1 datafile size 1M;
Tablespace created.
SQL> alter user jay quota unlimited on tbs1;
User altered.
SQL> create table t1(id number, col1 varchar2(100)) tablespace tbs1;
Table created.
SQL> insert into t1 select level, 'dsfldshfkjdhsfkdshfdklsjfhdkhfdks'||level
from dual connect by level<=1000;
1000 rows created.
SQL> commit;
Commit complete.
SQL> select bytes from user_segments where segment_name='T1';
BYTES
----------
983040
SQL> conn sys@orclpdb as sysdba
Enter password:
Connected.
SQL> select ts#, name from v$tablespace;
TS# NAME
---------- ------------------------------
10 TBS1
1 rows selected.
SQL> select bytes from v$datafile where ts#=10;
BYTES
----------
1048576
SQL> select file# from v$datafile where ts#=10;
FILE#
----------
55
SQL> conn jay@orclpdb
Enter password:
Connected.
SQL> drop table t1;
Table dropped.
SQL> select object_name from recyclebin;
OBJECT_NAME
--------------------------------------------------------------------------------
BIN$XYY3afBNKwPgUzIUqMAIkA==$0
BIN$XYYmdj0XKLjgUzIUqMB2iA==$0
SQL> conn sys@orclpdb as sysdba
Enter password:
Connected.
SQL> alter database datafile 55 resize 512K;
alter database datafile 55 resize 512K
*
ERROR at line 1:
ORA-03297: file contains used data beyond requested RESIZE value
SQL> conn jay@orclpdb
Enter password:
Connected.
SQL> purge recyclebin;
Recyclebin purged.
SQL> conn sys@orclpdb as sysdba
Enter password:
Connected.
SQL> alter database datafile 55 resize 512K;
Database altered.
Hm, on my 12.2 system I see no BIN$ segments in *_SEGMENTS views (with SYS as SYSDBA user). And I think they never showed up in *_EXTENTS, or?
There is no recycle bin for SYSDBA privilege.
Each user can be thought of as having his own recycle bin, since unless a user has the SYSDBA privilege, the only objects that the user has access to in the recycle bin are those that the user owns. What is Recycle Bin?