Cargas intensas de UPDATE causam inchaço nas tabelas: tuplas mortas se acumulam e aumentam o tamanho da tabela mesmo após a execução do VACUUM. A extensão pg_repack recupera esse espaço no ApsaraDB RDS for PostgreSQL sem manter um bloqueio exclusivo na tabela durante toda a operação, tornando-a menos disruptiva que CLUSTER ou VACUUM FULL.
Pré-requisitos
Antes de começar, certifique-se de que:
A instância executa o PostgreSQL 10 ou superior
A versão secundária do mecanismo é 20240229 ou superior (para o PostgreSQL 17, é necessária a versão 20241030 ou superior)
Para atualizar a versão secundária do mecanismo, consulte Atualizar a versão secundária do mecanismo de uma instância ApsaraDB RDS for PostgreSQL.
Se a versão secundária do mecanismo for anterior a 20240229, a execução de qualquer função pg_repack retornará ERROR: must be superuser to use xxx function.
Limitações
Não é possível recompactar tabelas temporárias ou índices GiST
Durante a recompactação de tabela completa, instruções DDL na tabela são bloqueadas. O pg_repack mantém um bloqueio ACCESS SHARE para impor isso
A recompactação de tabela completa exige armazenamento disponível com pelo menos o dobro do tamanho da tabela alvo
A recompactação de tabela completa consome muita E/S. Em uma instância com Enhanced SSD (ESSD) no nível de desempenho 1 (PL1), recompactar uma tabela de 100 GB pode saturar o throughput máximo de E/S de 250 MB/s — execute fora dos horários de pico
Como funciona
Recompactação de tabela completa
O pg_repack reconstrói a tabela em sete etapas:
Cria uma tabela de log para capturar alterações feitas na tabela original durante a recompactação
Adiciona triggers à tabela original para gravar cada INSERT, UPDATE e DELETE na tabela de log
Copia todas as linhas para uma nova tabela
Cria índices na nova tabela
Aplica as alterações acumuladas da tabela de log à nova tabela
Troca as tabelas original e nova no catálogo do sistema
Exclui a tabela original
O pg_repack mantém um bloqueio ACCESS EXCLUSIVE nas etapas 1, 2, 6 e 7. Nas demais etapas, mantém apenas um bloqueio ACCESS SHARE, permitindo que operações de INSERT, UPDATE e DELETE na tabela original continuem sem interrupção.
Recompactação apenas de índice
Cria novos índices simultaneamente
Troca os índices original e novo no catálogo do sistema
Exclui os índices originais
Ativar ou desativar o pg_repack
Execute estas instruções usando a conta privilegiada.
-- Enable
CREATE EXTENSION pg_repack;
-- Disable
DROP EXTENSION pg_repack;
Instalar o utilitário cliente pg_repack
O cliente de linha de comando pg_repack é executado na sua instância Elastic Compute Service (ECS) e se conecta remotamente à instância RDS. As etapas a seguir se aplicam a instâncias ECS executando Alibaba Cloud Linux 3.2104 ou superior.
-
Instale as dependências de compilação:
sudo yum install postgresql* redhat-rpm-config libpq* openssl-devel readline-devel -y -
Adicione os binários do PostgreSQL ao seu path:
NotaO path e a versão do PostgreSQL no comando acima são exemplos. Substitua-os pelos valores do seu ambiente.
export PATH=$PATH:/usr/lib64/pgsql/postgresql-12/bin -
Baixe, compile e instale o cliente:
wget https://github.com/reorg/pg_repack/archive/refs/tags/ver_1.4.6.tar.gz tar zxvf ver_1.4.6.tar.gz cd pg_repack-ver_1.4.6 make && make install
Recompactar uma tabela
Verificar armazenamento disponível
A recompactação de tabela completa exige armazenamento disponível com pelo menos o dobro do tamanho da tabela. Antes de recompactar, verifique se há espaço livre suficiente.
Execute as consultas a seguir para verificar o tamanho da tabela e estimar o armazenamento necessário:
-- Check total table size (including TOAST and indexes)
SELECT pg_size_pretty(pg_total_relation_size('schema1.table1')) AS total_size;
-- Check heap size only
SELECT pg_size_pretty(pg_relation_size('schema1.table1')) AS heap_size;
Provisione pelo menos 2 vezes o tamanho total atual da tabela como armazenamento livre antes de iniciar uma recompactação de tabela completa.
Execução de teste (recomendado)
Execute com --dry-run para validar a operação sem fazer alterações:
pg_repack --dry-run --no-superuser-check --echo --no-order \
-h <endpoint> -p <port> -d <database> -U <user> \
--table schema1.table1
Recompactação de tabela completa
pg_repack --no-superuser-check --echo --no-order \
-h <endpoint> -p <port> -d <database> -U <user> \
--table schema1.table1
Substitua os espaços reservados pelos valores reais:
|
Espaço reservado |
Descrição |
Exemplo |
|
|
Endpoint da instância RDS |
|
|
|
Número da porta |
|
|
|
Nome do banco de dados |
|
|
|
Nome de usuário do banco de dados |
|
Verificar o resultado
Verifique o tamanho da tabela antes e depois da recompactação para confirmar a recuperação do espaço.
Antes da recompactação:
SELECT pg_size_pretty(pg_relation_size('schema1.table1'));
Após a recompactação, execute a mesma consulta. Uma recompactação bem-sucedida mostra um valor menor.
Solução de problemas
Erro: pg_repack failed with error: You must be a superuser to use pg_repack
Adicione -k (ou --no-superuser-check) para ignorar a verificação de superusuário:
pg_repack -k --no-superuser-check ...
Ao recompactar uma tabela completa, não é possível usar este método para obter permissões.
Referência
Reorganizar tabelas em bancos de dados PostgreSQL com bloqueios mínimos — documentação oficial do pg_repack