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

Чрезвычайно медленный ввод-вывод с простыми запросами PostgreSQL 8.4.4 на Centos 5.5

Я наблюдаю странный и чрезвычайно медленный паттерн ввода-вывода (вывод iostat -dxk 1 /dev/xvdb1):

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdb1             0.00     0.00  0.99  0.99     7.92     3.96    12.00     1.96 2206.00 502.00  99.41

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdb1             0.00     0.00  0.00  0.00     0.00     0.00     0.00     1.00    0.00   0.00 100.40

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdb1             0.00     0.00  0.00  0.00     0.00     0.00     0.00     1.00    0.00   0.00 100.40

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdb1             0.00     0.00  0.99  0.00     3.96     0.00     8.00     0.99 2220.00 1004.00  99.41

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdb1             0.00     0.00  0.00  0.00     0.00     0.00     0.00     1.00    0.00   0.00 100.40

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdb1             0.00     0.99  0.99  0.00     7.92     0.00    16.00     1.14 2148.00 1004.00  99.41

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdb1             0.00     0.00  0.00  0.00     0.00     0.00     0.00     2.01    0.00   0.00 100.40

Device:         rrqm/s   wrqm/s   r/s   w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
xvdb1             0.00     0.00  1.00  1.00     4.00     8.00    12.00     2.01 1874.00 502.00 100.40

Я не знаю, почему использование диска и ожидание так высоко, а скорость чтения / записи так низка. В чем может быть причина?

Запрашиваемая таблица просто имеет только несколько столбцов varchar, один из которых - last_name, который индексируется (фактически lower(last_name) индексируется). Сам запрос прост:

SELECT * FROM consumer_m WHERE lower(last_name) = 'hoque';

Вот результат объяснения:

                                           QUERY PLAN                                            
-------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on consumer_m  (cost=2243.90..274163.41 rows=113152 width=164)
   Recheck Cond: (lower((last_name)::text) = 'hoque'::text)
   ->  Bitmap Index Scan on consumer_m_last_name_index  (cost=0.00..2215.61 rows=113152 width=0)
         Index Cond: (lower((last_name)::text) = 'hoque'::text)

Также обратите внимание, что база данных находится в режиме auto_vacuum, поэтому явная очистка / анализ не выполнялись.

Дело в том, что ваше устройство /dev/xvdb1 подразумевает, что вы работаете под Xen. Как настроено ваше хранилище? Есть ли конкуренция за базовое устройство и как iostat посмотри на который?

Если вы не можете исключить это как вероятность, вот где я собираюсь указать на вихрь виноватых в плохой производительности.

По сути, общий подход к распутыванию проблемы производительности, подобной этой, состоит в том, чтобы подумать обо всех уровнях, на которых может возникнуть узкое место, а затем разработать тесты для устранения каждого из них, пока вы не изолируете проблему.

Я сомневаюсь, что это проблема PostgreSQL, и, скорее всего, проблема с Disk IO. Как упоминается в комментариях к другому ответу, если это проблема с дисковым вводом-выводом, вам действительно следует измерять с помощью Dom0, чтобы получить картину всего, что происходит.

Некоторое время назад у меня была очень похожая проблема, и оказалось, что это проблема с контроллером диска. Очень медленный доступ к диску приводил к тому, что система становилась узким местом при ожидании ввода-вывода диска (что проявлялось в очень высоких средних нагрузках и времени ожидания, но также приводило к тому, что процессы, ожидающие диска, потребляли больше ресурсов ЦП, чем в противном случае. Оказалось, что ядро не распознавал контроллер должным образом и возвращался к старому школьному контроллеру IDE вместо быстрого sata.

Исправление заключалось в загрузке с

hda=noprobe hda=none 

в конце строки ядра в /etc/grub.conf. (Конечно, добавьте все диски, которые у вас есть, аля: hdc=noprobe, hdc=none, hdd=...)

Вот несколько предложений в более или менее случайном порядке:

  1. Autovacum по умолчанию не включен в CentOS. Вы должны установить несколько параметров, чтобы включить его. Дважды проверьте, чтобы процесс очистки действительно запустился. Легко пропустить одну из необходимых настроек.

  2. Обратите внимание, что вам нужно выполнить второй шаг фильтрации для этого запроса, что может быть дорогостоящим в зависимости от того, что вы получите обратно. Я бы рассмотрел такой индекс, как:

    СОЗДАТЬ ИНДЕКС consumer_m_lower_last ON consumer_m (lower (last_name));

    Что будет соответствовать вашему запросу и удалит повторную проверку.

  3. Кроме того, как указывает mattdm, нельзя доверять iostat в виртуализированных средах.

  4. Вам, наверное, стоит проверить http://lonesysadmin.net/2008/02/21/elevatornoop/ если у вас есть проблемы ввода-вывода в среде XEN. Настройки лифта могут иметь влияние, но не настолько.

  5. Использует ли базовый диск моментальные снимки LVM? Хотя это очень полезно с точки зрения управления, оно может снизить производительность ввода-вывода. Это верно как в том случае, если используемое вами блочное устройство является моментальным снимком, так и в том случае, если был сделан моментальный снимок блочного устройства.