Diferença do PostgreSQL entre VACUUM FULL e CLUSTER

13

Eu tenho uma tabela com 200 GB de tamanho ocupado por dados e 180 GB de tamanho pelos 6 índices nele. Como está inchado em 30%, quero recuperar o espaço indesejado ocupado por ele. Está agrupado no job_id_idíndice x.

Então, para recuperar o espaço, preciso usar clustercomando ou vacuum fullcomando?

  1. Qual é a diferença entre esses dois comandos?

  2. A vacuum fullordem por alguma coluna é igual ao clustercomando?

  3. O índice é recriado nos dois comandos?

  4. No meu caso, qual será mais rápido?

A versão do banco de dados PostgreSQL é 9.1

Arun P
fonte
1
Sim, os índices serão recriados. O que é mais rápido depende de algumas coisas, imagino. Mas uma coisa é certa: não há nada como "vácuo da ordem completa por alguma coluna".
Dezso
1
Permitam-me mencionar também que o VACUUM não pode ser executado dentro de uma transação que, em muitos casos, faz do CLUSTER uma alternativa melhor (e às vezes a única alternativa) que produz resultados semelhantes.
oᴉɹǝɥɔ

Respostas:

8

Para verificar o que CLUSTERaconteceu, tirei uma tabela da minha de um experimento anterior que continha basicamente os primeiros 10 milhões de números inteiros positivos. Eu já excluí algumas linhas e também existe uma outra coluna, mas elas afetam apenas o tamanho real da tabela, portanto não é tão interessante.

Primeiro, tendo corrido VACUUM FULLsobre a mesa fka, tomei seu tamanho:

\dt+ fka
                    List of relations
 Schema | Name | Type  |  Owner   |  Size  | Description 
--------+------+-------+----------+--------+-------------
 public | fka  | table | test     | 338 MB | 

Então vamos ver a ordem física dos dados desde o início da tabela:

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   5 | 5    | (0,4)
   6 | 6    | (0,5)

Agora vamos excluir algumas linhas:

DELETE FROM fka WHERE id % 10 = 5;
--DELETE 1000000

Depois disso, o tamanho da tabela relatada não foi alterado. Então, vamos ver agora o que CLUSTERfaz:

CLUSTER fka USING fka_pkey;

SELECT *, ctid FROM fka ORDER BY ctid LIMIT 5;

 id  | col1 |  ctid   
-----+------+---------
   2 | 2    | (0,1)
   3 | 3    | (0,2)
   4 | 4    | (0,3)
   6 | 6    | (0,4)
   7 | 7    | (0,5)

Após a operação, o tamanho da tabela mudou de 338 para 296 MB. Na ctidcoluna, que descreve o local físico da tupla na página, você também vê que não há espaços onde a correspondência de linha id = 5costumava estar.

À medida que as tuplas foram reordenadas, os índices deveriam ter sido recriados para que apontassem para os locais corretos.

Portanto, parece que a diferença é que VACUUM FULLnão ordena as linhas. Até onde eu sei, há alguma diferença no mecanismo que os dois comandos usam, mas, do ponto de vista prático, essa parece ser a principal (apenas?) Diferença.

dezso
fonte
Eu não tinha certeza do que é a ctidcoluna. Acontece que é uma coluna do sistema que descreve a localização física da linha em sua tabela. postgresql.org/docs/current/ddl-system-columns.html
Gajus
8

VACUUM FULLreescreve todo o conteúdo da tabela em um novo arquivo de disco sem espaço extra, permitindo que o espaço não utilizado retorne ao sistema operacional. Esse método também requer espaço em disco extra, pois grava uma nova cópia da tabela e não libera a cópia antiga até que a operação seja concluída. Geralmente, isso só deve ser usado quando uma quantidade significativa de espaço precisa ser recuperada de dentro da tabela.

http://www.postgresql.org/docs/9.1/static/sql-vacuum.html

CLUSTERinstrui o PostgreSQL a agrupar a tabela especificada por table_name com base no índice especificado por index_name. O índice já deve ter sido definido em table_name. Quando uma tabela é agrupada em cluster, ela é reordenada fisicamente com base nas informações do índice e um bloqueio ACCESS EXCLUSIVE é adquirido nela.

http://www.postgresql.org/docs/9.1/static/sql-cluster.html

também interessante: is-a-reindex-required-after-cluster

Mas talvez tudo o que você precise seja simples, REINDEXque reconstrua um índice usando os dados armazenados na tabela do índice, substituindo a cópia antiga do índice.

http://www.postgresql.org/docs/9.1/static/sql-reindex.html

cptPH
fonte
1
Woah! Ótima dica sobre o REINDEX também! Estive encolhendo algumas tabelas por VACUUM e CLUSTER (tentando comparar tempos e impactos para fazê-lo ao vivo) e agora meus maiores objetos são na verdade índices.
7763 Mike