Thursday, December 29, 2011

ORA-39726: unsupported add/drop column operation on compressed tables

Problem Description
While dropping a column on compressed table it fails with ORA-39726.
An example is demonstrated below.

SQL> alter table arjut compress;

Table altered.

SQL> alter table arjut move nocompress;

Table altered.

SQL> alter table arjut add c2  varchar2(100);

Table altered.

SQL> alter table arjut drop column c2;
alter table arjut drop column c2
                              *
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables

Cause of the Problem
Oracle is not intelligent enough to drop column on compressed table. For compressed column we can't drop the column straightforward. In order to drop column on compressed table, first we need to make the column unused and then drop the unused column.

Solution of the Problem
SQL> alter table arjut set unused column c2;

Table altered.

SQL> alter table arjut drop unused columns;

Table altered.

SQL> desc arjut
 Name                                                                          Null?    Type
 ----------------------------------------------------------------------------- -------- -------------------
 A                                                                                      NUMBER

ORA-00600: internal error code, arguments: [psdmsc.c: spawned type invalid]

Problem Description
While compiling a package using "alter package ... compile" statement containing a pipelined function whose return type is based on a table belonging to a different schema may fail with:

ORA-00600: internal error code, arguments: [psdmsc.c: spawned type invalid]

When a similar package exists in a third schema. The error occurs when PL/SQL attempts to generate the global collection type for the function return type in the current schema.

The same error may also be seen in a database trace file, though not reported back to the client, when the package is first created.

With an example this issue is as follows:
SQL> grant create session, resource to u identified by u;

Grant succeeded.

SQL> grant create session, resource to u1 identified by u1;

Grant succeeded.

SQL> grant create session, resource to u2 identified by u2;

Grant succeeded.

SQL> connect u/u
Connected.
SQL> create table u_table ( id number , value varchar2(100));

Table created.

SQL> grant select on u_table to u1;

Grant succeeded.

SQL> grant select on u_table to u2;

Grant succeeded.

SQL>
SQL> connect u1/u1
Connected.
SQL> create or replace package u_pkg as
  2    type u_tab is table of u.u_table%rowtype;
  3    function f_u return u_tab pipelined;
  4  end;
  5  /

Package created.

SQL> alter package u_pkg compile;

Package altered.

SQL> connect u2/u2
Connected.
SQL> create or replace package u_pkg as
  2    type u_tab is table of u.u_table%rowtype;
  3    function f_u return u_tab pipelined;
  4  end;
  5
  6  /

Package created.

SQL> alter package u_pkg compile;
alter package u_pkg compile
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [psdmsc.c: spawned type invalid], [], [], [], [], [], [], []

Cause of the Problem
This issue is due to Oracle bug. Oracle named this bug as 8425548. From the trace file we see following:

ksedst, dbkedDefDump, ksedmp, ksfdmp,
dbkeIncDump_kgsf, kgerinv_internal, kgerinv, kserin, psdtygen,
pcitygen, phpcmp, pcicmp0, kkxcmp0, rpiswu2, kkxcmp, kkpcrt, opiexe,
opiosq0, kpooprx, kpoal8, opiodr, ttcpip, opitsk, opiino, opiodr,
opidrv, sou2o, opimai_real


The reason it only fails when pipelined is because it has to create corresponding global types to match the plsql ones in order to allow it to be called from sql. As with the referenced bug something is going wrong with respect to these types.

Solution of the Problem
As the owner of the table on which the function's return type is based, manually GRANT EXECUTE ON..WITH GRANT OPTION to the system generated object type that matches the table%rowtype definition.

Run following query in order to find the extra object name created by owner u to which grant permission is needed.
SQL> set lines 140
SQL> col object_name for a40
SQL> select owner, object_name, object_type from dba_objects
  2    where owner IN ('U','U1','U2') and
  3          object_type = 'TYPE' and
  4          object_name like 'SYS_PLSQL_%';

OWNER                          OBJECT_NAME                              OBJECT_TYPE
------------------------------ ---------------------------------------- --------------------
U                              SYS_PLSQL_60110_18_1                     TYPE
U                              SYS_PLSQL_60110_DUMMY_1                  TYPE
U1                             SYS_PLSQL_60111_9_2                      TYPE
U1                             SYS_PLSQL_60111_DUMMY_2                  TYPE
U2                             SYS_PLSQL_60120_9_1                      TYPE
U2                             SYS_PLSQL_60120_DUMMY_1                  TYPE
Now connect as u user and execute grant permission.

SQL> conn u/u
Connected.

SQL> grant execute on SYS_PLSQL_60110_18_1 to U2 with grant option;

Grant succeeded.

SQL> conn u2/u2
Connected.
SQL> alter package u_pkg compile;

Package altered.

However this issue is fixed in patchset 11.2.0.3.

ALTER TABLE ADD COLUMN or mass UPDATE can be slow in ASSM

Problem Description
While adding a new column to a table by using statement alter table .. add statement with default clause it is horribly slow for large ASSM managed tables. Additionally large UPDATE DMLs may
be slow for ASSM segments.
For example following statement is taking a lot of time.

alter table horribly_slowtable add (new_column varchar2(100) default 'Test Value' not null);

Cause of the Problem
This slowness is identified as Oracle bug 6781367.

Solution of the Problem
Workaround of this solution is to use dbms_redefinition package while doing add column operation to the table. The online redefinition process is discussed in http://arjudba.blogspot.com/2008/11/how-to-convert-non-partitioned-table-to.html.

Based on the type of bug also you can consider first do reorganize the table and then do alter table add column operation. Reorganize table by using create table as select statement and then do the 'alter table add column default' operation.

This bug remained up to Oracle version 10.2.0.4 and below.

However this isssue is fixed in 10.2.0.5 (Server Patch Set) and 11.2 release.

Select query returns wrong result after ALTER TABLE ADD column and Index-only Joins

Problem Description
This is one of the pathetic Oracle bug I have ever seen as select query shows the wrong result. A simple select query shows wrong record! Can you imagine that? With demonstration I am showing this issue.
SQL> create table test_table (a number not null, b number not null, d number not null);

Table created.

SQL> alter table test_table add (c number default 10 not null);

Table altered.

SQL> create index test_table_ab on test_table (a,b);

Index created.

SQL> create index test_table_cd on test_table (c,d);

Index created.

SQL>
SQL> begin
  2   for i in 1..10 loop
  3    insert into test_table values(i,i*i,i,i*i);
  4   end loop;
  5   commit;
  6   -- stats
  7   dbms_stats.gather_table_stats(user,'test_table',cascade=>true);
  8   dbms_stats.set_table_stats(user,'test_table',numblks=>1000);
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL> set pages 100 lines 180
SQL> select a,c from test_table where c != 10;

         A          C
---------- ----------
         1         10
         2         10
         3         10
         4         10
         5         10
         6         10
         7         10
         8         10
         9         10
        10         10

10 rows selected.

SQL> set autot traceonly
SQL> select a,c from test_table where c != 10;

10 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 3602436212

-------------------------------------------------------------------------------------------
| Id  | Operation              | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |                  |     9 |    54 |     3   (0)| 00:00:01 |
|*  1 |  VIEW                  | index$_join$_001 |     9 |    54 |     3   (0)| 00:00:01 |
|*  2 |   HASH JOIN            |                  |       |       |            |          |
|   3 |    INDEX FAST FULL SCAN| TEST_TABLE_AB    |     9 |    54 |     1   (0)| 00:00:01 |
|*  4 |    INDEX FAST FULL SCAN| TEST_TABLE_CD    |     9 |    54 |     1   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("C"<>10)
   2 - access(ROWID=ROWID)
   4 - filter("C"<>10)


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        588  bytes sent via SQL*Net to client
        396  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         10  rows processed
whereas the expected result would be,
         A          C
---------- ----------
         1          1
         2          4
         3          9
         4         16
         5         25
         6         36
         7         49
         8         64
         9         81
        10        100
Cause of the Problem
This is serious Oracle bug which is identified as Bug 8509848. However this bug might not arises in all platforms. This bug observed in Oracle version 11.2.0.1 or below. This wrong result occurs whenever queries using index-only join if the table involved had undergone an ADD COLUMN.

Solution of the Problem
Workaround we can disable the use of index join by setting _index_join_enabled=false

alter system set "_index_join_enabled"=false scope=spfile;

However this issue is fixed in the following versions:

- 11.2.0.2 (Server Patch Set)
- 11.2.0.1 Patch 15 on Windows Platforms

So upgrading to these version will resolve the problem.

ALTER TABLE SHRINK operation is very slow with table contains LOB

ALTER TABLE ... SHRINK SPACE CASCADE is taking a very long time on a table with LOB columns.
Here goes some diagnostic analysis.

1. While querying v$session_longops view the Alter Table shrink operation is not listed there.

2. Any other session working on this table seems fine. Delay does not occur for others.

3. The 10046 dump, shows waits reading the datafiles 'db file sequential read' most of them on the the object 31324 which is the LOB:

OBJECT_NAME OBJECT_ID OBJECT_TYPE
---------------------------------------- ---------- -------------------
SYS_LOB0000032195C00001$$ 31324 LOB

This issue of slowness is identified as Oracle bug 5768710 and there is no workaround available. This bug found on Oracle database version 10.2.0.1, 10.2.0.2, 10.2.0.3 and 10.2.0.4. However this bug is fixed in the following releases:

- 10.2.0.3 Patch 13 on Windows Platforms
- 10.2.0.5 (Server Patch Set)
- 11.1.0.6 (Base Release)

So upgrade to any of these version will likely resolve this bug.

ORA-600 [25029] on ALTER TYPE MODIFY ELEMENT when type used in temporary table

Problem Description
Oracle is extremely buggy product. If you do anything in some different order horrible bug will appear. Here is one of them. ORA-600 [25029] occurs during ALTER of a TYPE having a VARRAY and dependent global temporary table.
SQL> create or replace type char_varray as varray(38) of varchar2(100);
  2  /

Type created.

SQL> create global temporary table char_tab(
  2       id                      VARCHAR2(100 char)
  3      ,des                 char_varray
  4      )  ON COMMIT PRESERVE ROWS;

Table created.

SQL> alter type char_varray modify element type varchar2(100 char) cascade;

Type altered.

SQL> alter type char_varray modify element type varchar2(130 char) cascade;
alter type char_varray modify element type varchar2(130 char) cascade
*
ERROR at line 1:
ORA-22324: altered type has compilation errors
ORA-22328: object "ARJU"."CHAR_TAB" has errors.
ORA-00600: internal error code, arguments: [25029], [2147483647], [], [], [], [], [], []

From the stack trace we see following stack.

STACK TRACE:
------------
kgeade <- kgeriv_int <- kgeriv <- kgesiv <- ksesic1 <- $cold_krtts2bz <- kkbllcs <- kkblclsi <- atbupar <- atbupg <- $cold_atbdrv <- rpiswu2 <- koktalt_dep_tabs <- 4976 <- koktalt <- $cold_opiexe <- opiosq0 <- kpooprx <- kpoal8 <- opiodr <- ttcpip <- opitsk <- opiino <- opiodr <- opidrv <- sou2o <- opimai_real <- ssthrdmain <- main <- main_opd_entry Cause of the Problem
This issue happened due to Oracle bug. Oracle numbered this bug as Bug 10224830.

Solution of the Problem
This issue is fixed in Oracle database patchset 11.2.0.3. There is no workaround available. So upgrade to your Oracle version is the only solution.

Sunday, December 25, 2011

ORA-00904: "SPECIFICATION": invalid identifier while moving XmlType CLOB

Problem Description
While using ALTER TABLE MOVE LOB statement to move an Xmltype CLOB to another tablespace fails with ORA-00904.
SQL> create table testxml (id number, specification sys.xmltype);

Table created.

SQL> alter table testxml move lob (specification) store as test_clob (tablespace users);
alter table testxml move lob (specification) store as test_clob (tablespace users)
                              *
ERROR at line 1:
ORA-00904: "SPECIFICATION": invalid identifier

Cause of the Problem
The syntax is not correct.
Solution of the Problem
Use the XMLDATA argument of the static function of the sys.XMLTYPE.createXML used to manipulate data in an XMLTYPE column.
SQL> alter table testxml move lob (specification.XMLDATA) store as test_clob (tablespace users);

Table altered.


SQL> col segment_name for a20
SQL>  select segment_name,segment_type,tablespace_name from dba_extents where segment_name='TEST_CLOB';

SEGMENT_NAME         SEGMENT_TYPE       TABLESPACE_NAME
-------------------- ------------------ ------------------------------
TEST_CLOB            LOBSEGMENT         USERS

Very poor performance for ALTER TABLE MOVE with many securefile lobs

Problem Description
While moving LOB segments using the statement as it is discussed in http://arjudba.blogspot.com/2008/09/how-to-move-lob-data-to-another.html we notice very poor performance in the database. The lob segments are moving very slowly. Since we are moving over millions of LOBs this causes significant performance impact. Since we are not doing online redefinition so DML are not allowed during this time. All LOBs are SecureFile enabled.

Cause of the Problem
The poor performance of moving SecureFile LOBs of large number of rows are due to Bug 8856478.

Solution of the Problem
This bug remained in Oracle version 11.2.0.1 and 11.1.0.7.
However this is fixed in the following version of Oracle.
1) 12.1 (Future Release)
2) 11.2.0.2 (Server Patch Set)
3) 11.2.0.1.2 (Patch Set Update)
4) 11.2.0.1 Bundle Patch 1 for Exadata Database
5) 11.1.0.7.5 (Patch Set Update)
6) 11.2.0.1 Patch 3 on Windows Platforms
7) 11.1.0.7 Patch 33 on Windows Platforms

So upgrade or install any of the above patch should resolve the problem.

ORA-22917: use VARRAY to define the storage clause for this column or attribute

Problem Description
While moving a LOB to another tablespace by ALTER TABLE MOVE LOB statement it fails with ORA-22917.

SQL> create type testtype1 as VARRAY (1000) of number;
  2  /

Type created.

SQL> create tablespace test1 datafile;

Tablespace created.

SQL> create table t (c1 testtype1) tablespace test1 VARRAY  c1 store as LOB (cache reads);

Table created.

SQL> alter table t move LOB  (c1) store as (tablespace users);
alter table t move LOB  (c1) store as (tablespace users)
                         *
ERROR at line 1:
ORA-22917: use VARRAY to define the storage clause for this column or attribute

Cause of the Problem
The error occurred due to the restriction on Varray Column Properties. You cannot specify TABLESPACE as part of the LOB parameters for a VARRAY column. The LOB tablespace for a VARRAY defaults to the containing table's tablespace.

Solution of the Problem

Solution 01: Move the table instead of moving the LOB column. As VARRAY defaults to containing table's tablespace so LOB column data will be moved to the new tablespace.

SQL> alter table t move tablespace users;

Table altered.

If LOB storage parameters need to be modified then use:

alter table t move tablespace users VARRAY c1 store as LOB [lob_segment_name] (Storage_clause);

Solution 02:
1) Export table and data from the current table.
2) Get DDL from the exported dump.
3)Get the script from step 2 and change the tablespace name and execute the changed script. At this phase table is created in the database.
4)Perform data pump import.

Alternatively you can use REMAP_TABLESPACE clause while doing import operation which is demonstrated in http://arjudba.blogspot.com/2008/12/import-fails-with-ora-39005-ora-31600.html