Preciso executar o VACUUM FULL sem espaço em disco disponível
27
Eu tenho uma tabela que ocupa quase 90% do espaço em hd no nosso servidor. Decidi soltar algumas colunas para liberar espaço. Mas preciso retornar o espaço para o sistema operacional. O problema, porém, é que não tenho certeza do que acontecerá se eu executar o VACUUM FULL e não houver espaço livre suficiente para fazer uma cópia da tabela.
Entendo que o VACUUM FULL não deve ser usado, mas achei que era a melhor opção nesse cenário.
Como você não tem espaço suficiente para executar um vácuo ou reconstruir, sempre é possível reconstruir seus bancos de dados postgresql restaurando-os. A restauração de bancos de dados, tabelas e índices liberará espaço e desfragmentação. Posteriormente, você pode configurar a manutenção automatizada para limpar seus bancos de dados regularmente.
1 Faça backup de todos os bancos de dados em seu servidor postgresql
Você deseja fazer backup de todos os seus bancos de dados em uma partição que tenha espaço suficiente. Se você estava no Linux, pode usar o gzip para compactar ainda mais o backup e economizar espaço
su - postgres
pg_dumpall | gzip -9>/some/partition/all.dbs.out.gz
Obrigado, foi isso que acabei fazendo, com algumas diferenças. Acabei de soltar o banco de dados depois de fazer o backup. Em seguida, criou um novo e o restaurou.
30712 Justin
De nada. Imaginei que remover o conteúdo do diretório de dados e executar o initdb seria suficiente.
Craig Efrein
Worked great, I just recommend skipping the gzip part to save time.
Rafael Barbosa
17
NOTA: Eu testei isso na 9.1. Não tenho nenhum servidor 9.0 por aqui. Tenho muita certeza de que ele funcionará no 9.0.
CUIDADO (Conforme observado nos comentários de @erny):
Note that high CPU load due to I/O operations may be expected.
Você pode fazer isso praticamente sem tempo de inatividade usando um espaço de tabela temporário. O tempo de inatividade será na forma de bloqueios exclusivos. Mas apenas na mesa você está aspirando. Então, tudo o que acontecerá é que as consultas do cliente simplesmente aguardarão a aquisição do bloqueio se eles acessarem a tabela em questão. Você não precisa fechar as conexões existentes.
Uma coisa a ter em mente, porém, é que mover a mesa e o vácuo cheio precisará esperar primeiro um bloqueio exclusivo!
Primeiro, você obviamente precisa de algum armazenamento adicional. Como Stéphanemencionado nos comentários, isso precisa ser pelo menos duas vezes maior que a tabela em questão, VACUUM FULLassim como uma cópia completa. Se você tiver sorte e puder adicionar dinamicamente um disco à máquina, faça isso. Na pior das hipóteses , você pode simplesmente conectar um disco USB (embora seja arriscado e lento)!
Em seguida, monte o novo dispositivo e disponibilize-o como espaço de tabela:
Você pode listar os espaços de tabela facilmente usando:
\db
Verifique duas vezes o espaço de tabela atual da sua tabela (você precisa saber para onde movê-lo de volta):
SELECT tablespace FROM pg_tables WHERE tablename ='mytable';
Se for NULL, ele estará no espaço de tabela padrão:
SHOW default_tablespace;
Se isso é NULLassim, ele provavelmente vai ser pg_default(confira os documentos oficiais em caso é alterado).
Agora mova a mesa para cima:
ALTERTABLE mytable SET TABLESPACE tempspace;COMMIT;-- if autocommit is off
Vácuo:
VACUUM FULL mytable;
Mover para trás:
-- assuming you are using the defaults, the tablespace will be "pg_default".-- Otherwise use the value from the SELECT we did earlier.ALTERTABLE mytable SET TABLESPACE pg_default;COMMIT;-- if autocommit is off
NB: o movimento parece usar mais espaço em disco no diretório de dados original ...
Chris Withers
Apenas testei na 9.3 e funciona como um encanto.
Bartek Jablonski
Utilizado com sucesso na produção em 9.1. Após alterar o espaço de tabela, o espaço usado original é liberado. Observe que alta carga da CPU devido a operações de E / S pode ser esperada.
erny 29/07
2
Dicas incríveis, obrigado por esta explicação detalhada. Observe que no espaço de tabela temporário você precisará pelo menos size of table x 2, pois VACUUM FULLestá fazendo uma cópia completa da tabela.
Stéphane
Obrigado @ Stéphane. Eu adicionei as informações ao corpo principal.
Exhuma
2
Rapido e sujo:
Parar Postgres
Mova o diretório principal do banco de dados para outro disco em que haja espaço suficiente para aspirar
No local original de main, adicione um link simbólico para o novo local
Vácuo
Exclua o link simbólico e mova o diretório principal de volta ao seu local original
Se você tiver espaço em disco para executar um despejo e restauração, deverá ter espaço em disco para executar um aspirador de pó - completo. O problema é que o vacuumdb --full fará uma cópia de todo o arquivo de dados. Então, o que você poderia fazer é:
copie os arquivos que mantêm a grande mesa em uma unidade diferente, por exemplo, uma unidade maior e mais lenta.
faça links simbólicos do local original para o novo local na outra unidade.
execute vacuumdb --full, agora ele deve ler os dados do outro disco e gravar a tabela final no seu disco de dados original.
gzip
part to save time.NOTA: Eu testei isso na 9.1. Não tenho nenhum servidor 9.0 por aqui. Tenho muita certeza de que ele funcionará no 9.0.
CUIDADO (Conforme observado nos comentários de @erny):
Você pode fazer isso praticamente sem tempo de inatividade usando um espaço de tabela temporário. O tempo de inatividade será na forma de bloqueios exclusivos. Mas apenas na mesa você está aspirando. Então, tudo o que acontecerá é que as consultas do cliente simplesmente aguardarão a aquisição do bloqueio se eles acessarem a tabela em questão. Você não precisa fechar as conexões existentes.
Uma coisa a ter em mente, porém, é que mover a mesa e o vácuo cheio precisará esperar primeiro um bloqueio exclusivo!
Primeiro, você obviamente precisa de algum armazenamento adicional. Como
Stéphane
mencionado nos comentários, isso precisa ser pelo menos duas vezes maior que a tabela em questão,VACUUM FULL
assim como uma cópia completa. Se você tiver sorte e puder adicionar dinamicamente um disco à máquina, faça isso. Na pior das hipóteses , você pode simplesmente conectar um disco USB (embora seja arriscado e lento)!Em seguida, monte o novo dispositivo e disponibilize-o como espaço de tabela:
Você pode listar os espaços de tabela facilmente usando:
Verifique duas vezes o espaço de tabela atual da sua tabela (você precisa saber para onde movê-lo de volta):
Se for
NULL
, ele estará no espaço de tabela padrão:Se isso é
NULL
assim, ele provavelmente vai serpg_default
(confira os documentos oficiais em caso é alterado).Agora mova a mesa para cima:
Vácuo:
Mover para trás:
Remova o espaço temporário:
fonte
size of table x 2
, poisVACUUM FULL
está fazendo uma cópia completa da tabela.Rapido e sujo:
Por exemplo,:
$ service postgresql stop $ mv /var/lib/postgresql/9.5/main /mnt/bigdisk $ ln -sr /mnt/bigdisk/main /var/lib/postgresql/9.5 $ vacuumdb --all --full $ rm /var/lib/postgresql/9.5/main $ mv /mnt/bigdisk/main /var/lib/postgresql/9.5 $ service postgresql start
fonte
Se você tiver espaço em disco para executar um despejo e restauração, deverá ter espaço em disco para executar um aspirador de pó - completo. O problema é que o vacuumdb --full fará uma cópia de todo o arquivo de dados. Então, o que você poderia fazer é:
fonte