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