[Postgre 9.6] CPU 100% и heavy disk I/O
От: dimb82  
Дата: 04.12.16 11:26
Оценка:
Установил Postgre 9.6. База данных очень простая. Всего несколько таблиц. С этими таблицами работают скрипты — читают и пишут (на 3 серверах, всего процессов около 30-40). Однако, такая вроде бы слабая нагрузка приводит к всегда 100% загруженности процессора. Также вижу, что процессы Postgre производят очень много операций записи. Некоторые процессы postgres.exe жрут по 10% и более. Я проверил время выполнения запросов. Все запросы выполняются более, чем за 0.5 секунд. Запросов в секунду немного. Не более 10.

Я попробовал увеличить значение shared_buffers с 128M до 1GB, но помогло несильно.
Что ещё можно попробовать?
Re: [Postgre 9.6] CPU 100% и heavy disk I/O
От: kov_serg Россия  
Дата: 04.12.16 11:42
Оценка:
Здравствуйте, dimb82, Вы писали:


D>Установил Postgre 9.6. База данных очень простая. Всего несколько таблиц. С этими таблицами работают скрипты — читают и пишут (на 3 серверах, всего процессов около 30-40). Однако, такая вроде бы слабая нагрузка приводит к всегда 100% загруженности процессора. Также вижу, что процессы Postgre производят очень много операций записи. Некоторые процессы postgres.exe жрут по 10% и более. Я проверил время выполнения запросов. Все запросы выполняются более, чем за 0.5 секунд. Запросов в секунду немного. Не более 10.


D>Я попробовал увеличить значение shared_buffers с 128M до 1GB, но помогло несильно.

D>Что ещё можно попробовать?

procmon от sysinternals и посмотри куда пишут.
Re[2]: [Postgre 9.6] CPU 100% и heavy disk I/O
От: dimb82  
Дата: 04.12.16 13:04
Оценка:
Запись в файлы БД:

Image PID File Read (B/sec) Write (B/sec) Total (B/sec) I/O Priority Response Time (ms)
System 4 C:\Program Files\PostgreSQL\9.6\data\base\16393\16595 0 60,416 60,416 Normal 5

и в логи:
Image PID File Read (B/sec) Write (B/sec) Total (B/sec) I/O Priority Response Time (ms)
postgres.exe 4736 C:\Program Files\PostgreSQL\9.6\data\pg_xlog\00000001000000070000002A 0 30,840 30,840 Normal 4


Данные по использованию CPU:
Image PID Description Status Threads CPU Average CPU
postgres.exe 4736 PostgreSQL Server Running 3 21 17.73
postgres.exe 4552 PostgreSQL Server Running 3 20 14.12
postgres.exe 4724 PostgreSQL Server Running 3 19 11.71
postgres.exe 4640 PostgreSQL Server Running 3 9 7.74
postgres.exe 4696 PostgreSQL Server Running 3 13 5.79
postgres.exe 4648 PostgreSQL Server Running 3 0 4.05
Re: [Postgre 9.6] CPU 100% и heavy disk I/O
От: Иль  
Дата: 04.12.16 15:57
Оценка:
Здравствуйте, dimb82, Вы писали:

D>Что ещё можно попробовать?


Запросы-то какие? Какая схема данных? Какие индексы имеются? Сколько записей в таблицах? Какие размеры таблиц?

По описанным симптомам первая мысль, что вакуум почему-то не справляется и таблицы/индексы поплыли. Поэтому первым делом я бы проверил эту версию скриптами вот отсюда. Если таблицы и/или индексы раздулись, то надо смотреть почему. Может быть есть idle in trasaction или присутствуют холостые апдейты...

Но вообще может быть куча вариантов почему всё так тормозит.

Кстати безусловное увеличение shared memory может иногда приводить к противоположным ожидаемым результатам. БД может начать "захлёбываться" во время чекпоинтов. См. например тут:

And, if you can't fit the entire working set inside shared_buffers, then there are a number of reasons to keep it relatively small, in line with the formula above. If the working set is larger than shared_buffers, most buffer accesses will miss the database buffer cache and fault a page in from the OS; clearly, it makes no sense to allocate a large amount of memory to a cache with a low hit rate. Furthermore, as dirty pages get pushed out of PostgreSQL's cache, they'll enter the operating system cache. If that cache is relatively large, the OS has more freedom to reorder writes and thus schedule the I/O more efficiently. This is especially important around checkpoint time, when the amount of additional dirty data that is pushed out into the OS cache figures to increase with shared_buffers; thus, a higher value for shared_buffers can contribute to latency spikes around checkpoint time.

Отредактировано 04.12.2016 16:15 Иль . Предыдущая версия . Еще …
Отредактировано 04.12.2016 15:59 Иль . Предыдущая версия .
Re[2]: [Postgre 9.6] CPU 100% и heavy disk I/O
От: dimb82  
Дата: 04.12.16 16:52
Оценка:
Иль>Запросы-то какие? Какая схема данных? Какие индексы имеются? Сколько записей в таблицах? Какие размеры таблиц?

Таблицы работают как распределённая очередь, куда складываются items для обработки. Схема примерно такая:

CREATE TABLE UsersQueue
(
ItemId SERIAL PRIMARY KEY,
UserId VARCHAR(32) UNIQUE,
// Далее данные item
ProcessId INT
);

Запущенный скрипт вызывает UPDATE, помечая первые N items как занятые этим процессом (SET ProcessId=...). Потом делает SELECT .. WHERE ProcessId=.... По мере обработки item вызывается DELETE ... WHERE ItemId=... .
Если после SELECT ничего не получаем (таблица пустая), то делаем sleep на 30 секунд и повторяем цикл.

Даже если таблицы пустые, то загрузка 100%.
Re[3]: [Postgre 9.6] CPU 100% и heavy disk I/O
От: kov_serg Россия  
Дата: 04.12.16 17:39
Оценка: 2 (1)
Здравствуйте, dimb82, Вы писали:


Иль>>Запросы-то какие? Какая схема данных? Какие индексы имеются? Сколько записей в таблицах? Какие размеры таблиц?


D>Таблицы работают как распределённая очередь, куда складываются items для обработки. Схема примерно такая:


D>CREATE TABLE UsersQueue

D>(
D> ItemId SERIAL PRIMARY KEY,
D> UserId VARCHAR(32) UNIQUE,
D> // Далее данные item
D> ProcessId INT
D>);
почему бы не create UNLOGGED table ?
или на рам диск её http://stackoverflow.com/questions/7785419/in-memory-table-in-postgresql

D>Запущенный скрипт вызывает UPDATE, помечая первые N items как занятые этим процессом (SET ProcessId=...). Потом делает SELECT .. WHERE ProcessId=.... По мере обработки item вызывается DELETE ... WHERE ItemId=... .

Не делай delete просто меняй статус на выполненный. потом удаляй все выполненные раз в 10мин например.

D>Если после SELECT ничего не получаем (таблица пустая), то делаем sleep на 30 секунд и повторяем цикл.

Чем не устраивает beanstalkd ?

D>Даже если таблицы пустые, то загрузка 100%.
Re[3]: [Postgre 9.6] CPU 100% и heavy disk I/O
От: Иль  
Дата: 05.12.16 00:42
Оценка: 2 (1)
Здравствуйте, dimb82, Вы писали:


Иль>>Запросы-то какие? Какая схема данных? Какие индексы имеются? Сколько записей в таблицах? Какие размеры таблиц?


D>Таблицы работают как распределённая очередь, куда складываются items для обработки. Схема примерно такая:


D>CREATE TABLE UsersQueue

D>(
D> ItemId SERIAL PRIMARY KEY,
D> UserId VARCHAR(32) UNIQUE,
D> // Далее данные item
D> ProcessId INT
D>);

D>Запущенный скрипт вызывает UPDATE, помечая первые N items как занятые этим процессом (SET ProcessId=...).


В этот момент постгрес копирует все эти записи на новое место, помечая старые версии как удалённые, но фактически не удаляя их. Соответственно если данные item объёмны, то размер таблицы увеличивается довольно интенсивно. Кроме того нечто похожее происходит и во всех индексах, связанных с таблицей.

Если вставка/обновление/удаление происходит довольно часто, то автовакуум, имея низший приорирет, постоянно прерывается и не успевает дойти до конца таблицы. А без этого постгрес не может переиспользовать место из под когда-то удалённых/обновлённых записей. В результате "пустая" таблица может занимать десятки гигабайт, а новые сообщения продолжают увеличивать её объём.

В общем скрипты в предыдущем сообщении. Если таблицы раздуты, то для начала надо сделать VACUUM FULL, который заблокирует систему, но скорее всего резко облегчит ситуацию.

В целом реляционная СУБД и особенно многоверсионник в качестве очереди сообщений работает очень плохо. Лучше подобрать для этой роли систему соответствующего класса.
Отредактировано 05.12.2016 1:02 Иль . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.