DEFERRED SEGMENT CREATION

A partir do Oracle 11g R2 foi introduzida uma nova funcionalidade que permite que as tabelas, indices e lobs não sejam criados até que uma linha seja inserida na respectiva tabela. Esta funcionalidade é controlada pelo parâmetro DEFERRED_SEGMENT_CREATION, que por padrão vem definido como true (ativo) a partir desta versão.
Esta funcionalidade tem como principal objetivo reduzir o espaço em disco e minimizar o tempo de criação de tabelas em uma nova implementação, por exemplo.

Tive um atendimento a um determinado cliente onde a aplicação estava apresentando erro de tabelas inexistentes após um reorg realizado pelo mesmo. Na atividade de reorg, foram criadas novas tablespaces e os dados foram movidos para as mesmas. Posteriormente as tablespaces antigas foram removidas apos ficaram offline por um determinado período.

Nesta situação, pude constatar que o problema ocorreu justamente devido ao parâmetro DEFERRED_SEGMENT_CREATION estar como true. Uma vez que o cliente baseou-se na dba_segments/dba_extents, para realizar a consulta de objetos a serem movidos e as tabelas que ainda não tinham dados inseridos não constavam na mesma.

Estarei demonstrando esse cenário em um exemplo pratico no qual será criada uma tabela lamimtst1 sem registros e uma segunda tabela lamimtst2 com registros, para demonstrar como ela não constará na dba_segments/dba_extents até que o primeiro registro seja inserido, independente da transação sofrer commit ou rollback.
SQL> conn lamim/lamim
Connected.
SQL> create tablespace lamimtst force logging datafile '/u01/lamimtst/datafiles/lamimtst01.dbf' size 100m autoextend on next 100m maxsize 1g;

Tablespace created.

SQL> show parameter DEFERRED_SEGMENT_CREATION;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
deferred_segment_creation            boolean     TRUE
SQL>
SQL> create table lamimtst1(fone number(9)) tablespace lamimtst;

Table created.

SQL> select owner, segment_name, tablespace_name from dba_segments where tablespace_name='LAMIMTST';

no rows selected

SQL> select OWNER, SEGMENT_NAME,TABLESPACE_NAME from dba_extents where tablespace_name='LAMIMTST';

no rows selected

SQL> create table lamimtst2(nome varchar2(20)) tablespace lamimtst;

Table created.

SQL> select owner, segment_name, tablespace_name from dba_segments where tablespace_name='LAMIMTST';

no rows selected

SQL> insert into lamimtst2 values ('Jhonata Lamim');

1 row created.

SQL> 
SQL> set lines 210
SQL> col segment_name for a45
SQL> select owner, segment_name, tablespace_name from dba_segments where tablespace_name='LAMIMTST';

OWNER                          SEGMENT_NAME                                  TABLESPACE_NAME
------------------------------ --------------------------------------------- ------------------------------
LAMIM                          LAMIMTST2                                     LAMIMTST
SQL> select OWNER, SEGMENT_NAME,TABLESPACE_NAME from dba_extents where tablespace_name='LAMIMTST';

OWNER                          SEGMENT_NAME         TABLESPACE_NAME
------------------------------ -------------------- ------------------------------
LAMIM                          LAMIMTST2            LAMIMTST

SQL>
SQL> rollback;

Rollback complete.

SQL> select owner, segment_name, tablespace_name from dba_segments where tablespace_name='LAMIMTST';

OWNER                          SEGMENT_NAME                                  TABLESPACE_NAME
------------------------------ --------------------------------------------- ------------------------------
LAMIM                          LAMIMTST2                                     LAMIMTST

SQL>
O problema do cliente ocorreu apos mover todos os objetos listados na dba_segments/dba_extents. Porém é possível mesmo com o parametro DEFERRED_SEGMENT_CREATION em true, especificar para que o segmento seja criado no momento da criação da tabela através do comando segment creation immediate. Ou caso o parametro esteja como false, podemos usar segment creation deffered para que o segmento não seja criado mesmo com o parametro definido como false.
SQL> show parameter DEFERRED_SEGMENT_CREATION;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
deferred_segment_creation            boolean     TRUE
SQL>
SQL> select owner, segment_name, tablespace_name from dba_segments where tablespace_name='LAMIMTST';

OWNER                          SEGMENT_NAME         TABLESPACE_NAME
------------------------------ -------------------- ------------------------------
LAMIM                          LAMIMTST2            LAMIMTST

SQL> create table LSMIMTST3 (CPF number(11)) segment creation immediate tablespace lamimtst;

Table created.

SQL> select owner, segment_name, tablespace_name from dba_segments where tablespace_name='LAMIMTST';

OWNER                          SEGMENT_NAME         TABLESPACE_NAME
------------------------------ -------------------- ------------------------------
LAMIM                          LAMIMTST2            LAMIMTST
LAMIM                          LSMIMTST3            LAMIMTST

SQL> alter system set deferred_segment_creation=false;

System altered.

SQL> create table LSMIMTST4 (CPF number(11)) segment creation deferred tablespace lamimtst;

Table created.

SQL> select owner, segment_name, tablespace_name from dba_segments where tablespace_name='LAMIMTST';

OWNER                          SEGMENT_NAME         TABLESPACE_NAME
------------------------------ -------------------- ------------------------------
LAMIM                          LAMIMTST2            LAMIMTST
LAMIM                          LSMIMTST3            LAMIMTST

SQL> create table LSMIMTST5 (CPF number(11)) tablespace lamimtst;

Table created.

SQL> select owner, segment_name, tablespace_name from dba_segments where tablespace_name='LAMIMTST';

OWNER                          SEGMENT_NAME         TABLESPACE_NAME
------------------------------ -------------------- ------------------------------
LAMIM                          LAMIMTST2            LAMIMTST
LAMIM                          LSMIMTST3            LAMIMTST
LAMIM                          LSMIMTST5            LAMIMTST

SQL>
Fonte:
https://docs.oracle.com/cloud/latest/db112/REFRN/initparams075.htm#REFRN10307
http://www.dba-oracle.com/t_oracle_deferred_segment_creation.htm

Comentários