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
https://docs.oracle.com/cloud/latest/db112/REFRN/initparams075.htm#REFRN10307
http://www.dba-oracle.com/t_oracle_deferred_segment_creation.htm

Comentários
Postar um comentário