terça-feira, 24 de maio de 2016

TABLESPACE SYSAUX crescendo excepcionalmente

1 - TABELA com 50GB na sysaux
Motivo - Armazena informações de snapshots do awr (automatic workload repository), que são relativos a relatórios automáticos relacionados a estatísticas do oracle.
Bug relatado no Metalink: 
Table/Index (partition) Growth Is Far More Than Expected (Doc ID 729149.1)
Devido a snapshots antigos, é necessário remover os mesmos, efetuar a limpeza da tabela e fazer o shrink da tabela.

Procedimento:

1.1 ver as configurações das estatísticas da instância:
col statistics_name for a40
SELECT STATISTICS_NAME, SESSION_STATUS, SYSTEM_STATUS, ACTIVATION_LEVEL
FROM v$statistics_level  ORDER BY 3 ;


2 - identificando a tabela:
== verificando o tamanho ==
set lines 200
col SEGMENT_NAME format a60
col 
select * from (select 
owner,segment_name||'~'||partition_name segment_name,bytes/(1024*1024) size_m
from dba_segments where tablespace_name = 'SYSAUX' 
ORDER BY BLOCKS desc )
where rownum < 3;


OWNER                SEGMENT_NAME                                                     SIZE_M
-------------------- ------------------------------------------------------------ ----------
SYS                  WRH$_LATCH_CHILDREN~WRH$_LATCH__1599336177_38253                  25567
SYS                  WRH$_LATCH_CHILDREN_PK~WRH$_LATCH__1599336177_38253               20695


3 - Range dos snapshots:
SQL> select min(snap_id), max(snap_id), snap_level from dba_hist_snapshot group by snap_level;

MIN(SNAP_ID) MAX(SNAP_ID) SNAP_LEVEL
------------ ------------ ----------
       40138        40347          2

4 - procedimento de limpeza:
4.1 - remoção dos snapshots:

SQL> execute dbms_workload_repository.drop_snapshot_range(40138, 40340);


4.2 - Para reduzir o tamanho dos blocos, reorganizando a tabela e liberar espaço, executar a seguinte procedure, cujo conteúdo faz a reorganização das linhas e assim que terminar, faz o shrink das tabelas do que armazenam as informações do AWR:

declare
v_sql1 varchar2(2000);
v_sql2 varchar2(2000);
begin
for rec in (select TABLE_NAME from dba_tables where TABLE_NAME like 'WRH$%') loop
v_sql1 := 'alter table ' || rec.TABLE_NAME || ' enable row movement ' ;
execute immediate v_sql1;
v_sql2 := 'alter table ' || rec.TABLE_NAME || ' shrink space cascade' ;
execute immediate v_sql2;
end loop;
end ;
/


Obs: pode ser feito também manualmente, porém não há previsão de tempo e por isso pode ser executado em nohup , basta criar um script.


Fontes:
http://colbran.co.za/wordpress/2010/10/01/sysman-tablespace-grows-excessively/
Metalink: Table/Index (partition) Growth Is Far More Than Expected (Doc ID 729149.1)

sexta-feira, 28 de novembro de 2014

SEQUENCES FULL - RESOLVENDO SEM DROPAR

Saudações. !!

Peguei hoje uma situação de uma sequence que estava com mais de 100% de ocupação.

SEQUENCE_OWNER                 SEQUENCE_NAME                   MIN_VALUE  MAX_VALUE INCREMENT_BY C O LAST_NUMBER       PERC
------------------------------ ------------------------------ ---------- ---------- ------------ - - ----------- ----------
OWNER                          NOME_SEQUENCE                  1           999999    1            N N     1000000   100.0001



Todos os sites recomendavam o drop e recriação da mesma, porém como sempre na madruga só podemos contar com pesquisas e Deus, não há como medir o impacto desta ação.
Nem mesmo alterar o incremento máximo da mesma recomendavam

Pesquisando, encontrei o site do ACE Gokhan Atil, foi recomendado que alterasse a sequence para somente começar a incrementar em numeros abaixo do número máximo.

ALTER SEQUENCE OWNER.NOME_SEQUENCE INCREMENT BY -200000;

Isto resolveu completamente o problema sem precisar dropar a sequence.

http://www.gokhanatil.com/2011/01/how-to-set-current-value-of-a-sequence-without-droppingrecreating.html

terça-feira, 1 de julho de 2014

Resize do banco - artigo do Burleson Traduzido

 Fonte: http://www.dba-oracle.com/art_dbazine_weeg_datafile_resizing_tips.htm

É possível liberar espaço de arquivos de dados, mas apenas para o primeiro bloco de dados.
Isto é feito com o comando "ALTER DATABASE ".
Ao invés de passar pelo tedioso processo de descobrir manualmente o comando cada vez que é usado, faz mais sentido para escrever um script que irá gerar este comando, se necessário.

Alter database name datafile 'file_name' resize size;

Onde name é o nome do banco de dados, file_name é o nome do arquivo e tamanho é o novo tamanho para o resize deste arquivo.
Podemos ver a mudança de tamanho na tabela DBA_DATA_FILES, bem como a partir do servidor.

Em primeiro lugar, puxar o nome do banco de dados:

Select 'alter database '||a.name
From v$database a;


Feito isso, é hora de adicionar os datafiles:

select 'alter database '||a.name||' datafile '''||b.file_name||''''
from v$database a
,dba_data_files b;


Embora este seja mais perto da solução final, não é bastante lá ainda.
A questão permanece: quais arquivos de dados que você quer alterar?
Neste ponto, você pode usar um padrão geralmente aceito, o que permite que os espaços de tabela a ser de 70 por cento para 90 por cento completo.
Se uma tabela está abaixo da marca de 70 por cento, uma maneira de trazer o número para cima é de-alocar uma parte do espaço.
É necessário ver a porcentagem usada.


Quantidade de espaço nos datafiles utilizada:

Select tablespace_name,sum(bytes) bytes_full
From dba_extents
Group by tablespace_name;



mais completa:

SET LINESIZE 200
SET PAGES 150
COL TABLESPACE_NAME FORMAT A15
SELECT  A.TABLESPACE_NAME TABLESPACE,
        round(A.TAMANHO_MAXIMO,2) TAMANHO_MAXIMO,
        round(A.TAMANHO_ATUAL,2) TAMANHO_ATUAL,
        A.AUTOEXTENSIBLE EXTEND,
        round(B.USADO,2) "USADO(MB)",
        round(CASE WHEN A.TAMANHO_MAXIMO<a.TAMANHO_ATUAL THEN A.TAMANHO_ATUAL-B.USADO
ELSE A.TAMANHO_MAXIMO-B.USADO END,2) "LIVRE(MB)",
        round(CASE WHEN A.TAMANHO_MAXIMO<a.TAMANHO_ATUAL THEN
(B.USADO/A.TAMANHO_ATUAL)*100 ELSE (B.USADO/A.TAMANHO_MAXIMO)*100 END,2)
"USADO%"
        FROM
        (SELECT TABLESPACE_NAME,AUTOEXTENSIBLE,
                       SUM(BYTES/1024/1024) TAMANHO_ATUAL,
                       SUM(MAXBYTES/1024/1024) TAMANHO_MAXIMO
         FROM   DBA_DATA_FILES
         GROUP BY TABLESPACE_NAME,AUTOEXTENSIBLE) A,
        (SELECT TABLESPACE_NAME,
                       SUM(BYTES/1024/1024) USADO
         FROM   DBA_SEGMENTS S
         GROUP BY TABLESPACE_NAME ) B
         WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME
/ 
 


Total de espaço disponível nos datafiles:

Select tablespace_name,sum(bytes) bytes_total
From dba_data_files
Group by tablespace_name;



Assim, se somarmos isso com a nossa declaração original, podemos selecionar em pct_used (menos de 70 por cento):

select 'alter database '||a.name||' datafile '''||b.file_name||''''
from v$database a
,dba_data_files b
,(Select tablespace_name,sum(bytes) bytes_full
From dba_extents
Group by tablespace_name) c
,(Select tablespace_name,sum(bytes) bytes_total
From dba_data_files
Group by tablespace_name) d
Where b.tablespace_name = c.tablespace_name
And b.tablespace_name = d.tablespace_name
And bytes_full/bytes_total < .7 ;


De acordo com o comando, a seleção foi feita com base na tabela.
E se você deseja redimensionar baseado em arquivo?
É fundamental lembrar que vários arquivos podem existir em qualquer espaço de tabela.
Além disso, apenas o espaço que é depois do último bloco de dados pode ser de-alocado.
Assim, o próximo passo deve ser o de encontrar o último bloco de dados:

select tablespace_name,file_id,max(block_id) max_data_block_id
from dba_extents
group by tablespace_name,file_id;


Agora que o comando para encontrar o último bloco de dados foi inserido,
é hora de encontrar o espaço livre em cada arquivo acima desse último bloco de dados:

Select a.tablespace_name,a.file_id,b.bytes bytes_free
From (select tablespace_name,file_id,max(block_id) max_data_block_id
from dba_extents
group by tablespace_name,file_id) a
,dba_free_space b
where a.tablespace_name = b.tablespace_name
and a.file_id = b.file_id
and b.block_id > a.max_data_block_id;



Como é possível, então, para combinar comandos para garantir a quantidade correta será redimensionada?


select 'alter database '||a.name||' datafile '''||b.file_name||'''' ||
' resize '||(bytes_total-bytes_free)
from v$database a
,dba_data_files b
,(Select tablespace_name,sum(bytes) bytes_full
From dba_extents
Group by tablespace_name) c
,(Select tablespace_name,sum(bytes) bytes_total
From dba_data_files
Group by tablespace_name) d
,(Select a.tablespace_name,a.file_id,b.bytes bytes_free
From (select tablespace_name,file_id
,max(block_id) max_data_block_id
from dba_extents
group by tablespace_name,file_id) a
,dba_free_space b
where a.tablespace_name = b.tablespace_name
and a.file_id = b.file_id
and b.block_id > a.max_data_block_id) e
Where b.tablespace_name = c.tablespace_name
And b.tablespace_name = d.tablespace_name;


Double check na compactação dos datafiles:

select 'alter database '||a.name||' datafile '''||b.file_name||'''' ||
' resize '||greatest(trunc(bytes_full/.7)
,(bytes_total-bytes_free))
from v$database a
,dba_data_files b
,(Select tablespace_name,sum(bytes) bytes_full
From dba_extents
Group by tablespace_name) c
,(Select tablespace_name,sum(bytes) bytes_total
From dba_data_files
Group by tablespace_name) d
,(Select a.tablespace_name,a.file_id,b.bytes bytes_free
From (select tablespace_name,file_id
,max(block_id) max_data_block_id
from dba_extents
group by tablespace_name,file_id) a
,dba_free_space b
where a.tablespace_name = b.tablespace_name
and a.file_id = b.file_id
and b.block_id > a.max_data_block_id) e
Where b.tablespace_name = c.tablespace_name
And b.tablespace_name = d.tablespace_name
And bytes_full/bytes_total < .7
And b.tablespace_name = e.tablespace_name
And b.file_id = e.file_id ;




Uma última coisa a fazer: Adicione uma instrução para indicar o que está sendo alterado.

Esta query gera os comandos necessários para o resize:

select 'alter database '||a.name||' datafile '''||b.file_name||'''' ||
' resize '||greatest(trunc(bytes_full/.7)
,(bytes_total-bytes_free))||chr(10)||
'--tablespace was '||trunc(bytes_full*100/bytes_total)||
'% full now '||
trunc(bytes_full*100/greatest(trunc(bytes_full/.7)
,(bytes_total-bytes_free)))||'%'
from v$database a
,dba_data_files b
,(Select tablespace_name,sum(bytes) bytes_full
From dba_extents
Group by tablespace_name) c
,(Select tablespace_name,sum(bytes) bytes_total
From dba_data_files
Group by tablespace_name) d
,(Select a.tablespace_name,a.file_id,b.bytes bytes_free
From (select tablespace_name,file_id
,max(block_id) max_data_block_id
from dba_extents
group by tablespace_name,file_id) a
,dba_free_space b
where a.tablespace_name = b.tablespace_name
and a.file_id = b.file_id
and b.block_id > a.max_data_block_id) e
Where b.tablespace_name = c.tablespace_name
And b.tablespace_name = d.tablespace_name
And bytes_full/bytes_total < .7
And b.tablespace_name = e.tablespace_name
And b.file_id = e.file_id ;


exemplo da saída:

'ALTERDATABASE'||A.NAME||'DATAFILE'''||B.FILE_NAME||''''||'RESIZE'||GREATEST(TRU
--------------------------------------------------------------------------------
alter database ORCL datafile '/home/oracle/app/oracle/oradata/orcl/undotbs01.dbf
' resize 31831771
--tablespace was 12% full now 70%




Enfim, este é um script que irá criar o script. Mesmo assim, é importante prestar atenção ao aplicar o script criado.
Por quê? Porque reversão, Sistema e espaços de tabela temporários são muito diferentes criaturas, e cada um não deve necessariamente ser realizada com a regra de 70 por cento.
Da mesma forma, pode haver uma razão muito boa para um espaço de tabela a ser alocado ao longo - como a carga gigante que vai triplicar o volume de noite.

Por fim , cheque os tamanhos das tablespaces novamente:

Select tablespace_name,sum(bytes) bytes_full
From dba_extents
Group by tablespace_name; 


SET LINESIZE 200
SET PAGES 150
COL TABLESPACE_NAME FORMAT A15
SELECT  A.TABLESPACE_NAME TABLESPACE,
        round(A.TAMANHO_MAXIMO,2) TAMANHO_MAXIMO,
        round(A.TAMANHO_ATUAL,2) TAMANHO_ATUAL,
        A.AUTOEXTENSIBLE EXTEND,
        round(B.USADO,2) "USADO(MB)",
        round(CASE WHEN A.TAMANHO_MAXIMO<a.TAMANHO_ATUAL THEN A.TAMANHO_ATUAL-B.USADO
ELSE A.TAMANHO_MAXIMO-B.USADO END,2) "LIVRE(MB)",
        round(CASE WHEN A.TAMANHO_MAXIMO<a.TAMANHO_ATUAL THEN
(B.USADO/A.TAMANHO_ATUAL)*100 ELSE (B.USADO/A.TAMANHO_MAXIMO)*100 END,2)
"USADO%"
        FROM
        (SELECT TABLESPACE_NAME,AUTOEXTENSIBLE,
                       SUM(BYTES/1024/1024) TAMANHO_ATUAL,
                       SUM(MAXBYTES/1024/1024) TAMANHO_MAXIMO
         FROM   DBA_DATA_FILES
         GROUP BY TABLESPACE_NAME,AUTOEXTENSIBLE) A,
        (SELECT TABLESPACE_NAME,
                       SUM(BYTES/1024/1024) USADO
         FROM   DBA_SEGMENTS S
         GROUP BY TABLESPACE_NAME ) B
         WHERE A.TABLESPACE_NAME=B.TABLESPACE_NAME
/



Uma palavra de cautela, também: Certifique-se de que as extensões ainda pode ser alocada em cada tabela.
Pode haver espaço livre suficiente, mas pode ser muito fragmentada para ser útil.

Fonte:http://www.dba-oracle.com/art_dbazine_weeg_datafile_resizing_tips.htm

quinta-feira, 24 de abril de 2014

Datatypes limits no oracle 11G

http://docs.oracle.com/cd/B28359_01/server.111/b28320/limits001.htm#i287903


Datatype Limits

DatatypesLimitComments
BFILEMaximum size: 4 GB
Maximum size of a file name: 255 characters
Maximum size of a directory name: 30 characters
Maximum number of open BFILEs: see Comments
The maximum number of BFILEs is limited by the value of theSESSION_MAX_OPEN_FILES initialization parameter, which is itself limited by the maximum number of open files the operating system will allow.
BLOBMaximum size: (4 GB - 1) * DB_BLOCK_SIZEinitialization parameter (8 TB to 128 TB)The number of LOB columns per table is limited only by the maximum number of columns per table (that is, 1000Foot 1 ).
CHARMaximum size: 2000 bytesNone
CHAR VARYINGMaximum size: 4000 bytesNone
CLOBMaximum size: (4 GB - 1) * DB_BLOCK_SIZEinitialization parameter (8 TB to 128 TB)The number of LOB columns per table is limited only by the maximum number of columns per table (that is, 1000Footref 1).
Literals (characters or numbers in SQL or PL/SQL)Maximum size: 4000 charactersNone
LONGMaximum size: 2 GB - 1Only one LONG column is allowed per table.
NCHARMaximum size: 2000 bytesNone
NCHAR VARYINGMaximum size: 4000 bytesNone
NCLOBMaximum size: (4 GB - 1) * DB_BLOCK_SIZEinitialization parameter (8 TB to 128 TB)The number of LOB columns per table is limited only by the maximum number of columns per table (that is, 1000Footref 1).
NUMBER999...(38 9's) x10125 maximum value
-999...(38 9's) x10125 minimum value
Can be represented to full 38-digit precision (the mantissa)
Can be represented to full 38-digit precision (the mantissa)
Precision38 significant digitsNone
RAWMaximum size: 2000 bytesNone
VARCHARMaximum size: 4000 bytesNone
VARCHAR2Maximum size: 4000 bytesNone

restore total de banco