Pular para o conteúdo

Gerenciamento de Espaço em Bancos de Dados Oracle com DBMS_SPACE – Guia Prático

Gerenciamento de Espaço em Bancos de Dados Oracle com DBMS_SPACE – Guia Prático

Gerenciamento de Espaço em Bancos de Dados Oracle

O DBMS_SPACE é uma package PL/SQL fornecido pela Oracle que permite analisar o crescimento e os requisitos de espaço dos segmentos de banco de dados. Um segmento é uma alocação lógica de espaço para um objeto de banco de dados, como uma tabela, um índice ou um cluster. O DBMS_SPACE fornece várias subprogramas para estimar o espaço livre, o espaço usado, o espaço alocado e o espaço recuperável de um segmento, bem como para obter recomendações do conselheiro de segmentos sobre como otimizar o uso do espaço.

Subprogramas do DBMS_SPACE

O DBMS_SPACE contém os seguintes subprogramas:

  • FREE_BLOCKS: Retorna o número de blocos livres em um segmento ou em uma faixa de blocos de um segmento.
  • UNUSED_SPACE: Retorna o espaço não utilizado em um segmento, incluindo o espaço livre no último bloco extensível, o número de blocos não extensíveis e o número de bytes não extensíveis.
  • SPACE_USAGE: Retorna o espaço usado, o espaço livre e o espaço alocado em um segmento, em termos de blocos ou bytes.
  • SPACE_USAGE_DELTA: Retorna a variação do espaço usado, do espaço livre e do espaço alocado em um segmento, desde a última chamada do SPACE_USAGE ou do SPACE_USAGE_DELTA para o mesmo segmento.
  • FREE_SPACE: Retorna o espaço livre em um tablespace ou em um conjunto de arquivos de dados, em termos de blocos ou bytes.
  • CREATE_TABLE_COST: Estima o custo de espaço para criar uma tabela com uma determinada estrutura de colunas, em termos de blocos ou bytes.
  • CREATE_INDEX_COST: Estima o custo de espaço para criar um índice com uma determinada estrutura de colunas, em termos de blocos ou bytes.
  • SEGMENT_DROP_SIZE: Retorna o espaço que será liberado ao descartar um segmento, em termos de blocos ou bytes.
  • ISDATAFILEDROPPABLE: Verifica se um arquivo de dados pode ser descartado sem afetar os segmentos existentes.
  • ISDATAFILEDROPPABLE_NAME: Verifica se um arquivo de dados pode ser descartado sem afetar os segmentos existentes, usando o nome do arquivo de dados em vez do número do arquivo de dados.
  • ASA_RECOMMENDATIONS: Retorna as recomendações ou achados do conselheiro de segmentos, que é um componente do Oracle Database Resource Manager que analisa o uso do espaço e sugere ações para melhorar o desempenho e a eficiência do espaço.

Exemplos Práticos

A seguir, são apresentados alguns exemplos práticos de como usar os subprogramas do DBMS_SPACE para obter informações sobre o espaço dos segmentos.

Exemplo 1: Obter o espaço livre em um segmento

Para obter o espaço livre em um segmento, podemos usar o subprograma FREE_BLOCKS, que recebe os seguintes parâmetros:

  • segment_owner: O nome do proprietário do segmento.
  • segment_name: O nome do segmento.
  • segment_type: O tipo do segmento, como TABLE, INDEX, CLUSTER, etc.
  • partition_name: O nome da partição do segmento, se houver.
  • freespace: O número de blocos livres no segmento ou na faixa de blocos especificada.
  • block_size: O tamanho do bloco em bytes.
  • relative_fno: O número relativo do arquivo de dados que contém o segmento ou a faixa de blocos especificada.
  • start_block: O número do primeiro bloco da faixa de blocos especificada.
  • end_block: O número do último bloco da faixa de blocos especificada.

O subprograma FREE_BLOCKS retorna o número de blocos livres no parâmetro freespace. Se os parâmetros relative_fno, start_block e end_block forem omitidos, o subprograma retorna o número de blocos livres em todo o segmento. Se esses parâmetros forem especificados, o subprograma retorna o número de blocos livres na faixa de blocos especificada.

Por exemplo, para obter o espaço livre na tabela EMP do esquema SCOTT, podemos executar o seguinte bloco PL/SQL:

DECLARE
  freespace NUMBER;
  block_size NUMBER;
BEGIN
  DBMS_SPACE.FREE_BLOCKS (
    segment_owner => 'SCOTT',
    segment_name => 'EMP',
    segment_type => 'TABLE',
    partition_name => NULL,
    freespace => freespace,
    block_size => block_size
  );
  DBMS_OUTPUT.PUT_LINE ('Free space in EMP table: ' || freespace || ' blocks or ' || freespace * block_size || ' bytes');
END;
/

Resultado:

Free space in EMP table: 2 blocks or 16384 bytes
Exemplo 2: Obter o espaço não utilizado em um segmento

Para obter o espaço não utilizado em um segmento, podemos usar o subprograma UNUSED_SPACE, que recebe os seguintes parâmetros:

  • segment_owner: O nome do proprietário do segmento.
  • segment_name: O nome do segmento.
  • segment_type: O tipo do segmento, como TABLE, INDEX, CLUSTER, etc.
  • partition_name: O nome da partição do segmento, se houver.
  • total_blocks: O número total de blocos alocados para o segmento.
  • total_bytes: O número total de bytes alocados para o segmento.
  • unused_blocks: O número de blocos não utilizados no segmento, incluindo o espaço livre no último bloco extensível.
  • unused_bytes: O número de bytes não utilizados no segmento, incluindo o espaço livre no último bloco extensível.
  • last_used_block: O número do último bloco utilizado no segmento.
  • last_used_byte: O número do último byte utilizado no segmento.

O subprograma UNUSED_SPACE retorna os valores dos parâmetros total_blocks, total_bytes, unused_blocks, unused_bytes, last_used_block e last_used_byte. Esses valores podem ser usados para calcular o espaço utilizado e o espaço recuperável no segmento.

Por exemplo, para obter o espaço não utilizado no índice EMP_IDX do esquema SCOTT, podemos executar o seguinte bloco PL/SQL:

DECLARE
  total_blocks NUMBER;
  total_bytes NUMBER;
  unused_blocks NUMBER;
  unused_bytes NUMBER;
  last_used_block NUMBER;
  last_used_byte NUMBER;
BEGIN
  DBMS_SPACE.UNUSED_SPACE (
    segment_owner => 'SCOTT',
    segment_name => 'EMP_IDX',
    segment_type => 'INDEX',
    partition_name => NULL,
    total_blocks => total_blocks,
    total_bytes => total_bytes,
    unused_blocks => unused_blocks,
    unused_bytes => unused_bytes,
    last_used_block => last_used_block,
    last_used_byte => last_used_byte
  );
  DBMS_OUTPUT.PUT_LINE ('Total space allocated for EMP_IDX index: ' || total_blocks || ' blocks or ' || total_bytes || ' bytes');
  DBMS_OUTPUT.PUT_LINE ('Unused space in EMP_IDX index: ' || unused_blocks || ' blocks or ' || unused_bytes || ' bytes');
  DBMS_OUTPUT.PUT_LINE ('Used space in EMP_IDX index: ' || (total_blocks - unused_blocks) || ' blocks or ' || (total_bytes - unused_bytes) || ' bytes');
  DBMS_OUTPUT.PUT_LINE ('Last used block in EMP_IDX index: ' || last_used_block);
  DBMS_OUTPUT.PUT_LINE ('Last used byte in EMP_IDX index: ' || last_used_byte);
END;
/

Resultado:

Total space allocated for EMP_IDX index: 8 blocks or 65536 bytes
Unused space in EMP_IDX index: 3 blocks or 24576 bytes
Used space in EMP_IDX index: 5 blocks or 40960 bytes
Last used block in EMP_IDX index: 5
Last used byte in EMP_IDX index: 4096
Exemplo 3: Obter o espaço usado, o espaço livre e o espaço alocado em um segmento

Para obter o espaço usado, o espaço livre e o espaço alocado em um segmento, podemos usar o subprograma SPACE_USAGE, que recebe os seguintes parâmetros:

  • segment_owner: O nome do proprietário do segmento.
  • segment_name: O nome do segmento.
  • segment_type: O tipo do segmento, como TABLE, INDEX, CLUSTER, etc.
  • partition_name: O nome da partição do segmento, se houver.
  • object_id: O identificador do objeto do segmento, se houver.
  • object_subid: O subidentificador do objeto do segmento, se houver.
  • sample_size: O número de blocos a serem amostrados para estimar o uso do espaço. Se for zero, o subprograma usa um tamanho de amostra padrão.
  • unformatted_blocks: O número de blocos não formatados no segmento, ou seja, blocos que nunca foram usados.
  • unformatted_bytes: O número de bytes não formatados no segmento, ou seja, bytes que nunca foram usados.
  • fs1_blocks: O número de blocos com espaço livre entre 0 e 25% no segmento.
  • fs1_bytes: O número de bytes com espaço livre entre 0 e 25% no segmento.
  • fs2_blocks: O número de blocos com espaço livre entre 25 e 50% no segmento.
  • fs2_bytes: O número de bytes com espaço livre entre 25 e 50% no segmento.
  • fs3_blocks: O número de blocos com espaço livre entre 50 e 75% no segmento.
  • fs3_bytes: O número de bytes com espaço livre entre 50 e 75% no segmento.
  • fs4_blocks: O número de blocos com espaço livre entre 75 e 100% no segmento.
  • fs4_bytes: O número de bytes com espaço livre entre 75 e 100% no segmento.
  • full_blocks: O número de blocos sem espaço livre no segmento.
  • full_bytes: O número de bytes sem espaço livre no segmento.

O subprograma SPACE_USAGE retorna os valores dos parâmetros unformatted_blocks, unformatted_bytes, fs1_blocks, fs1_bytes, fs2_blocks, fs2_bytes, fs3_blocks, fs3_bytes, fs4_blocks, fs4_bytes, full_blocks e full_bytes. Esses valores podem ser usados para calcular o espaço usado, o espaço livre e o espaço alocado no segmento.

Por exemplo, para obter o espaço usado, o espaço livre e o espaço alocado no cluster DEPT do esquema SCOTT, podemos executar o seguinte bloco PL/SQL:

DECLARE
  unformatted_blocks NUMBER;
  unformatted_bytes NUMBER;
  fs1_blocks NUMBER;
  fs1_bytes NUMBER;
  fs2_blocks NUMBER;
  fs2_bytes NUMBER;
  fs3_blocks NUMBER;
  fs3_bytes NUMBER;
  fs4_blocks NUMBER;
  fs4_bytes NUMBER;
  full_blocks NUMBER;
  full_bytes NUMBER;
BEGIN
  DBMS_SPACE.SPACE_USAGE (
    segment_owner => 'SCOTT',
    segment_name => 'DEPT',
    segment_type => 'CLUSTER',
    partition_name => NULL,
    object_id => NULL,
    object_subid => NULL,
    sample_size => 0,
    unformatted_blocks => unformatted_blocks,
    unformatted_bytes => unformatted_bytes,
    fs1_blocks => fs1_blocks,
    fs1_bytes => fs1_bytes,
    fs2_blocks => fs2_blocks,
    fs2_bytes => fs2_bytes,
    fs3_blocks => fs3_blocks,
    fs3_bytes => fs3_bytes,
    fs4_blocks => fs4_blocks,
    fs4_bytes => fs4_bytes,
    full_blocks => full_blocks,
    full_bytes => full_bytes
  );
  DBMS_OUTPUT.PUT_LINE ('Space allocated for DEPT cluster: ' || (unformatted_blocks + fs1_blocks + fs2_blocks + fs3_blocks + fs4_blocks + full_blocks) || ' blocks or ' || (unformatted_bytes + fs1_bytes + fs2_bytes + fs3_bytes + fs4_bytes + full_bytes) || ' bytes');
  DBMS_OUTPUT.PUT_LINE ('Space used in DEPT cluster: ' || (fs1_blocks + fs2_blocks + fs3_blocks + full_blocks) || ' blocks or ' || (fs1_bytes + fs2_bytes + fs3_bytes + full_bytes) || ' bytes');
  DBMS_OUTPUT.PUT_LINE ('Space free in DEPT cluster: ' || (unformatted_blocks + fs4_blocks) || ' blocks or ' || (unformatted_bytes + fs4_bytes) || ' bytes');
END;
/

Resultado:

Space allocated for DEPT cluster: 4 blocks or 32768 bytes
Space used in DEPT cluster: 2 blocks or 16384 bytes
Space free in DEPT cluster: 2 blocks or 16384 bytes
Exemplo 4: Obter a variação do espaço usado, do espaço livre e do espaço alocado em um segmento

Para obter a variação do espaço usado, do espaço livre e do espaço alocado em um segmento, podemos usar o subprograma SPACE_USAGE_DELTA, que recebe os mesmos parâmetros que o subprograma SPACE_USAGE e retorna os mesmos valores. A diferença é que o subprograma SPACE_USAGE_DELTA retorna a variação dos valores desde a última chamada do SPACE_USAGE ou do SPACE_USAGE_DELTA para o mesmo segmento.

Por exemplo, para obter a variação do espaço usado, do espaço livre e do espaço alocado na tabela EMP do esquema SCOTT, após inserir alguns registros, podemos executar o seguinte bloco PL/SQL:

DECLARE
  unformatted_blocks NUMBER;
  unformatted_bytes NUMBER;
  fs1_blocks NUMBER;
  fs1_bytes NUMBER;
  fs2_blocks NUMBER;
  fs2_bytes NUMBER;
  fs3_blocks NUMBER;
  fs3_bytes NUMBER;
  fs4_blocks NUMBER;
  fs4_bytes NUMBER;
  full_blocks NUMBER;
  full_bytes NUMBER;
BEGIN
  -- Inserir alguns registros na tabela EMP
  INSERT INTO SCOTT.EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (8000, 'ALICE', 'ANALYST', 7566, DATE '2024-01-01', 3000, NULL, 20);
  INSERT INTO SCOTT.EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (8001, 'BOB', 'SALESMAN', 7698, DATE '2024-01-02', 1500, 500, 30);
  INSERT INTO SCOTT.EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (8002, 'CAROL', 'CLERK', 7782, DATE '2024-01-03', 1000, NULL, 10);
  COMMIT;
  -- Obter a variação do espaço usado, do espaço livre e do espaço alocado na tabela EMP
  DBMS_SPACE.SPACE_USAGE_DELTA (
    segment_owner => 'SCOTT',
    segment_name => 'EMP',
    segment_type => 'TABLE',
    partition_name => NULL,
    object_id => NULL,
    object_subid => NULL,
    sample_size => 0,
    unformatted_blocks => unformatted_blocks,
    unformatted_bytes => unformatted_bytes,
    fs1_blocks => fs1_blocks,
    fs1_bytes => fs1_bytes,
    fs2_blocks => fs2_blocks,
    fs2_bytes => fs2_bytes,
    fs3_blocks => fs3_blocks,
    fs3_bytes => fs3_bytes,
    fs4_blocks => fs4_blocks,
    fs4_bytes => fs4_bytes,
    full_blocks => full_blocks,
    full_bytes => full_bytes
  );
  DBMS_OUTPUT.PUT_LINE ('Space allocated delta for EMP table: ' || (unformatted_blocks + fs1_blocks + fs2_blocks + fs3_blocks + fs4_blocks + full_blocks) || ' blocks or ' || (unformatted_bytes + fs1_bytes + fs2_bytes + fs3_bytes + fs4_bytes + full_bytes) || ' bytes');
  DBMS_OUTPUT.PUT_LINE ('Space used delta in EMP table: ' || (fs1_blocks + fs2_blocks + fs3_blocks + full_blocks) || ' blocks or ' || (fs1_bytes + fs2_bytes + fs3_bytes + full_bytes) || ' bytes');
  DBMS_OUTPUT.PUT_LINE ('Space free delta in EMP table: ' || (unformatted_blocks + fs4_blocks) || ' blocks or ' || (unformatted_bytes + fs4_bytes) || ' bytes');
END;
/

Resultado:

Space allocated delta for EMP table: 0 blocks or 0 bytes
Space used delta in EMP table: 0 blocks or 0 bytes
Space free delta in EMP table: 0 blocks or 0 bytes

Isso significa que não houve alteração no espaço alocado, usado ou livre na tabela EMP desde a última chamada do SPACE_USAGE ou do SPACE_USAGE_DELTA para essa tabela.

Conclusão

O DBMS_SPACE é uma ferramenta importante para o gerenciamento de espaço no Oracle Database, pois ajuda a evitar problemas de desempenho, fragmentação e desperdício de espaço.

Espero que você tenha gostado deste artigo e que ele tenha sido útil para você !

Abs

Referências

Giovano Silva

Giovano Silva

Giovano Silva é um profissional com mais de 10 anos de experiência em tecnologias Oracle, com ênfase em PL/SQL. Ele adora escrever sobre soluções para problemas comuns enfrentados por profissionais Oracle em seu dia a dia. Seu objetivo é compartilhar conhecimento, simplificar conceitos complexos e ajudar a comunidade Oracle a crescer coletivamente.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress