A extensão pg_squeeze recupera espaço em disco de tabelas e índices inchados no ApsaraDB RDS for PostgreSQL sem bloquear operações de leitura ou escrita.
Pré-requisitos
Antes de começar, verifique se você possui:
Uma instância RDS executando a versão secundária do mecanismo 20240229 ou posterior. Para o PostgreSQL 17, a versão secundária do mecanismo deve ser 20241030 ou posterior. Para verificar e atualizar sua versão, consulte Atualizar a versão secundária do mecanismo.
-
Os seguintes parâmetros configurados na sua instância RDS. Para obter detalhes, consulte Modificar os parâmetros de uma instância do ApsaraDB RDS for PostgreSQL:
wal_leveldefinido comologicalpg_squeezeadicionado ashared_preload_libraries
Espaço livre em disco suficiente. A extensão requer pelo menos o dobro do tamanho combinado da tabela e de seus índices. Por exemplo, se uma tabela e seus índices totalizarem 1 GB, você precisará de pelo menos 2 GB de espaço livre adicional.
Como funciona
O PostgreSQL utiliza o Controle de Concorrência Multiversão (MVCC) para gerenciar transações simultâneas. Quando uma linha é atualizada ou excluída, o PostgreSQL marca a versão antiga da linha como um dead tuple em vez de sobrescrevê-la. Os dead tuples são invisíveis para novas transações, mas continuam ocupando espaço em disco. Com o tempo, esse acúmulo resulta no inchaço da tabela.
O autovacuum consegue limpar dead tuples, mas não elimina totalmente o inchaço da tabela, pois o espaço anteriormente ocupado por eles não é recuperado imediatamente. O comando VACUUM FULL recupera esse espaço, mas exige um Access Exclusive Lock, tornando a tabela inacessível durante toda a operação.
A extensão pg_squeeze opera de forma diferente: ela reconstrói a tabela criando uma nova cópia da original, o que elimina os dead tuples. A tabela permanece disponível para leituras e escritas durante todo esse processo. Além disso, é possível executar instruções SQL diretamente, sem a necessidade de usar um cliente externo.
Detectar inchaço de tabela
Tabelas com operações frequentes de UPDATE ou DELETE são as mais propensas ao inchaço. Utilize o SQL abaixo para estimar a taxa de inchaço de uma tabela específica:
CREATE EXTENSION pgstattuple;
SELECT *, 1.0 - tuple_len::numeric / table_len AS bloat FROM pgstattuple('your_relation');
A taxa de inchaço representa a proporção de espaço não utilizado na tabela:
bloat rate = 1 - (live tuple space / total table space)
Esta consulta realiza uma varredura completa na tabela. Execute-a fora dos horários de pico em tabelas grandes.
Limitações
A tabela deve possuir uma chave única.
O processo de limpeza consome uma quantidade significativa de recursos de I/O. Recomendamos realizar a limpeza fora dos horários de pico.
Para limpar tabelas em vários bancos de dados, crie a extensão separadamente em cada banco de dados.
Configurar o pg_squeeze
Crie a extensão no banco de dados de destino:
CREATE EXTENSION pg_squeeze;
Para remover a extensão:
DROP EXTENSION pg_squeeze;
Reduzir tabelas inchadas
Compactação única de tabela
Execute a instrução a seguir para compactar uma tabela imediatamente. Este exemplo limpa a tabela bar no schema public:
SELECT squeeze.squeeze_table('public', 'bar');
Compactação automática agendada
Para tabelas que acumulam inchaço regularmente, configure uma tarefa de limpeza agendada.
Etapa 1: Registre a tabela e o agendamento.
O exemplo a seguir agenda a tabela foo no schema public para ser compactada todas as quartas e sextas-feiras às 22:30:
INSERT INTO squeeze.tables (tabschema, tabname, schedule)
VALUES ('public', 'foo', ('{30}', '{22}', NULL, NULL, '{3, 5}'));
Para a sintaxe completa do agendamento, consulte a documentação do pg_squeeze.
Etapa 2: Inicie o worker.
Escolha um dos métodos a seguir para iniciar o worker em segundo plano:
-
Iniciar manualmente com SQL:
SELECT squeeze.start_worker(); -- Start SELECT squeeze.stop_worker(); -- Stop -
Iniciar automaticamente na reinicialização do banco de dados: Defina os seguintes parâmetros no console do ApsaraDB RDS e reinicie o banco de dados. Para obter detalhes, consulte Modificar os parâmetros de uma instância do ApsaraDB RDS for PostgreSQL.
NotaA conta
rds_superuserdeve ser uma conta privilegiada. Crie a extensãopg_squeezeem cada banco de dados listado antes que o worker seja iniciado. Para obter detalhes, consulte Configurar o pg_squeeze.squeeze.worker_autostart = 'database1 database2' squeeze.worker_role = rds_superuser