Estou tentando adicionar um INTEGER DEFAULT 0
campo a uma tabela muito grande (particionada) espalhada por dois tablespaces.
Cada tablespace está em um disco diferente (um na unidade C, o outro na D). Estou tendo o erro a seguir
ERROR: could not extend file "pg_tblspc/31575/PG_10201707211/31576/1155134.27": No space left on device
HINT: Check free disk space
SQL state: 53100
As unidades C e D têm um diretório chamado pg_tblspc/31575/PG_10201707211/31576
, mas nenhum deles tem um arquivo chamado 1155134.27 (acho que é um arquivo temporário?)
A unidade C tem 70 Gbytes de espaço livre, a unidade D 350 Gbytes.
Questão 1 - como posso descobrir qual dos dois discos está realmente com pouco espaço?
Questão 2 - como posso calcular quanto espaço livre é realmente necessário? Um número inteiro requer 4 bytes de armazenamento, a tabela consiste em dados particionados mensais, cada mês tem cerca de 60 milhões de linhas e a tabela tem 4 anos de dados. 4 x 60 x 12 x 4 = cerca de 12.000 Mbytes ou 12 GB, portanto, de acordo com minha matemática simples, deve haver espaço suficiente em qualquer um dos discos para todo o espaço extra necessário. Então, por que o postgres exige mais?
(postgres versão 10.4)
A estrutura de arquivo em cada disco é provavelmente a mesma porque cada espaço de tabela foi criado com comandos muito semelhantes...
CREATE TABLESPACE fastDb OWNER dbOwn LOCATION 'c:/pgdata/fdb';
CREATE TABLESPACE slowDb OWNER dbOwn LOCATION 'd:/pgdata/fdb';
Consegui responder à primeira pergunta simplesmente executando novamente a consulta (leva horas) e monitorando o espaço livre do sistema operacional - d: a unidade está ficando sem espaço.
Ainda não consigo descobrir quanto espaço deve ser necessário. Eu liberei 800 Gb na unidade d: e mudei para um campo SMALLINT (2 bytes em vez de 4), mas ainda estou ficando sem espaço.
O PostgreSQL é um banco de dados de armazenamento de linha, não um banco de dados de armazenamento de coluna. Adicionar uma nova coluna significa reescrever toda a tabela para adicionar o novo valor a cada linha. Para fins transacionais, os dados da tabela antiga não podem ser excluídos até que a nova tabela seja concluída e confirmada. Ele também precisará criar novos índices, enquanto também mantém os índices antigos até o commit.
Adicionado na v11 foi um recurso de padrão rápido, onde adicionar uma nova coluna com um valor padrão constante pode ser feito sem reescrever. Ele apenas armazena a constante no momento da adição como metadados e sabe usar esse valor se encontrar uma linha que não tenha uma entrada para a nova coluna. Mas na v10, você precisará de armazenamento suficiente para reescrever a tabela e os índices.
Vamos dividir o caminho
/31575/PG_10201707211/31576/1155134.27
em partespg_tblspc
-> está em um espaço de tabela31575
-> referências oid do tablespace pg_tablespace .oid
PG_10201707211
-> Versão do Catálogo31576
-> referências oid do banco de dados pg_database .oid
1155134
-> referências de oid de armazenamento pg_class .relfilenode
27
-> é o 28º arquivo (1 GB cada) da relação (digamos tabela).Você pode usar as funções pg_tablespace_location para obter o caminho do tablespace. Aqui está um exemplo para o seu caso;