Назад | Перейти на главную страницу

Диагностика ошибки нехватки места на диске из PostgreSQL, несмотря на низкое использование диска

У меня есть веб-приложение Django, использующее базу данных PostgreSQL 9.3, которое иногда вызывает ошибку:

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?

Он работает на EC2 / RDS, и я не могу найти ничего, на котором мало места на диске. Экземпляр EC2 имеет диск емкостью 9 ГБ, который используется только 38%. База данных RDS PostgreSQL имеет 20 ГБ хранилища, которое используется едва ли 1%. Я думал, что это может быть проблема с низким индексом inode в экземпляре EC2, но df -i показывает, что используется только 33%.

Что может вызвать эту ошибку?

Вы получаете эту ошибку, потому что PostgreSQL не хватает места для записи временного файла. У вас есть хотя бы один запрос, который заставляет базу данных иногда записывать временную таблицу, размер которой слишком велик для доступного пространства.

По умолчанию postgresql использует пустую строку для temp_tablespaces конфигурация; это означает, что временные таблицы записываются в табличное пространство по умолчанию (также известное как ваш $ DATA_DIR). Поскольку вы используете RDS Postgres, вам нужно будет увидеть, что говорит этот параметр, используя

select * from pg_settings where name='temp_tablespaces';

Учитывая упомянутую позицию блока и размер блока RDS 8192. Похоже, вы записываете почти 20 ГБ временных таблиц, что не случайно является объемом табличного пространства, имеющимся у вас для этого кластера базы данных.

Это говорит о том, что у вас есть патологический запрос, который создает временную таблицу, кратную содержимому вашей базы данных. Вам следует попробовать регистрировать все запросы, поступающие в вашу базу данных ( см. документы AWS в качестве примера) и посмотрите, сможете ли вы определить, где вы случайно выполняете декартово соединение двух таблиц и фильтруете вывод (или любую другую форму, которую мог принять ваш неправильный запрос).

Вы, вероятно, захотите установить temp_file_limit ограничение до разумного значения (я бы выбрал 4 ГБ), но это только сделает основную проблему более заметной, поскольку вы достигнете предела раньше.

Настоящее решение - найти и изолировать запрос, который заставляет вас использовать все это временное пространство. Самый простой способ - получить его в sql и выяснить, почему Django ORM это создает.