У меня есть веб-приложение 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 это создает.