Thursday, February 18, 2016

Creating Tables in the UNDO Tablespace??

I was reading an article written by Martin Widlake in Oracle Scene Issue 58 (Autumn/Winter 2015). It said:

The second new item is the UNDO tablespace. This is a special tablespace that is only used for internal purposes and one that users cannot put any tables or indexes into.

This seemed perfectly reasonable so I wondered what might happen if I tried to do it. In an Oracle 9.2.0.7 database Oracle returned an error:

SQL> create table tab1
  2  (col1 number)
  3  tablespace undo_1
  4  /
create table tab1
*
ERROR at line 1:
ORA-30022: Cannot create segments in undo tablespace

SQL>

In an Oracle 11.2.0.1 database, I was not allowed to use the UNDO tablespace as a user’s default tablespace:

SQL> l
  1  create user andrew
  2  identified by reid
  3* default tablespace undotbs1
SQL> /
create user andrew
*
ERROR at line 1:
ORA-30033: Undo tablespace cannot be specified as
default user tablespace

SQL>

... but I was allowed to create a table in it:

SQL> create table tab1
  2  (col1 number)
  3  tablespace undotbs1
  4  /

Table created.

SQL> 

Does anybody know if this is a bug? I will update this post if I find out.

Postscript written on 19th February 2016:

I wrote the post above yesterday and, if you check the comments below, you will see that a couple of people have now helped me to understand what happened. It was all down to deferred segment creation. I have discussed this before here and here (and other places too) but it still catches me out from time to time. I returned to the Oracle 11.2.0.1 database and ran Andrzej’s SQL for confirming that UNDOTBS1 was an UNDO tablespace:

SQL> select contents from dba_tablespaces
  2  where tablespace_name = 'UNDOTBS1'
  3  /

CONTENTS
---------
UNDO

SQL>

Then I confirmed that deferred segment creation was turned on:

SQL> l
  1  select value from v$parameter
  2* where name = 'deferred_segment_creation'
SQL> /

VALUE
--------------------
TRUE

SQL>

I created another table in the UNDO tablespace:

SQL> create table dom (col1 number)
  2  tablespace undotbs1
  3  /

Table created.

SQL>

That worked but, as Dom suggested, when I tried to insert a row, Oracle needed to create a segment and was unable to do so:

SQL> insert into dom values (1)
  2  /
insert into dom values (1)
            *
ERROR at line 1:
ORA-30022: Cannot create segments in undo tablespace

SQL>

Finally, I turned deferred segment creation off:

SQL> l
  1  alter session
  2* set deferred_segment_creation = false
SQL> /

Session altered.

SQL>

Once I had done that, I was unable to create a table in the UNDO tablespace at all:

SQL> create table andrzej (col1 number)
  2  tablespace undotbs1
  3  /
create table andrzej (col1 number)
*
ERROR at line 1:
ORA-30022: Cannot create segments in undo tablespace

SQL>

I’m guessing that when Andrzej created his example, deferred_segment_creation was set to false at the session level as above, at the system level like this:

SQL> alter system set deferred_segment_creation = false
  2  /

System altered.

SQL>

Or via an initialisation parameter in his database’s parameter file.

5 comments:

Martin Widlake said...

Ohh!!! Interesting.

Thanks for the name check, BTW. I'll try and check this out in a couple of weeks when life calms down. end-of-a-book hell.

Andrzej Nowicki said...

SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production

SQL> create table tab1 (col1 number) tablespace undotbs1;
create table tab1 (col1 number) tablespace undotbs1
*
ERROR at line 1:
ORA-30022: Cannot create segments in undo tablespace


SQL> select contents from dba_tablespaces where tablespace_name='UNDOTBS1';

CONTENTS
---------
UNDO

Dom Brooks said...

Deferred segment creation... Try inserting a row.

Andrew Reid said...

Thank you for your comments. I have now corrected the post.

Andrzej Nowicki said...

Actually, I had deferred_segment_creation set to TRUE, but still I wasn't able to create a table in UNDO tbsp.
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - Production
PL/SQL Release 11.2.0.2.0 - Production
CORE 11.2.0.2.0 Production
TNS for Linux: Version 11.2.0.2.0 - Production
NLSRTL Version 11.2.0.2.0 - Production

SQL> select value from v$parameter where name='deferred_segment_creation';

VALUE
------------------
TRUE

SQL> create table tab1 (col1 number) tablespace undotbs1;
create table tab1 (col1 number) tablespace undotbs1
*
ERROR at line 1:
ORA-30022: Cannot create segments in undo tablespace


It seems to behave differently in 11.2.0.1 and 11.2.0.2, however I don't have any databases running 11.2.0.1 at the moment, so I can't confirm.