У меня есть сервер с Postgres 9.1.15. Сервер имеет 2 ГБ ОЗУ и без обмена. Периодически Postgres начнет получать ошибки "из памяти" на некоторых SELECT и будет продолжать делать это до тех пор, пока я не перезапущу Postgres или некоторые из клиентов, которые к нему подключены. Что странно, когда это происходит, free
все еще сообщает о 500 МБ свободной памяти.
select version();
:
PostgreSQL 9.1.15 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit
uname -a
:
Linux db 3.2.0-23-virtual #36-Ubuntu SMP Tue Apr 10 22:29:03 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
Postgresql.conf(все остальное закомментировано/по умолчанию):
max_connections = 100
shared_buffers = 500MB
work_mem = 2000kB
maintenance_work_mem = 128MB
wal_buffers = 16MB
checkpoint_segments = 32
checkpoint_completion_target = 0.9
random_page_cost = 2.0
effective_cache_size = 1000MB
default_statistics_target = 100
log_temp_files = 0
Я получил эти значения из pgtune (я выбрал "смешанные типы приложений" ), и они играли с ними на основе того, что я читал, без делая значительный реальный прогресс. На данный момент существует 68 соединений, которые являются типичным числом (я еще не использую pgbouncer или любые другие пулы соединений).
/etc/sysctl.conf
:
kernel.shmmax=1050451968
kernel.shmall=256458
vm.overcommit_ratio=100
vm.overcommit_memory=2
Сначала я изменил overcommit_memory
на 2 около двух недель назад после того, как убийца OOM убил сервер Postgres. До этого сервер работал хорошо в течение длительного времени. Ошибки, которые я получаю сейчас, менее катастрофичны, но гораздо более раздражают, потому что они намного чаще.
Мне не удалась точно определить первое событие, которое заставляет postgres запускать "вне памяти" - каждый раз кажется, что они разные. В последний раз, когда он разбился, первые три строки были зарегистрированы:
2015-04-07 05:32:39 UTC ERROR: out of memory
2015-04-07 05:32:39 UTC DETAIL: Failed on request of size 125.
2015-04-07 05:32:39 UTC CONTEXT: automatic analyze of table "xxx.public.delayed_jobs"
TopMemoryContext: 68688 total in 10 blocks; 4560 free (4 chunks); 64128 used
[... snipped heaps of lines which I can provide if they are useful ...]
---
2015-04-07 05:33:58 UTC ERROR: out of memory
2015-04-07 05:33:58 UTC DETAIL: Failed on request of size 16.
2015-04-07 05:33:58 UTC STATEMENT: SELECT oid, typname, typelem, typdelim, typinput FROM pg_type
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
2015-04-07 05:33:59 UTC LOG: could not fork new process for connection: Cannot allocate memory
TopMemoryContext: 396368 total in 50 blocks; 10160 free (28 chunks); 386208 used
[... snipped heaps of lines which I can provide if they are useful ...]
---
2015-04-07 05:33:59 UTC ERROR: out of memory
2015-04-07 05:33:59 UTC DETAIL: Failed on request of size 1840.
2015-04-07 05:33:59 UTC STATEMENT: SELECT... [nested select with 4 joins, 19 ands, and 2 order bys]
TopMemoryContext: 388176 total in 49 blocks; 17264 free (55 chunks); 370912 used
Сбой перед этим, несколькими часами ранее, просто имел три экземпляра последнего запроса в качестве первых трех строк аварии. Этот запрос запускается очень часто, поэтому я не уверен, являются ли проблемы из-за этого запроса, или если он просто появляется в журнале ошибок, потому что это достаточно сложный запуск SELECT все время. Тем не менее, здесь EXPLAIN ANALYZE: http://explain.depesz.com/s/r00
Это то, что ulimit -a
для пользователя postgres выглядит следующим образом:
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 15956
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 1024
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 15956
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Я попробую и получаю точные цифры от free
в следующий раз, когда произойдет сбой, тем временем это будет braindump всей информации, которую у меня есть.
Любые идеи о том, куда идти отсюда?