Postmaster використовує надмірну кількість процесора та дискових записів


9

використовуючи PostgreSQL 9.1.2

Я бачу надмірне використання процесора та велику кількість записів на диск із завдань постмайстра. Це трапляється навіть тоді, коли моя програма майже нічого не робить (10 секунд вставок за MINUTE). Однак відкрита достатня кількість з'єднань.

Я намагався визначити, що в моїй програмі викликає це. Я досить новачок з postgresql, і ніде ще не дістався. Я ввімкнув кілька параметрів реєстрації у своєму конфігураційному файлі та переглянув з'єднання в таблиці pg_stat_activity, але всі вони простоюють. Тим не менш, кожне з'єднання споживає ~ 50% процесора і записує ~ 15 М / с на диск (нічого не читаючи).

Я в основному використовую акцію postgresql.conf з дуже маленькими налаштуваннями. Буду вдячний за будь-які поради чи вказівки щодо того, що я можу зробити, щоб відстежити це.

Ось зразок того, що показує мені top / iotop:

Cpu(s): 18.9%us, 14.4%sy,  0.0%ni, 53.4%id, 11.8%wa,  0.0%hi,  1.5%si,  0.0%st
Mem:  32865916k total,  7263720k used, 25602196k free,   575608k buffers
Swap: 16777208k total,        0k used, 16777208k free,  4464212k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                          
17057 postgres  20   0  236m  33m  13m R 45.0  0.1  73:48.78 postmaster                                                                                                                       
17188 postgres  20   0  219m  15m  11m R 42.3  0.0  61:45.57 postmaster                                                                                                                       
17963 postgres  20   0  219m  16m  11m R 42.3  0.1  27:15.01 postmaster                                                                                                                       
17084 postgres  20   0  219m  15m  11m S 41.7  0.0  63:13.64 postmaster                                                                                                                       
17964 postgres  20   0  219m  17m  12m R 41.7  0.1  27:23.28 postmaster                                                                                                                       
18688 postgres  20   0  219m  15m  11m R 41.3  0.0  63:46.81 postmaster                                                                                                                       
17088 postgres  20   0  226m  24m  12m R 41.0  0.1  64:39.63 postmaster                                                                                                                       
24767 postgres  20   0  219m  17m  12m R 41.0  0.1  24:39.24 postmaster                                                                                                                       
18660 postgres  20   0  219m  14m 9.9m S 40.7  0.0  60:51.52 postmaster                                                                                                                       
18664 postgres  20   0  218m  15m  11m S 40.7  0.0  61:39.61 postmaster                                                                                                                       
17962 postgres  20   0  222m  19m  11m S 40.3  0.1  11:48.79 postmaster                                                                                                                       
18671 postgres  20   0  219m  14m   9m S 39.4  0.0  60:53.21 postmaster                                                                                                                       
26168 postgres  20   0  219m  15m  10m S 38.4  0.0  59:04.55 postmaster  


Total DISK READ: 0.00 B/s | Total DISK WRITE: 195.97 M/s
  TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND                                                                                                                        
17962 be/4 postgres    0.00 B/s   14.83 M/s  0.00 %  0.25 % postgres: aggw aggw [local] idle
17084 be/4 postgres    0.00 B/s   15.53 M/s  0.00 %  0.24 % postgres: aggw aggw [local] idle
17963 be/4 postgres    0.00 B/s   15.00 M/s  0.00 %  0.24 % postgres: aggw aggw [local] idle
17188 be/4 postgres    0.00 B/s   14.80 M/s  0.00 %  0.24 % postgres: aggw aggw [local] idle
17964 be/4 postgres    0.00 B/s   15.50 M/s  0.00 %  0.24 % postgres: aggw aggw [local] idle
18664 be/4 postgres    0.00 B/s   15.13 M/s  0.00 %  0.23 % postgres: aggw aggw [local] idle
17088 be/4 postgres    0.00 B/s   14.71 M/s  0.00 %  0.13 % postgres: aggw aggw [local] idle
18688 be/4 postgres    0.00 B/s   14.72 M/s  0.00 %  0.00 % postgres: aggw aggw [local] idle
24767 be/4 postgres    0.00 B/s   14.93 M/s  0.00 %  0.00 % postgres: aggw aggw [local] idle
18671 be/4 postgres    0.00 B/s   16.14 M/s  0.00 %  0.00 % postgres: aggw aggw [local] idle
17057 be/4 postgres    0.00 B/s   13.58 M/s  0.00 %  0.00 % postgres: aggw aggw [local] idle
26168 be/4 postgres    0.00 B/s   15.50 M/s  0.00 %  0.00 % postgres: aggw aggw [local] idle
18660 be/4 postgres    0.00 B/s   15.85 M/s  0.00 %  0.00 % postgres: aggw aggw [local] idle

Оновлення : багато запису файлів, здається, є деякими тимчасовими (?) Файлами в $ PG_DATA / base / каталогу. Я розумію тут структуру файлів, що кожна таблиця в основному зберігається як файл, ім'я якого - OID таблиці. Однак є багато імен файлів tnn_nnnnnnn, і саме ці файли, здається, записуються (можливо, переписуються) постійно. Для чого ці файли? Файлів розміщено ~ 4700, і всі вони мають розмір 8K:

-rw-------. 1 postgres postgres     8192 Jul  3 23:08 t12_1430975
-rw-------. 1 postgres postgres     8192 Jul  3 23:08 t16_1432736
-rw-------. 1 postgres postgres     8192 Jul  3 23:08 t28_1439066
-rw-------. 1 postgres postgres     8192 Jul  3 23:08 t24_1436243
-rw-------. 1 postgres postgres     8192 Jul  3 23:08 t24_1436210
-rw-------. 1 postgres postgres     8192 Jul  3 23:08 t19_1393372
-rw-------. 1 postgres postgres     8192 Jul  3 23:08 t28_1439051
-rw-------. 1 postgres postgres     8192 Jul  3 23:08 t8_1430334

Оновлення : Запуск страйку в процесах поштового керування в основному показує багато файлів вводу / виводу:

open("base/16388/t24_1435947_fsm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435947_vm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435947", O_RDWR)  = 9
lseek(9, 0, SEEK_END)                   = 8192
ftruncate(9, 0)                         = 0
lseek(9, 0, SEEK_END)                   = 0
open("base/16388/t24_1435941", O_RDWR)  = 18
lseek(18, 0, SEEK_END)                  = 0
write(9, "\0\0\0\0\0\0\0\0\1\0\0\0000\0\360\37\360\37\4 \0\0\0\0b1\5\0\2\0\0\0"..., 8192) = 8192
lseek(18, 0, SEEK_END)                  = 0
close(9)                                = 0
open("base/16388/t24_1435947", O_RDWR)  = 9
lseek(9, 0, SEEK_END)                   = 8192
close(18)                               = 0
close(9)                                = 0
open("base/16388/t24_1435944_fsm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435944_vm", O_RDWR) = -1 ENOENT (No such file or directory)
open("base/16388/t24_1435944", O_RDWR)  = 9
lseek(9, 0, SEEK_END)                   = 0
close(9)                                = 0

Оновлення : Отже, ця проблема, як видається, пов'язана з тимчасовими таблицями. Ми змінили налаштування, щоб тимчасові таблиці були «звичайними» таблицями, і вся активність диска пішла, а продуктивність повертається туди, де я очікував. Тепер ця зміна була просто швидким і брудним випробуванням: якщо ми дійсно збираємося змінити звичайні таблиці, у нас виникнуть проблеми з одночасністю та очищенням. Чи тимчасові столи справді є злими, чи ми їх зловживаємо?

Оновлення : ще деяке тло. Я використовую внутрішнє програмне забезпечення для реплікації, засноване на власних розробниках . Він досить зрілий і застосовується в ряді проектів протягом багатьох років, але використовує MySQL. Ми працювали з PostgreSQL лише останній рік-два. Ми використовували тимчасові таблиці як частину механізму реплікації. Щоразу, коли встановлюється нове з'єднання, ми створюємо тимчасову таблицю для кожної таблиці в базі даних. З 10-20 (довготривалими) з'єднаннями та ~ 50 таблицями це може становити безліч тимчасових таблиць. Усі тимчасові таблиці були створені за допомогою:

CREATE TEMPORARY TABLE... ON COMMIT DELETE ROWS;

Семантика тимчасових таблиць дуже добре поєднується з нашою схемою реплікації та спростила багато коду, який ми мали використати для MySQL, але схоже, що реалізація також не спрацювала. З трохи досліджуваних нами досліджень, я не думаю, що тимчасові таблиці справді були призначені для функції, для якої ми їх використовували.

Я не є власним експертом (навіть не близьким) з цього приводу, просто його користувачем, тому моє пояснення може бути не на 100% точним, але я думаю, що це досить близько.


3
Ваше розуміння трохи застаріло, якщо ви подивитесь на офіційну документацію , ви побачите, що "... для тимчасових відносин, назва файлу має форму tBBB_FFF, де BBB - ідентифікатор бекенду бекенда, який створив файл , а FFF - це номер фленоди. ... »
Мілен А. Радев,

Нічого собі, це добре працює підсистема вводу / виводу диска. Що говорить про те, що насправді роблять робітники?
жіноча

@ MilenA.Radev, тому, схоже, я можу робити щось дивне / зайве з тимчасовими таблицями. Це цікаво. У мене є маса тригерів, які використовують тимчасові таблиці. Я придивлюся до них уважніше.
wolfcastle

@womble, я оновив питання з результатами з strace.
wolfcastle

Чи відчуваєте ви насправді проблеми з продуктивністю?
voretaq7

Відповіді:


1

Ваша конфігурація PostgreSQL закінчена. Це було підозріло з вашої початкової посади,

 Cpu(s): 18.9%us, 14.4%sy,  0.0%ni, 53.4%id, 11.8%wa,  0.0%hi,  1.5%si,  0.0%st
 Mem:  32865916k total,  7263720k used, 25602196k free,   575608k buffers
 Swap: 16777208k total,        0k used, 16777208k free,  4464212k cached

З 32 ГБ на вашому сервері, ~ 25 ГБ безкоштовно, за винятком ~ 575 МБ буфера.

З вашого файлу postgresql.conf,

 shared_buffers = 32MB                   # min 128kB                               
 #temp_buffers = 8MB                     # min 800kB
 #max_prepared_transactions = 0          # zero disables the feature
 ...
 #work_mem = 1MB                         # min 64kB
 #maintenance_work_mem = 16MB            # min 1MB
 #max_stack_depth = 2MB   

Я припускаю, що це спеціальна база даних. Якщо так, змініть його на наступні параметри та перезавантажте / перезавантажте,

 shared_buffers = 16GB                   # min 128kB                               
 temp_buffers = 128MB                     # min 800kB
 #max_prepared_transactions = 0          # zero disables the feature
 ...
 work_mem = 8MB                         # min 64kB
 maintenance_work_mem = 64MB            # min 1MB
 max_stack_depth = 4MB   

Повідомте мене, як це змінює вашу ефективність і може додатково настроїти її за потребою.

З повагою до незаблокованих таблиць, якщо ваші тимчасові таблиці містять тимчасові дані, які є ефемерними, і, як ви вже згадували, створені на сеансі, краще використовувати незаблоковані таблиці.

Ви можете скоротити свої таблиці після сеансу, якщо це прийнятно.

Більше інформації тут - http://michael.otacoo.com/postgresql-2/unlogged-table-performance-in-postgresql-9-1/

Я не впевнений, для чого потрібні тимчасові таблиці для тиражування. Не можете використовувати потокову реплікацію PostgreSQL?


0

Використання тимчасових таблиць та встановлення давніх з'єднань (можливо, це об'єднання з'єднань) може бути тягарем, якщо ваш сервер до цього не готовий. Один параметр PostgreSQL, з яким ви можете спробувати пограти, - це те, temp_buffersщо керує оперативною пам’яттю, призначеною для тимчасових таблиць. Ці тимчасові буфери розподіляються за з'єднання, і значення за замовчуванням (8 МБ), ймовірно, занадто низьке для вашого сайту.

Можливо, вам також потрібно трохи змінити поведінку вашої клієнтської програми, залежно від того, як ви використовуєте свої тимчасові таблиці. Існує аналогічне запитання з приємною відповіддю на Stack Overflow .


Мені доведеться запитати свого внутрішнього експерта про те, намагалися ми скорегувати значення temp_buffers чи ні (ми спробували багато різних речей). Питання, на яке ви вказуєте, насправді не стосується, оскільки таким чином ми не використовуємо тимчасові таблиці. Я оновив питання ще деякими деталями.
wolfcastle

Дякуємо за оновлення до питання та за файл postgresql.conf, саме це нам потрібно спробувати покращити у цій ситуації. Я погоджуюся з відповіддю @Chida, яка відповідає тому, що я запропонував temp_buffers. Чи можете ви також сказати нам, який розмір БД ви намагаєтесь копіювати? Скільки таблиць, середній розмір на таблицю та загальний розмір БД?
Тонін

0

Чи можете ви опублікувати файл postgresql.conf? Здається, ваш postgresql значно недооцінений.

Чи можете ви також опублікувати:

  • Якщо ви використовуєте незахищені таблиці для тимчасових таблиць?

  • Скільки дисків і в якій RAID-конфігурації?


Я помістив сюди файл postgresql.conf . Я вважаю, що ви не можете створити таблицю, яка є тимчасовою та незахищеною. У RAID 1 + 0 є 6 1 ТБ дисків (загальний обсяг 3 ТБ)
wolfcastle
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.