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

Постгрес, время от времени просто зависает

Мы используем 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.