Мы используем Postgres в качестве серверной части БД для нашего проекта Django. Все работает нормально, за исключением того, что время от времени зависает Postgres jus. Средняя загрузка достигает 80 точек, и существует множество процессов отправки сообщений. Насколько я понимаю, проблематичной является наша таблица с пользователями онлайн. По каждому запросу есть обновление, мы обновляем столбец «последний раз видели». Каждую минуту идет cronjob, удаляющий неактивных пользователей на 1 минуту. И в сегодняшнем примере, когда было зависание Postgres, я видел много обновлений и удалений в этой таблице и из нее. Я думаю, это какое-то состояние гонки?
Таблица с пользователями онлайн не большая. В часы пик ~ 800 записей. Вот схема.
Column | Type | Modifiers
------------+--------------------------+-----------------------------------------------------------------
id | integer | not null default nextval('spoleczniak_online_id_seq'::regclass)
postac_id | integer | not null
data | timestamp with time zone | not null
zalogowany | timestamp with time zone | not null
Indexes:
"spoleczniak_online_pkey" PRIMARY KEY, btree (id)
"spoleczniak_online_postac_id_key" UNIQUE CONSTRAINT, btree (postac_id)
"spoleczniak_online_data" btree (data)
Foreign-key constraints:
"spoleczniak_online_postac_id_fkey" FOREIGN KEY (postac_id) REFERENCES postac_postacie(id) DEFERRABLE INITIALLY DEFERRED
Обычно Postgres генерирует менее 1,5 точки средней нагрузки. Мы запускаем его на i7, 16 ГБ ОЗУ и аппаратном RAID-10 (3x2 диска) для ОС / данных + RAID-1 (2 диска) для WAL. Аппаратный RAID имеет 512 МБ кеш-памяти.
Я пробовал бета-версии 9.0 и 9.1 (я даже не установил журналы WAL для этой таблицы в 9.1).
Я действительно думаю о переходе на MySQL, но не знаю никаких инструментов преобразования. :П
PS. Я не знаю, больше ли это Serverfault или Stackoverflow ... но, как вы видите, я решил поместить его на Serverfault. :П
Редактировать:
Некоторая информация из журналов:
Jul 31 20:37:16 postgres postgres[1420]: [3-1] LOG: 00000: process 1420 acquired ExclusiveLock on tuple (29,7) of relation 33107 of database 20005 after 2071.481 ms
Jul 31 20:37:16 postgres postgres[1420]: [3-2] LOCATION: ProcSleep, proc.c:1076
Jul 31 20:37:16 postgres postgres[1420]: [3-3] STATEMENT: UPDATE "spoleczniak_online" SET "postac_id" = 101651, "data" = '2011-07-31 20:39:18.000699', "zalogowany" = '2011-07-31 20:31:04.843741' WHERE "spoleczniak_online"."id" = 559650
Jul 31 20:37:16 postgres postgres[1493]: [3-1] LOG: 00000: process 1493 acquired ExclusiveLock on tuple (29,7) of relation 33107 of database 20005 after 1393.154 ms
Jul 31 20:37:16 postgres postgres[1493]: [3-2] LOCATION: ProcSleep, proc.c:1076
Jul 31 20:37:16 postgres postgres[1493]: [3-3] STATEMENT: UPDATE "spoleczniak_online" SET "postac_id" = 101651, "data" = '2011-07-31 20:39:15.646537', "zalogowany" = '2011-07-31 20:31:04.843741' WHERE "spoleczniak_online"."id" = 559650
Хорошо, проблема с блокировкой ... но как этого избежать?
Это похоже на проблему с блокировкой: некоторые большие запросы слишком сильно блокируются, поэтому другие выполняющиеся запросы не могут быть выполнены, пока блокировка не будет освобождена. Включите медленное ведение журнала запросов, добавьте больше мониторинга. Я настоятельно рекомендую использовать какую-нибудь систему мониторинга (zabbix, zenoss и т. Д.), Чтобы знать статус вашей базы данных postgresql.
В качестве быстрого «мониторинга» взгляните на представления pg_stat_activity и pg_locks во время зависания. Вот хороший запрос, с которого я часто начинаю:
SELECT
datname,
NOW() - query_start AS duration,
procpid,
current_query
FROM
pg_stat_activity
WHERE
current_query <> '<IDLE>'
AND
NOW() - query_start > '1 second'
ORDER BY duration DESC;
Часто это дает достаточно информации, но иногда мне приходится пробегать больше, чтобы понять, что происходит.
Обновите свой вопрос, указав результат этого (или аналогичного) запроса.
Я бы рекомендовал книгу PostgreSQL 9.0 Высокая производительность глава 11, «Активность базы данных и статистика». Еще одно отличное место для решения этой проблемы - список рассылки postgresql-performance.