Diagnosticando erro de pouco espaço em disco do PostgreSQL apesar do baixo uso do disco

3

Eu tenho uma aplicação web Django usando um banco de dados PostgreSQL 9.3, que ocasionalmente gera o erro:

File "/usr/local/my_site/.env/lib/python2.7/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/my_site/.env/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
OperationalError: could not write block 2432320 of temporary file: No space left on device
HINT:  Perhaps out of disk space?

Está sendo executado no EC2 / RDS e não consigo encontrar nada com pouco espaço em disco. A instância do EC2 tem uma unidade de 9 GB com apenas 38% em uso. O banco de dados PostgreSQL do RDS possui 20 GB de armazenamento, com apenas 1% de uso. Eu pensei que isso poderia ser um problema de baixo inode na instância do EC2, mas df -i mostra que é apenas 33% em uso.

O que estaria causando esse erro?

    
por Cerin 01.02.2017 / 15:45

1 resposta

9

Você está recebendo este erro porque o PostgreSQL está ficando sem espaço para gravar um arquivo temporário. Você tem pelo menos uma consulta que faz com que o banco de dados, ocasionalmente, escreva uma tabela temporária muito grande para o espaço disponível.

Por padrão, o postgresql usa uma string vazia para a configuração temp_tablespaces ; o que significa que tabelas temporárias são escritas no tablespace padrão (AKA your $ DATA_DIR). Como você está usando o RDS Postgres, você terá que ver o que essa configuração diz usando

select * from pg_settings where name='temp_tablespaces';

Dada a posição do bloco mencionada e usando o tamanho de bloco RDS de 8192. Parece que você está escrevendo quase 20GB de tabelas temporárias que não coincidentemente é a quantidade de tablespace que você tem para esse cluster de banco de dados.

Isso sugere que você tenha uma consulta patológica que crie uma tabela temporária que seja um múltiplo do conteúdo do banco de dados. Você deve tentar registrar todas as consultas indo para o seu banco de dados ( veja os documentos aws para um exemplo) e veja se você consegue identificar onde você está acidentalmente fazendo uma junção cartesiana de duas tabelas e filtrando a saída (ou qualquer outra forma que sua consulta ruim possa ter feito).

Você provavelmente deseja definir temp_file_limit limit como um valor sensato (eu usaria 4 GB), mas isso só tornará o problema subjacente mais visível, já que você atingirá o limite mais cedo.

A solução real para isso é localizar e isolar a consulta que está fazendo com que você use todo esse espaço temporário. A maneira mais fácil é obtê-lo em sql e descobrir por que o Django ORM está produzindo isso.

    
por 01.02.2017 / 21:56