Diferenças de Reorganização de Objetos com Shrink em Banco de Dados Oracle 10g e 11g

O objetivo deste artigo é explicar como funciona a reorganização de objetos com o Shrink nas versões do Banco de Dados Oracle 10g e 11g funcionam.

“Reclamação de Espaço.”

O Banco de Dados Oracle possui uma reorganização dos dados para ótima utilização de espaço por encolhê-los (Shrink).
Encolhendo-os de um segmento faz disponível de espaço não utilizado para outros segmentos na tablespace e pode melhorar a performance de comandos SQL e operações DML.

A funcionalidade do Shrink do segmento ambos compacta o espaço usado num segmento e então desaloca eles do segmento.
O espaço desalocado é retornado para a tablespace e é disponível para outros objetos na tablespace.
Esparsamente tabelas populadas podem causar um problema de performance por um “full table scans”. Executando o Shrink, dados na tabela são compactados e a Marca D´água Alta do segmento é empurrado para baixo. Isto faz “full table scans” ler menos blocos mais rápido.

Encolhendo segmento é uma operação online. A tabela sendo encolhida é aberta para comandos SQL e operações DML enquanto o segmento está sendo encolhido.
Adicionalmente, encolher segmentos é executado no lugar. Isto é uma vantagem sobre redefinição de tabelas online para compactação e reclamação de espaço.
Pode-se agendar o Shrink do segmento por um ou todos objetos no banco de dados com Jobs noturnos e adicionais espaços são providos para o banco de dados.

Encolhendo segmentos trabalha em segmentos (heaps, IOTs, IOT overflow segments, LOBs, LOB segments, materialized views e indexes) com linha movimentada (row movement) habilitada nas tablespaces com o gerenciamento automático de espaço no segmento. Quando o Shrink do segmento é executado nas tabelas com indexes e outros, os indexes são automaticamente mantidos quando linhas são movidas para compactação. Triggers definidos não são disparados, entretanto, porque compactação é puramente uma operação física e não impacta a aplicação.

Nota:
Shrink do segmento pode ser executado somente em tabelas com linhas movimentadas habilitado. Aplicações que explicitamente faixa “rowids” de objetos não pode ser encolhidos, porque a aplicação faixa a localização física das linhas nos objetos isso para a versão 10g o que não ocorre na versão 11g.
Para facilitar a identidade, segmentos candidatos para Shrink, o Banco de Dados Oracle automaticamente executa o “Segment Advisor” para avaliar o banco de dados todo.
O “Segment Advisor” executa a análise das tendências de crescimento de objetos individuais para determinar se haverá algum espaço adicional no objeto em 7 dias.
Isso então usa a reclamação de espaço para selecionar os objetos candidatos para encolher.

Nota:
O “Segment Advisor” não analisa tablespaces de “UNDO” e “TEMPORARY TABLESPACES”.
Adicionalmente para usar as estatísticas pré-computadas no repositório do AWR, o “Segment Advisor” executa uma amostragem dos objetos sobre considerações para refinar as estatísticas para os objetos. Embora esta operação é mais recurso intensivo, isso pode ser usado para executar uma análise mais acurada.

Embora encolher segmentos reduz os encadeamentos das linhas, e o banco de dados Oracle recomenda a redefinição online para moder as linhas encadeadas, o “Segment Advisor” atualmente detecta certas linhas encadeadas que estão acima de um limite. Por exemplo, se o tamanho de uma linha aumenta durante uma atualização tal que isso não cabe mais no bloco, então o “Segment Advisor” recomenda que o segmento seja reorganizado para prover performance de I/O.

Nota:
O “Segment Advisor” não detecta linhas encadeadas creadas por inserções (inserts).

OBS: “Executar um Export e Import em uma tabelas com movimentação de linhas (row movement) ao ser importada a tabela a mesma é importada com o row movement desabilitado”.
“Utilizando o Datapump isso não ocorre, a tabela permanece com movimentação de linhas (row movement) habilitada”.
Vamos realizar os testes do shrink e verificar durante export / import, Datapump o status do row movement na tabela.

Vamos realizar o Shrink no banco de dados Oracle 10g primeiramente e após vamos executar no 11g.
Segue abaixo passo-a-passo a realização da reclamação de espaço.

Banco de Dados 10g.

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Release 10.2.0.1.0 - Production
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

SQL> select * from all_users where username='MASTER';

USERNAME                          USER_ID CREATED
------------------------------ ---------- ---------
MASTER                                 56 10-JAN-12

SQL> conn master/master
Connected.
SQL> desc user_dependencies;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 NAME                                      NOT NULL VARCHAR2(30)
 TYPE                                               VARCHAR2(17)
 REFERENCED_OWNER                                   VARCHAR2(30)
 REFERENCED_NAME                                    VARCHAR2(64)
 REFERENCED_TYPE                                    VARCHAR2(17)
 REFERENCED_LINK_NAME                               VARCHAR2(128)
 SCHEMAID                                           NUMBER
 DEPENDENCY_TYPE                                    VARCHAR2(4)
SQL>

Abaixo vamos verificar as dependências da tabela “PRODUCT” e verificar o estado dos objetos. Importante salientar que na versão 10g do Banco de Dados Oracle ao habilitar o row movement na Tabela, os objetos dependentes ficam inválidos.
Neste caso vamos verificar primeiramente as dependências da tabela a ser habilitada.

SQL> select name, type from user_dependencies where referenced_name='PRODUCT';

NAME                           TYPE
------------------------------ -----------------
P_PRODUCT                      PROCEDURE
TRG_PRODUCT                    TRIGGER

SQL> set lines 155
SQL> col OBJECT_NAME for a30
SQL> select object_name, object_type, status from user_objects;

OBJECT_NAME                    OBJECT_TYPE         STATUS
------------------------------ ------------------- -------
PRODUCT                        TABLE               VALID
PRD_ID_PK                      INDEX               VALID
PRD_ID_SEQ                     SEQUENCE            VALID
P_PRODUCT                      PROCEDURE           VALID
T_PRODUCT                      TABLE               VALID
PRD_ID_PK_T                    INDEX               VALID
TRG_PRODUCT                    TRIGGER             VALID

7 rows selected.

SQL>

Vamos verificar os registros e os blocos que estão sendo usados pela tabela “PRODUCT”.

SQL> select count(*) from product;

  COUNT(*)
----------
    293999

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
         1188                   0          293999

SQL>

Vamos remover algumas linhas da tabela e verificar os blocos novamente na Tabela.

 
SQL> delete from PRODUCT where prd_id >= 200000;

100001 rows deleted.

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
         1188                   0          293999

SQL> commit;

Commit complete.

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
         1188                   0          293999

SQL>

Não houve nenhuma mudança, portanto vamos computar as estatísticas da tabela e verificar os blocos após a análise e habilitar a tabela PRODUCT para movimentar as linhas (row movement).

SQL> analyze table PRODUCT compute statistics;

Table analyzed.

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
         1188                  92          193998

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
DISABLED

SQL> select name, type from user_dependencies where referenced_name='PRODUCT';

NAME                           TYPE
------------------------------ -----------------
P_PRODUCT                      PROCEDURE
TRG_PRODUCT                    TRIGGER

SQL> alter table PRODUCT enable row movement;

Table altered.

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
ENABLED

SQL>

Vamos visualizar os objetos após habilitar a tabela com “row movement”.

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

OBJECT_NAME                    OBJECT_TYPE         STATUS
------------------------------ ------------------- -------
P_PRODUCT                      PROCEDURE           INVALID
TRG_PRODUCT                    TRIGGER             INVALID

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
         1188                  92          193998

SQL>

Vamos compilar os objetos inválidos.

SQL> select 'ALTER '||decode(object_type,'PACKAGE BODY','PACKAGE',object_type)||' '||OWNER||'."'||OBJECT_NAME||'" COMPILE'||DECODE(OBJECT_TYPE,'PACKAGE BODY',' BODY','TRIGGER',' reuse settings')||';' OBJETO
FROM DBA_OBJECTS
WHERE STATUS = 'INVALID'
AND   OBJECT_TYPE not in ('UNDEFINED','SYNONYM')
AND   OBJECT_NAME not like 'BIN$%==$0'
order by owner||object_name,object_type
/  2    3    4    5    6    7

OBJETO
-----------------------------------------------------------------------------------------------------------------------------------------------------------
ALTER PROCEDURE MASTER."P_PRODUCT" COMPILE;
ALTER TRIGGER MASTER."TRG_PRODUCT" COMPILE reuse settings;

SQL> ALTER PROCEDURE MASTER."P_PRODUCT" COMPILE;

Procedure altered.

SQL> ALTER TRIGGER MASTER."TRG_PRODUCT" COMPILE reuse settings;

Trigger altered.

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

no rows selected

SQL>

Vamos encolher (shrink) a tabela “PRODUCT”, verificar o estado dos objetos dependentes e computar novamente as estatíscas após o “shrink”.

SQL> alter table PRODUCT shrink space;

Table altered.

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

no rows selected

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
         1188                  92          193998

SQL> analyze table PRODUCT compute statistics;

Table analyzed.

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
          759                  25          193998

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
ENABLED

SQL>!

Com o Shrink na tabela PRODUCT conseguimos salvar 3,875 MB de 10 MB de espaço no Segmento.
Vamos realizar o teste de exportar e importar a tabela para verificarmos se a mesma permanece com o “row movement” habilitado.
Após vamos realizar com o Datapump e conferir a tabela.

Exportando a Tabela com EXP.

[oracle@serveroracle ~]$ exp userid=master/master file=/home/oracle/export_table_product.dmp buffer=8192000 grants=n statistics=none;

Export: Release 10.2.0.1.0 - Production on Sun Jan 15 00:56:37 2012

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


Connected to: Oracle Database 10g Release 10.2.0.1.0 - Production
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses WE8ISO8859P1 character set (possible charset conversion)
Note: grants on tables/views/sequences/roles will not be exported

About to export specified users ...
. exporting pre-schema procedural objects and actions
. exporting foreign function library names for user MASTER
. exporting PUBLIC type synonyms
. exporting private type synonyms
. exporting object type definitions for user MASTER
About to export MASTER's objects ...
. exporting database links
. exporting sequence numbers
. exporting cluster definitions
. about to export MASTER's tables via Conventional Path ...
. . exporting table                        PRODUCT     193998 rows exported
. . exporting table                      T_PRODUCT     100000 rows exported
. exporting synonyms
. exporting views
. exporting stored procedures
. exporting operators
. exporting referential integrity constraints
. exporting triggers
. exporting indextypes
. exporting bitmap, functional and extensible indexes
. exporting posttables actions
. exporting materialized views
. exporting snapshot logs
. exporting job queues
. exporting refresh groups and children
. exporting dimensions
. exporting post-schema procedural objects and actions
. exporting statistics
Export terminated successfully without warnings.
[oracle@serveroracle ~]$ exit
exit

Dropando a Tabela PRODUCT.

SQL> drop table PRODUCT purge;

Table dropped.

SQL> select count(*) from PRODUCT;
select count(*) from PRODUCT
                     *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> !

Importando a Tabela PRODUCT com o IMP

[oracle@serveroracle ~]$ imp userid=master/master file=/home/oracle/export_table_product.dmp fromuser=master touser=master tables=PRODUCT statistics=none grants=n;

Import: Release 10.2.0.1.0 - Production on Sun Jan 15 00:58:29 2012

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


Connected to: Oracle Database 10g Release 10.2.0.1.0 - Production

Export file created by EXPORT:V10.02.01 via conventional path
import done in US7ASCII character set and AL16UTF16 NCHAR character set
import server uses WE8ISO8859P1 character set (possible charset conversion)
. importing MASTER's objects into MASTER
. . importing table                      "PRODUCT"     193998 rows imported
Import terminated successfully without warnings.
[oracle@serveroracle ~]$ exit
exit
SQL> select count(*) from PRODUCT;

  COUNT(*)
----------
    193998

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
DISABLED

SQL>

Como podemos perceber ao utilizar o EXP (EXPORT) e IMP (IMPORT) a tabela é importada com o “row movement” desabilitado.
Vamos agora exportar e importar a tabela via Datapump (EXPDP / IMPDP) e verificar se a tabela permanece com o “row movement” habilitado.
Com o usuário “SYS” vamos criar o diretório para a Exportação/ Importação da Tabela PRODUCT, garantir privilégios de leitura e gravação e Executar o Datapump.

SQL> disc
Disconnected from Oracle Database 10g Release 10.2.0.1.0 - Production
SQL> conn / as sysdba
Connected.

SQL> show user
USER is "SYS"
SQL> create directory DATAPUMP_MASTER as '/home/oracle';

Directory created.

SQL> grant read,write on directory DATAPUMP_MASTER to master;

Grant succeeded.

SQL> disc
Disconnected from Oracle Database 10g Release 10.2.0.1.0 - Production
SQL> conn master/master
Connected.
SQL> alter table PRODUCT enable row movement;

Table altered.

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
ENABLED

SQL> !
[oracle@serveroracle ~]$ expdp master/master directory=DATAPUMP_MASTER dumpfile=expdp_table_product.dmp tables=PRODUCT;

Export: Release 10.2.0.1.0 - Production on Sunday, 15 January, 2012 1:07:58

Copyright (c) 2003, 2005, Oracle.  All rights reserved.

Connected to: Oracle Database 10g Release 10.2.0.1.0 - Production
Starting "MASTER"."SYS_EXPORT_TABLE_01":  master/******** directory=DATAPUMP_MASTER dumpfile=expdp_table_product.dmp tables=PRODUCT
Estimate in progress using BLOCKS method...
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
Total estimation using BLOCKS method: 7 MB
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/INDEX/INDEX
Processing object type TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type TABLE_EXPORT/TABLE/TRIGGER
. . exported "MASTER"."PRODUCT"                          5.084 MB  193998 rows
Master table "MASTER"."SYS_EXPORT_TABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for MASTER.SYS_EXPORT_TABLE_01 is:
  /home/oracle/expdp_table_product.dmp
Job "MASTER"."SYS_EXPORT_TABLE_01" successfully completed at 01:08:27

[oracle@serveroracle ~]$ exit
exit
SQL> drop table PRODUCT purge;

Table dropped.

SQL> select count(*) from PRODUCT;
select count(*) from PRODUCT
                     *
ERROR at line 1:
ORA-00942: table or view does not exist


SQL> !
[oracle@serveroracle ~]$ impdp master/master directory=DATAPUMP_MASTER dumpfile=expdp_table_product.dmp tables=PRODUCT;

Import: Release 10.2.0.1.0 - Production on Sunday, 15 January, 2012 1:09:23

Copyright (c) 2003, 2005, Oracle.  All rights reserved.

Connected to: Oracle Database 10g Release 10.2.0.1.0 - Production
Master table "MASTER"."SYS_IMPORT_TABLE_01" successfully loaded/unloaded
Starting "MASTER"."SYS_IMPORT_TABLE_01":  master/******** directory=DATAPUMP_MASTER dumpfile=expdp_table_product.dmp tables=PRODUCT
Processing object type TABLE_EXPORT/TABLE/TABLE
Processing object type TABLE_EXPORT/TABLE/TABLE_DATA
. . imported "MASTER"."PRODUCT"                          5.084 MB  193998 rows
Processing object type TABLE_EXPORT/TABLE/INDEX/INDEX
Processing object type TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type TABLE_EXPORT/TABLE/TRIGGER
Job "MASTER"."SYS_IMPORT_TABLE_01" successfully completed at 01:09:31

[oracle@serveroracle ~]$ exit
exit
SQL> select count(*) from PRODUCT;

  COUNT(*)
----------
    193998

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
ENABLED

SQL> ALTER PROCEDURE MASTER."P_PRODUCT" COMPILE;

Procedure altered.

SQL> ALTER TRIGGER MASTER."TRG_PRODUCT" COMPILE reuse settings;

Trigger altered.

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

no rows selected

SQL>

Com a realização do teste acima, podemos afirmar que com o Datapump a tabela com o “row movement” habilitado na importação da mesma o objeto “Tabela” permanece com habilitado.
Vamos realizar o teste com o banco de dados Oracle 11g seguindo o mesmo procedimento acima na versão 10g.

SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> conn master/master
Conectado.
SQL> select name, type from user_dependencies where referenced_name='PRODUCT';

NAME                           TYPE
------------------------------ ------------------
P_PRODUCT                      PROCEDURE
TRG_PRODUCT                    TRIGGER

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
DISABLED

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
          403                 109           99998
		  
SQL> alter table PRODUCT enable  row movement;

Tabela alterada.

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
ENABLED

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

n?o ha linhas selecionadas

SQL>

Podemos perceber acima que os objetos permaneceram válidos após habilitar a tabela o que não ocorre na versão 10g.

SQL> alter table PRODUCT shrink space;

Tabela alterada.

SQL> analyze table PRODUCT compute statistics;

Tabela analisada.

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
          403                   5           99998

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

n?o ha linhas selecionadas

SQL> select blocks "Blocos Usados", empty_blocks "Blocos Nunca Usados", num_rows "Total de Linhas" from user_tables where table_name='PRODUCT';

Blocos Usados Blocos Nunca Usados Total de Linhas
------------- ------------------- ---------------
          403                   5           99998

SQL> !

Agora vamos executar a exportação da tabela PRODUCT novamente com o “EXP” porém na versão 11g.

[oracle@srvoracle11g ~]$ exp userid=master/master file=/home/oracle/export_table_product.dmp buffer=8192000 grants=n statistics=none;

Export: Release 11.2.0.1.0 - Production on Sun Jan 15 01:35:22 2012

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.


Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses WE8MSWIN1252 character set (possible charset conversion)
Note: grants on tables/views/sequences/roles will not be exported

About to export specified users ...
. exporting pre-schema procedural objects and actions
. exporting foreign function library names for user MASTER
. exporting PUBLIC type synonyms
. exporting private type synonyms
. exporting object type definitions for user MASTER
About to export MASTER's objects ...
. exporting database links
. exporting sequence numbers
. exporting cluster definitions
. about to export MASTER's tables via Conventional Path ...
. . exporting table                        PRODUCT      99998 rows exported
. exporting synonyms
. exporting views
. exporting stored procedures
. exporting operators
. exporting referential integrity constraints
. exporting triggers
. exporting indextypes
. exporting bitmap, functional and extensible indexes
. exporting posttables actions
. exporting materialized views
. exporting snapshot logs
. exporting job queues
. exporting refresh groups and children
. exporting dimensions
. exporting post-schema procedural objects and actions
. exporting statistics
Export terminated successfully without warnings.
[oracle@srvoracle11g ~]$ exit
exit

Vamos dropar a tabela.

SQL> drop table PRODUCT purge;

Tabela eliminada.

SQL> select count(*) from PRODUCT;
select count(*) from PRODUCT
                     *
ERRO na linha 1:
ORA-00942: a tabela ou view n?o existe


SQL> !

Vamos importar a tabela PRODUCT com o IMP na versão 11g.

[oracle@srvoracle11g ~]$ imp userid=master/master file=/home/oracle/export_table_product.dmp fromuser=master touser=master tables=PRODUCT statistics=none grants=n;

Import: Release 11.2.0.1.0 - Production on Sun Jan 15 01:36:08 2012

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.


Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

Export file created by EXPORT:V11.02.00 via conventional path
import done in US7ASCII character set and AL16UTF16 NCHAR character set
import server uses WE8MSWIN1252 character set (possible charset conversion)
. importing MASTER's objects into MASTER
. . importing table                      "PRODUCT"      99998 rows imported
Import terminated successfully without warnings.
[oracle@srvoracle11g ~]$ exit
exit

Vamos visualizar se a tabela PRODUCT que estava com o “row movement” habilitado após a importação através do IMP.

SQL> select count(*) from PRODUCT;

  COUNT(*)
----------
     99998

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
DISABLED

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

OBJECT_NAME                    OBJECT_TYPE         STATUS
------------------------------ ------------------- -------
P_PRODUCT                      PROCEDURE           INVALID

SQL> ALTER PROCEDURE MASTER."P_PRODUCT" COMPILE;

Procedimento alterado.

SQL>

Podemos perceber que acima tanto na versão 10g quanto na versão 11g com EXPORT/IMPORT (EXP/IMP) o objeto é importado com o “row movement” desabilitado.
Vamos executar com o Datapump na versão 11g.

SQL> disc
Desconectado de Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> conn / as sysdba
Conectado.
SQL> show user
USER e "SYS"
SQL> create directory DATAPUMP_MASTER as '/home/oracle';

Diretorio criado.

SQL> grant read,write on directory DATAPUMP_MASTER to master;

Concess?o bem-sucedida.

SQL> conn master/master
Conectado.
SQL> alter table PRODUCT enable row movement;

Tabela alterada.

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
ENABLED

SQL> !

Vamos exportar via Datapump a tabela PRODUCT com o “row movement” habilitado.

[oracle@srvoracle11g ~]$ expdp master/master directory=DATAPUMP_MASTER dumpfile=expdp_table_product.dmp tables=PRODUCT;

Export: Release 11.2.0.1.0 - Production on Sun Jan 15 01:37:21 2012

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Iniciando "MASTER"."SYS_EXPORT_TABLE_01":  master/******** directory=DATAPUMP_MASTER dumpfile=expdp_table_product.dmp tables=PRODUCT
Estimativa em andamento com o metodo BLOCKS...
Processando o tipo de objeto TABLE_EXPORT/TABLE/TABLE_DATA
Estimativa total usando o metodo de BLOCKS: 4 MB
Processando o tipo de objeto TABLE_EXPORT/TABLE/TABLE
Processando o tipo de objeto TABLE_EXPORT/TABLE/INDEX/INDEX
Processando o tipo de objeto TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processando o tipo de objeto TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processando o tipo de objeto TABLE_EXPORT/TABLE/TRIGGER
. . exportou "MASTER"."PRODUCT"                          2.616 MB   99998 linhas
Tabela-mestre "MASTER"."SYS_EXPORT_TABLE_01" carregada/descarregada com sucesso
******************************************************************************
Conjunto de arquivos de dump para MASTER.SYS_EXPORT_TABLE_01 e:
  /home/oracle/expdp_table_product.dmp
O job "MASTER"."SYS_EXPORT_TABLE_01" foi concluido com sucesso em 01:37:55

[oracle@srvoracle11g ~]$ exit
exit

Dropando a Tabela PRODUCT.

SQL> drop table PRODUCT purge;

Tabela eliminada.

SQL> select count(*) from PRODUCT;
select count(*) from PRODUCT
                     *
ERRO na linha 1:
ORA-00942: a tabela ou view n?o existe


SQL> !

Importanto a tabela PRODUCT via Datapump.

[oracle@srvoracle11g ~]$ impdp master/master directory=DATAPUMP_MASTER dumpfile=expdp_table_product.dmp tables=PRODUCT;

Import: Release 11.2.0.1.0 - Production on Sun Jan 15 01:38:21 2012

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Tabela-mestre "MASTER"."SYS_IMPORT_TABLE_01" carregada/descarregada com sucesso
Iniciando "MASTER"."SYS_IMPORT_TABLE_01":  master/******** directory=DATAPUMP_MASTER dumpfile=expdp_table_product.dmp tables=PRODUCT
Processando o tipo de objeto TABLE_EXPORT/TABLE/TABLE
Processando o tipo de objeto TABLE_EXPORT/TABLE/TABLE_DATA
. . importou "MASTER"."PRODUCT"                          2.616 MB   99998 linhas
Processando o tipo de objeto TABLE_EXPORT/TABLE/INDEX/INDEX
Processando o tipo de objeto TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processando o tipo de objeto TABLE_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processando o tipo de objeto TABLE_EXPORT/TABLE/TRIGGER
O job "MASTER"."SYS_IMPORT_TABLE_01" foi concluido com sucesso em 01:38:32

[oracle@srvoracle11g ~]$ exit
exit
SQL> select count(*) from PRODUCT;

  COUNT(*)
----------
     99998

SQL> select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
ENABLED

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

OBJECT_NAME                    OBJECT_TYPE         STATUS
------------------------------ ------------------- -------
P_PRODUCT                      PROCEDURE           INVALID

SQL> ALTER PROCEDURE MASTER."P_PRODUCT" COMPILE;

Procedimento alterado.

SQL>  select row_movement from user_tables where table_name='PRODUCT';

ROW_MOVE
--------
ENABLED

SQL> select object_name, object_type, status from user_objects where status != 'VALID';

n?o ha linhas selecionadas

SQL>

Podemos perceber que tanto na versão 10g quanto na versão 11g através Datapump o objeto permanece com o “row movement” habilitado.

Portanto podemos concluir que o shrink pode ser realizado online, porém cuidado ao utilizar o mesmo para habilitar as movimentações de linhas na versão 10g, pois os objetos dependentes da tabela podem ficar inválidos o que não ocorre na versão 11g.

Mais sobre Reclamação de Espaço veja na documentação da Oracle.

Documentação da Oracle 10g
Documentação da Oracle 11g

%name Diferenças de Reorganização de Objetos com Shrink em Banco de Dados Oracle 10g e 11g

Autor: Maycon Tomiasi

Formado em Tecnologia da Informação na FIPP (Faculdade de Informática de Presidente Prudente), Analista DBA Oracle pela Teiko Soluções em Tecnologia da Informação, residente em Blumenau/ SC, Certificado OCP 10g/11g/12c, OCS 11g Implementation, OCE 11g Performance Tuning, OCE 11g RAC & GRID e OPN Specialist. Conhecimentos em PHP.