O aumento excessivo de tabelas e índices ocorre quando a operação de limpeza não acompanha a taxa de linguagem de manipulação de dados (DML) em uma tabela. Algum aumento de tabelas e índices é inevitável e geralmente aceitável porque as transações podem reutilizar esse espaço. O bloat grave causa problemas de desempenho, como tempos de consulta mais lentos, aumento de E/S, uso menos eficiente de buffer e cache compartilhados e aumento dos custos de armazenamento.
A melhor maneira de estimar o aumento é usar o módulo
pgstattuple. No entanto, usar pgstattuple é menos eficiente quando a extensão precisa
ler todas as páginas de uma relação. Se não for possível usar o pgstattuple, use outros scripts para estimar o aumento, embora essa abordagem seja menos precisa.
Ler a saída do pgstattuple
Quando você usa pgstattuple para informar as características de armazenamento físico de uma
tabela ou índice, a saída tem o seguinte formato:
> SELECT * FROM pgstattuple('large_table');
-[ RECORD 1 ]------+-----------
table_len | 7431888896
tuple_count | 66666666
tuple_len | 2796296271
tuple_percent | 37.63
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 3873153652
free_percent | 52.12
A seguir, descrevemos a saída:
table_len(7431888896)- O tamanho total da tabela em bytes. Ele inclui todas as tuplas ativas, tuplas
inativas e espaço livre. Nesse caso,
large_tableocupa aproximadamente 7.088 GB. tuple_count(66666666)- Representa o número de tuplas ativas (linhas visíveis e ativas) na tabela. A tabela contém aproximadamente 66 milhões de linhas ativas.
tuple_len(2796296271)- O comprimento total em bytes de todas as tuplas ativas combinadas, que é de aproximadamente 2,6 GB.
tuple_percent(37.63)A porcentagem do
table_lenocupada por tuplas ativas. O cálculo é feito da seguinte forma:(
tuple_len/table_len) ∗ 100 = (2796296271/7431888896) ∗ 100 ≈37.63%Esse resultado indica que os dados ativos usam menos de 40% do espaço em disco da tabela.
dead_tuple_count(0)O número de tuplas mortas (linhas que as operações de limpeza ainda não removeram após atualizações ou exclusões). Um valor de
0significa que a tabela está limpa e não tem tuplas inativas aguardando recuperação. Isso geralmente sugere queVACUUMou autovacuum é executado com eficiência na tabela.dead_tuple_len(0)O comprimento total em bytes de todas as tuplas mortas. De acordo com
dead_tuple_count, um valor de0significa que as linhas inativas não consomem espaço.dead_tuple_percent(0)A porcentagem do
table_lenocupada por tuplas inativas. O cálculo é feito da seguinte forma:(
dead_tuple_len/table_len) ∗ 100 = (0/7431888896) ∗ 100 =0%free_space(3873153652)Esse valor representa a quantidade de espaço livre nas páginas de dados da tabela. É possível reutilizar esse espaço para novas inserções ou atualizações sem precisar expandir a tabela. Isso indica uma quantidade significativa de espaço livre, aproximadamente 3,7 GB.
free_percent(52.12)Esse valor representa a porcentagem do
table_lenque é espaço livre. O cálculo é feito da seguinte forma:(
free_space/table_len) ∗ 100 = (3873153652/7431888896) ∗ 100 ≈52.12%
Estimar o aumento usando consultas
É possível estimar o aumento usando consultas em tabelas do catálogo do sistema, mas esse método é menos preciso do que usar extensões como pgstattuple. Se você usar scripts como Verificação de bloat da tabela do PostgreSQL, as estatísticas da tabela precisam estar atualizadas. Caso contrário, a estimativa será imprecisa.
Ao comparar a saída de uma consulta com o módulo pgstattuple, as estimativas são comparáveis, mas não são medidas exatas de inflacionamento. O módulo ainda é a medição mais precisa de bloat porque a consulta SQL depende do mecanismo de estatísticas cumulativas do PostgreSQL, enquanto o módulo lê as páginas de dados reais.
O exemplo a seguir compara a saída de dois métodos diferentes para analisar o aumento de tabelas no PostgreSQL para uma tabela chamada large_table.
> SELECT * FROM pgstattuple('large_table');
-[ RECORD 1 ]------+-----------
table_len | 2475892736
tuple_count | 22000000
tuple_len | 922925931
tuple_percent | 37.28
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 1293696900
free_percent | 52.25
Vs.
-[ RECORD 1 ]+------------
databasename | postgres
schemaname | public
tablename | large_table
can_estimate | t
est_rows | 21965400
pct_bloat | 54
mb_bloat | 1269.24
table_mb | 2361.195
Excesso de endereços
É possível gerenciar o aumento de tamanho das seguintes maneiras, cada uma com vantagens e desvantagens que exigem um planejamento cuidadoso:
- Faça uma limpeza completa. Essa operação requer um bloqueio completo da tabela durante a duração do vácuo e exige tempo de inatividade.
- Mova os dados para uma nova tabela. Para usar esse método, é necessário interromper as mudanças na tabela para garantir que elas não sejam transferidas para a nova relação.
- Use
pg_squeeze. Essa extensão reduz o excesso de informações on-line. A extensão cria uma tabela de sombra, insere todos os dados e mantém as alterações da tabela usando um slot de replicação até a última etapa, que é a troca da tabela inchada pela tabela não inchada recém-criada. Em seguida, ele solicita um bloqueio breve da tabela para mover a tabela não inchada e substituir a tabela inchada. Esse método exige o dobro do espaço do objeto durante a operação, mas é o menos intrusivo para a operação normal.