I was recently using an Oracle 9 database. It had an undo tablespace with 1 datafile, which was set to autoextend. However, it could not do so as the file system it was on was full. This produced an ORA-30036 error. I decided to demonstrate this on Oracle 11.1.0.6.0 running on Windows XP. First I created a 500k undo tablespace. By the time I ran the SQL below, it had grown to 647168 bytes:
SQL> l
1 select file_name, bytes, autoextensible
2 from dba_data_files
3* where tablespace_name = 'UNDOTBS2'
SQL> /
FILE_NAME BYTES AUT
-------------------- ---------- ---
A:\UNDOTBS2.DBF 647168 YES
SQL>
Notice that it is on the A: drive. This is the 3.5” floppy disk drive (remember them?). It contained a 720k disk. I did this on purpose to stop the undo tablespace growing any bigger than that. I told the database to use this new undo tablespace:
SQL> alter system set undo_tablespace = undotbs2;
System altered.
SQL>
Then I tried to create a table but Oracle returned an ORA-30036:
SQL> create table fred
2 as select * from dba_tables
3 /
as select * from dba_tables
*
ERROR at line 2:
ORA-00604: error occurred at recursive SQL level 1
ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS2'
SQL>
The following errors appeared in the alert log:
Sun Sep 09 23:43:01 2012
GATHER_STATS_JOB encountered errors. Check the trace file.
Errors in file c:\app\andrew\diag\rdbms\orcl\orcl\trace\orcl_j003_2916.trc:
ORA-00604: error occurred at recursive SQL level 2
ORA-30036: unable to extend segment by 8 in undo tablespace 'UNDOTBS2'
Sun Sep 09 23:44:48 2012
Thread 1 advanced to log sequence 37
Current log# 1 seq# 37 mem# 0: C:\APP\ANDREW\ORADATA\ORCL\REDO01.LOG
Mon Sep 10 00:06:16 2012
ORA-1652: unable to extend temp segment by 8 in tablespace UNDOTBS2
Mon Sep 10 00:13:05 2012
And when I looked at the floppy disk in Windows, it was full:
If this happens to you, you need to add an extra datafile to the undo tablespace (on a file system with enough free space). Alternatively, you can extend the file system, although in this case it was not possible as a floppy disk has a finite size.
Showing posts with label undo_tablespace. Show all posts
Showing posts with label undo_tablespace. Show all posts
Sunday, September 09, 2012
ORA-30036
Labels:
720k,
A:,
alert log,
alter system,
autoextend,
autoextensible,
floppy disk,
ORA-00604,
ORA-1652,
ORA-30036,
Oracle 11.1.0.6.0,
Oracle 9,
undo,
undo_tablespace,
windows xp
Location:
West Sussex, UK
Monday, April 16, 2012
Oracle Flashback
This was introduced in Oracle 9. It allows you to query the database as it was at some recent point in the past.
You enable Flashback at the session level and use a system time or a system change number (SCN) to tell Oracle how far back to go. Then you will be able to see data which has been committed at that point.
This feature uses the Automatic Undo Management functionality. The undo_retention initialisation parameter tells Oracle how many seconds to keep undo information for. It therefore determines how far back you can go.
I produced the example below on an Oracle 10 database running on Linux. First check that undo_management is set to auto, that you have an undo tablespace and that the undo_retention parameter is large enough:
SQL> select name, value
2 from v$parameter
3 where name like '%undo%'
4 /
NAME VALUE
-------------------- --------------------
undo_management AUTO
undo_tablespace UNDOTBS1
undo_retention 900
SQL>
Then create a test user and give it permission to use dbms_flashback:
SQL> create user flash identified by gordon
2 default tablespace users
3 quota unlimited on users
4 temporary tablespace temp
5 /
User created.
SQL> grant create session,
2 create table to flash
3 /
Grant succeeded.
SQL> grant execute on dbms_lock to flash
2 /
Grant succeeded.
SQL> grant execute on dbms_flashback to flash
2 /
Grant succeeded.
SQL>
Create a table called time_now containing 1 row. This will be updated regularly with the current time:
SQL> conn flash/gordon
Connected.
SQL> create table time_now as
2 select sysdate current_time from dual
3 /
Table created.
SQL>
Also create a table called control_times. Whenever time_now is updated with sysdate, that sysdate will be inserted into control_times:
SQL> create table control_times
2 (control_time date)
3 /
Table created.
SQL>
Update time_now and insert into control_times as described above 20 times with a second between each iteration. As you do this, display the values updated and inserted:
SQL> declare
2 display_time date;
3 begin
4 for a in 1..20 loop
5 update time_now
6 set current_time = (select sysdate from dual);
7 commit;
8 insert into control_times values (sysdate);
9 commit;
10 select current_time
11 into display_time
12 from time_now;
13 dbms_output.put_line('Current Time: '||
14 to_char(display_time,'hh24:mi:ss'));
15 select max(control_time)
16 into display_time from control_times;
17 dbms_output.put_line('Control Time: '||
18 to_char(display_time,'hh24:mi:ss'));
19 dbms_output.put_line('**********');
20 dbms_lock.sleep(1);
21 end loop;
22 end;
23 /
Current Time: 00:01:32
Control Time: 00:01:32
**********
Current Time: 00:01:33
Control Time: 00:01:33
**********
Current Time: 00:01:34
Control Time: 00:01:34
**********
Current Time: 00:01:35
Control Time: 00:01:35
**********
Current Time: 00:01:36
Control Time: 00:01:36
**********
Current Time: 00:01:37
Control Time: 00:01:37
**********
Current Time: 00:01:38
Control Time: 00:01:38
**********
Current Time: 00:01:39
Control Time: 00:01:39
**********
Current Time: 00:01:40
Control Time: 00:01:40
**********
Current Time: 00:01:41
Control Time: 00:01:41
**********
Current Time: 00:01:42
Control Time: 00:01:42
**********
Current Time: 00:01:43
Control Time: 00:01:43
**********
Current Time: 00:01:44
Control Time: 00:01:44
**********
Current Time: 00:01:45
Control Time: 00:01:45
**********
Current Time: 00:01:46
Control Time: 00:01:46
**********
Current Time: 00:01:47
Control Time: 00:01:47
**********
Current Time: 00:01:48
Control Time: 00:01:48
**********
Current Time: 00:01:49
Control Time: 00:01:49
**********
Current Time: 00:01:50
Control Time: 00:01:50
**********
Current Time: 00:01:51
Control Time: 00:01:51
**********
PL/SQL procedure successfully completed.
SQL>
SQL> declare
2 display_time date;
3 cursor c1 is
4 select control_time from control_times
5 order by 1;
6 begin
7 for x in c1 loop
8 --
9 -- Try to flashback the database to each control_time:
10 --
11 dbms_flashback.enable_at_time(x.control_time);
12 dbms_output.put_line('Control Time: '||
13 to_char(x.control_time,'hh24:mi:ss'));
14 declare
15 unable_to_read_data exception;
16 pragma exception_init(unable_to_read_data,-01466);
17 consistent_read_failure exception;
18 pragma exception_init(consistent_read_failure,-08176);
19 begin
20 --
21 -- Now get the corresponding time from the TIME_NOW table.
22 -- It should be the same:
23 --
24 select current_time
25 into display_time from time_now;
26 dbms_output.put_line('Data Restored: '||
27 to_char(display_time,'hh24:mi:ss'));
28 dbms_output.put_line('**********');
29 dbms_flashback.disable;
30 exception
31 --
32 -- The flashback times are not always accurate
33 -- so you may not be able to read the table.
34 --
35 when unable_to_read_data then
36 dbms_output.put_line('Cannot read current_time from time_now');
37 dbms_output.put_line('**********');
38 dbms_flashback.disable;
39 when consistent_read_failure then
40 dbms_output.put_line('Consistent read failure');
41 dbms_output.put_line('**********');
42 dbms_flashback.disable;
43 end;
44 end loop;
45 end;
46 /
Control Time: 00:01:32
Cannot read current_time from time_now
**********
Control Time: 00:01:33
Cannot read current_time from time_now
**********
Control Time: 00:01:34
Data Restored: 00:01:34
**********
Control Time: 00:01:35
Data Restored: 00:01:34
**********
Control Time: 00:01:36
Data Restored: 00:01:34
**********
Control Time: 00:01:37
Data Restored: 00:01:37
**********
Control Time: 00:01:38
Data Restored: 00:01:37
**********
Control Time: 00:01:39
Data Restored: 00:01:37
**********
Control Time: 00:01:40
Data Restored: 00:01:40
**********
Control Time: 00:01:41
Data Restored: 00:01:40
**********
Control Time: 00:01:42
Data Restored: 00:01:40
**********
Control Time: 00:01:43
Data Restored: 00:01:43
**********
Control Time: 00:01:44
Data Restored: 00:01:43
**********
Control Time: 00:01:45
Data Restored: 00:01:43
**********
Control Time: 00:01:46
Data Restored: 00:01:46
**********
Control Time: 00:01:47
Data Restored: 00:01:46
**********
Control Time: 00:01:48
Data Restored: 00:01:46
**********
Control Time: 00:01:49
Data Restored: 00:01:49
**********
Control Time: 00:01:50
Data Restored: 00:01:49
**********
Control Time: 00:01:51
Data Restored: 00:01:49
**********
PL/SQL procedure successfully completed.
SQL>
Labels:
dbms_flashback,
dbms_lock,
Oracle 10,
Oracle 9,
Oracle Flashback,
SCN,
undo_management,
undo_retention,
undo_tablespace,
v$parameter
Location:
West Sussex, UK
Subscribe to:
Posts (Atom)