Friday, September 6, 2019

In defense of HCC: ORA-39726: unsupported add/drop column operation on compressed tables

A friend asked to check the

ISSUE:
ORA-39726 is hit when adding column with default value to basic compressed table.

CAUSE:
compressed table will not allow some operation, which are allowed in uncompressed table.


"Is there any error during add column with default value to table compressed with HCC ?
Does Oracle unpack HCC data during add column with default value to the table compressed with HCC ?"  he asked.

----------------------------------------------------------

And the answer is here.

RDBMS version is 12.1.0.2.171017 (i choosed old enough version i can find. newer versions belived work the same).

$ opatch lspatches
26635845;Database PSU 12.1.0.2.171017, Oracle JavaVM Component (OCT2017)
25729214;OCW Interim patch for 25729214
26717470;Database Bundle Patch : 12.1.0.2.171017 (26717470)



$ sqlplus / as sysdba
SQL> create tablespace yu extent management local segment space management auto;
SQL> create user yu identified by yu default tablespace yu;
SQL> grant dba to yu ;

SQL> conn yu/yu

SQL> create table NOCOMP as select owner,object_type,object_name,object_id,created from dba_objects order by owner,object_type,object_name;
insert into nocomp select * from nocomp;
insert into nocomp select * from nocomp;
insert into nocomp select * from nocomp;
insert into nocomp select * from nocomp;
commit;

Table created.

SQL>
151156 rows created.

SQL>
302312 rows created.

SQL>
604624 rows created.

SQL>
1209248 rows created.

SQL>
Commit complete.

SQL> select table_name from user_tables;

TABLE_NAME
--------------------------------------------
NOCOMP

SQL> select segment_name, bytes, bytes/1048576 MB, blocks from user_segments order by 1;

SEGMENT_NAME        BYTES   MB    BLOCKS
-------------- ---------- ------- ----------
NOCOMP          159383552   152   9728


SQL> create table BASICOMP compress as select * from NOCOMP;

create table OLTPCOMP  compress for OLTP as select * from NOCOMP;

create table QL   compress for query LOW as select * from NOCOMP;
create table QLRL compress for query LOW row level locking as select * from NOCOMP;

create table QH   compress for query HIGH as select * from NOCOMP;
create table QHRL compress for query HIGH row level locking as select * from NOCOMP;

create table AL   compress for archive LOW as select * from NOCOMP;
create table ALRL compress for archive LOW row level locking as select * from NOCOMP;

create table AH   compress for archive HIGH as select * from NOCOMP;
create table AHRL compress for archive HIGH row level locking as select * from NOCOMP;


Table created.

SQL>
Table created.

SQL> SQL>
Table created.

SQL>
Table created.

SQL> SQL>
Table created.

SQL>
Table created.

SQL> SQL>
Table created.

SQL>
Table created.

SQL> SQL>
Table created.

SQL>
Table created.

SQL> exec dbms_stats.gather_schema_stats('YU');
PL/SQL procedure successfully completed.

SQL> col segment_name for a8
SQL> select segment_name, bytes, bytes/1048576 MB, blocks from user_segments order by 2 desc;

SEGMENT_      BYTES        MB     BLOCKS
-------- ---------- ---------- ---------

NOCOMP    159383552       152       9728
OLTPCOMP  100663296        96       6144
BASICOMP   92274688        88       5632
QLRL       47185920        45       2880
QL         44040192        42       2688
QHRL       26214400        25       1600
ALRL       25165824        24       1536
QH         24117248        23       1472
AL         23068672        22       1408
AHRL       18874368        18       1152
AH         16777216        16       1024

SQL> col table_name for a8
SQL> select table_name,num_rows,blocks from user_tables order by blocks desc;

TABLE_NA   NUM_ROWS    BLOCKS
-------- ---------- ---------
NOCOMP      2418496      9652
OLTPCOMP    2418496      5799
BASICOMP    2418496      5211
QLRL        2418496      2848
QL          2418496      2670
QHRL        2418496      1577
ALRL        2418496      1492
QH          2418496      1456
AL          2418496      1400
AHRL        2418496      1148
AH          2418496      1010

SQL> 

alter table NOCOMP   add new_column number(3) default 0;
alter table BASICOMP add new_column number(3) default 0;
alter table OLTPCOMP add new_column number(3) default 0;
alter table QLRL     add new_column number(3) default 0;
alter table QL       add new_column number(3) default 0;
alter table QHRL     add new_column number(3) default 0;
alter table ALRL     add new_column number(3) default 0;
alter table QH       add new_column number(3) default 0;
alter table AL       add new_column number(3) default 0;
alter table AHRL     add new_column number(3) default 0;
alter table AH       add new_column number(3) default 0;
Table altered.

alter table BASICOMP add new_column number(3) default 0
                        *
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables

SQL>
Table altered.

SQL>
Table altered.

SQL>
Table altered.

SQL>
Table altered.

SQL>
Table altered.

SQL>
Table altered.

SQL>
Table altered.

SQL>
Table altered.

SQL>
Table altered.

SQL> exec dbms_stats.gather_schema_stats('YU');
PL/SQL procedure successfully completed.

SQL> col segment_name for a8
SQL> select segment_name, bytes, bytes/1048576 MB, blocks from user_segments order by 2 desc;

SEGMENT_      BYTES     MB   BLOCKS  BLOCKS before add column
-------- ---------- ------- ------- --------------------------

NOCOMP    159383552    152     9728    9728
OLTPCOMP  100663296     96     6144    6144
BASICOMP   92274688     88     5632    5632
QLRL       47185920     45     2880    2880
QL         44040192     42     2688    2688
QHRL       26214400     25     1600    1600
ALRL       25165824     24     1536    1536
QH         24117248     23     1472    1472
AL         23068672     22     1408    1408
AHRL       18874368     18     1152    1152
AH         16777216     16     1024    1024

SQL> col table_name for a8
SQL> select table_name,num_rows,blocks from user_tables order by blocks desc;

TABLE_NA   NUM_ROWS    BLOCKS   BLOCKS before add column

-------- ---------- ----------   ------------------------
NOCOMP      2418496      9652     9652
OLTPCOMP    2418496      5799     5799
BASICOMP    2418496      5211     5211
QLRL        2418496      2848     2848
QL          2418496      2670     2670
QHRL        2418496      1577     1577
ALRL        2418496      1492     1492
QH          2418496      1456     1456
AL          2418496      1400     1400
AHRL        2418496      1148     1148
AH          2418496      1010     1010


No one block is added after ADD COLUMN modification!

As you can see the only issue for BASIC COMPRESSION:

alter table BASICOMP add new_column number(3) default 0
                         *
ERROR at line 1:
ORA-39726: unsupported add/drop column operation on compressed tables

In other cases "alter table add column" work well: no decompression at all.
As the DOC 12.1.0.2 say:
"... the default value is stored as metadata, the column itself is not populated with data"




No comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Does DEALLOCATE UNUSED or SHRINK SPACE will free space occupied by LOB segment?

Lets check how it works. My env is DB 19.20@Linux-x64 1) I created the table with 4 LOB columns of 4 different LOB types: BASICFILE BLOB, BA...