Sem dúvida, vc PODE remover o espaço acima da hwm, vc PODE também alterar 
pctfree/pctused pra que MENOS espaço dentro dos blocos fique reservado para 
futuros UPDATEs, vc PODE compactar tabelas e índices, vc  PODE recriar um 
extent com um tamanho menor para que o último extent não usado até o fim seja 
menor, sim, como eu havia dito...
 Porém, via de regra, a quota do leão de espaço "desperdiçado" é o espaço 
ABAIXO da hwm que ficou em branco após DELETEs : como eu disse, esse espaço NÂO 
está desperdiçado pro si só, está reservado para futuros INSERTs/UPDATEs, mas 
se a pessoa SOUBER que aconteceram DELETEs em massa e não virão mais 
INSERTs/UPDATEs, aí sim, essa alocação passa a ser questionável.... Desse jeito 
:
 
 => primeiro, vamos criar uma tabespace LMT com extent sizes restritos E com 
controle de espaço dentro dos blocos automático, pra não precisarmos se 
preocupar com isso :
 
SYSTEM@O11GR2>create tablespace TS_LMT_AUTO_FULL datafile 
'C:\APP\ORACLE\ORADATA\O11GR2\O11GR2\TS_LMT_AUTO_FULL_01.DBF'  size 100M 
autoextend on maxsize unlimited EXTENT MANAGEMENT LOCAL AUTOALLOCATE SEGMENT 
SPACE MANAGEMENT AUTO;

Tablespace criado.

SYSTEM@O11GR2>alter user scott quota unlimited on TS_LMT_AUTO_FULL;

Usuário alterado.

 => crio uma tabela com mais do que um punhado de extents :
 
SCOTT@O11GR2>create table TAB_TESTE_ESPACO( c1 number, c2 varchar2(2000)) 
tablespace TS_LMT_AUTO_FULL;

Tabela criada.

SCOTT@O11GR2>create sequence SEQ_TESTe_ESPACO;

Sequência criada.

SCOTT@O11GR2>insert into TAB_TESTE_ESPACO (select seq_teste_espaco.nextval, 
lpad(object_name, 2000, '*') from all_objects);

68267 linhas criadas.

SCOTT@O11GR2>commit;

Commit concluído.

SCOTT@O11GR2>select count(*) from TAB_TESTE_ESPACO;

  COUNT(*)
----------
     68267

1 linha selecionada.

SCOTT@O11GR2>

==> Veja que cada extent está  'grudado' um no outro, o próximo começa onde o 
anterior terminou, não há 'GAPS' entre eles :

SYSTEM@O11GR2>select owner, file_id, extent_id, block_id, bytes, 
block_id+blocks as PROXIMO from dba_extents where 
tablespace_name='TS_LMT_AUTO_FULL';

OWNER               FILE_ID  EXTENT_ID   BLOCK_ID      BYTES         PROXIMO
---------------- ---------- ---------- ---------- ---------- ---------------
SCOTT                     5          0        128      65536             136
SCOTT                     5          1        136      65536             144
SCOTT                     5          2        144      65536             152
SCOTT                     5          3        152      65536             160
SCOTT                     5          4        160      65536             168
SCOTT                     5          5        168      65536             176
SCOTT                     5          6        176      65536             184
SCOTT                     5          7        184      65536             192
SCOTT                     5          8        192      65536             200
SCOTT                     5          9        200      65536             208
SCOTT                     5         10        208      65536             216
SCOTT                     5         11        216      65536             224
SCOTT                     5         12        224      65536             232
SCOTT                     5         13        232      65536             240
SCOTT                     5         14        240      65536             248
SCOTT                     5         15        248      65536             256
SCOTT                     5         16        256    1048576             384
SCOTT                     5         17        384    1048576             512
.... vários e vários mais ....
SCOTT                     5         78       8192    1048576            8320
SCOTT                     5         79       8320    8388608            9344
SCOTT                     5         80       9344    8388608           10368
SCOTT                     5         81      10368    8388608           11392
SCOTT                     5         82      11392    8388608           12416
SCOTT                     5         83      12416    8388608           13440
SCOTT                     5         84      13440    8388608           14464
SCOTT                     5         85      14464    8388608           15488
SCOTT                     5         86      15488    8388608           16512
SCOTT                     5         87      16512    8388608           17536
SCOTT                     5         88      17536    8388608           18560
SCOTT                     5         89      18560    8388608           19584
SCOTT                     5         90      19584    8388608           20608
SCOTT                     5         91      20608    8388608           21632
SCOTT                     5         92      21632    8388608           22656
SCOTT                     5         93      22656    8388608           23680

94 linhas selecionadas.

=> ok, consumiu quase 200 MB para armazenar as 68 mil e tantas linhas :

SYSTEM@O11GR2>select sum(bytes), count(*) from DBA_EXTENTS where 
segment_name='TAB_TESTE_ESPACO';

              SUM(BYTES)   COUNT(*)
------------------------ ----------
             192.937.984         94

1 linha selecionada.

SYSTEM@O11GR2>

==> no caso, meu blocksize é de 8KB, então com um registro lógico de pouco mais 
de 2000 caracteres , vou ter 3 linhas por bloco (considerando que além das 
linhas da tabela há Cabeçalhos e info interna que também vai nos blocos)... E 
como tablespaces LMT tem um bitmap no começo, veja acima que não começou a usar 
o espaço a partir do primeiro bloco da tablespace....
 Muito bem, quero apagar dados de uma tal forma que fique um 'espaço em branco' 
mais ou menos entre o 10º e o 50º extent, o que implica em apagar dados com C1 
entre 
 
SCOTT@O11GR2>select min(c1), max (c1) from (select c1, 
dbms_rowid.rowid_block_number(rowid) bloco_onde_a_linha_esta from 
TAB_TESTE_ESPACO)
   where bloco_onde_a_linha_esta between 208 and 4608;

   MIN(C1)    MAX(C1)
---------- ----------
       220      13206

1 linha selecionada.

SCOTT@O11GR2>delete from TAB_TESTE_ESPACO where c1 between 220 and 13206;

12987 linhas deletadas.

SCOTT@O11GR2>commit;

Commit concluído.

SCOTT@O11GR2>

===> olha só como ficamos depois do DELETE :

SYSTEM@O11GR2>select sum(bytes), count(*) from DBA_EXTENTS where 
segment_name='TAB_TESTE_ESPACO';

              SUM(BYTES)   COUNT(*)
------------------------ ----------
             192.937.984         94

1 linha selecionada.

SYSTEM@O11GR2>select count(*) from scott.tab_teste_espaco;

  COUNT(*)
----------
     55280

1 linha selecionada.

SYSTEM@O11GR2>


==> ó dia, ó azar, ó vida : continuo gastando o MESMO ESPAÇO que gastava antes 
pra armazenar 68267, o que aconteceu com o espaço que foi logicamente liberado 
após deletar as 12987 linhas ??? É o que eu disse, ele está em branco, sem 
dados, MAS AINDA ESTÁ RESERVADO pra uso dos futuros INSERTs/UPDATEs que vierem 
a acontecer na tabela , okdoc ??
 E esse espaço está ABAIXO DA HWM, pois os DELETEs liberaram blocos ABAIXO da 
HWM :

SYSTEM@O11GR2>SELECT file_name, hwm, blocks total_blocks, blocks-hwm+1 as 
Shrinkage_Available
  2  FROM dba_data_files a,
  3       ( select file_id, max(block_id+blocks) hwm
  4         from dba_extents
  5         group by file_id ) b
  6  WHERE a.file_id = b.file_id
  7*   AND 
a.file_name='C:\APP\ORACLE\ORADATA\O11GR2\O11GR2\TS_LMT_AUTO_FULL_01.DBF';
 
 FILE_NAME                                                                   
HWM TOTAL_BLOCKS SHRINKAGE_AVAILABLE
-------------------------------------------------------------------- ---------- 
------------ -------------------
C:\APP\ORACLE\ORADATA\O11GR2\O11GR2\TS_LMT_AUTO_FULL_01.DBF               23680 
       24864                1185

1 linha selecionada.

 ==>> ESTE é o caso que eu queria demonstrar : há um PEDAÇÂO de espaço que em 
tese PODE ser liberado pro sistema operacional mas está ABAIXO da hwm, blz ?
 

 []s
 

   Chiappa

Responder a